pax_global_header00006660000000000000000000000064151304323510014507gustar00rootroot0000000000000052 comment=096257f7dbfd7c0326811f3556cfffe8057b2086 someipy-2.1.2/000077500000000000000000000000001513043235100131765ustar00rootroot00000000000000someipy-2.1.2/.coveragerc000066400000000000000000000000301513043235100153100ustar00rootroot00000000000000[run] omit = tests/*someipy-2.1.2/.github/000077500000000000000000000000001513043235100145365ustar00rootroot00000000000000someipy-2.1.2/.github/workflows/000077500000000000000000000000001513043235100165735ustar00rootroot00000000000000someipy-2.1.2/.github/workflows/tests.yml000066400000000000000000000024031513043235100204570ustar00rootroot00000000000000name: Run Tests on: push: branches: - '*' pull_request: branches: - '*' jobs: test: runs-on: ubuntu-latest # Use the latest version of Ubuntu as the operating system steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Python 3.12 uses: actions/setup-python@v2 with: python-version: 3.12 - name: Install dependencies run: | python -m pip install --upgrade pip pip install -e . pip install pytest pip install pytest-asyncio pip install coverage - name: Run pytest run: coverage run -m pytest tests/ - name: Generate coverage HTML report run: coverage html - name: Upload coverage report uses: actions/upload-artifact@v4 with: name: coverage-report path: './htmlcov' - name: Generate coverage json run: coverage json -o coverage.json - name: Upload coverage json to gist env: GIST_ID: ${{ secrets.GIST_ID }} GIST_TOKEN: ${{ secrets.GIST_TOKEN }} run: | # Create a GitHub CLI authentication token echo "$GIST_TOKEN" | gh auth login --with-token # Update existing gist gh gist edit $GIST_ID coverage.jsonsomeipy-2.1.2/.gitignore000066400000000000000000000002261513043235100151660ustar00rootroot00000000000000.vscode/ dist/ someipy.egg-info/ __pycache__ venv/ *.whl integration_tests/build integration_tests/install build/ .coverage htmlcov/ *.pdf *.bash someipy-2.1.2/.readthedocs.yaml000066400000000000000000000011151513043235100164230ustar00rootroot00000000000000# Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the OS, Python version, and other tools you might need build: os: ubuntu-24.04 tools: python: "3.13" # Build documentation in the "docs/" directory with Sphinx sphinx: configuration: docs/conf.py # Optionally, but recommended, # declare the Python requirements required to build your documentation # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html python: install: - requirements: docs/requirements.txt someipy-2.1.2/LICENSE.md000066400000000000000000001045151513043235100146100ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . someipy-2.1.2/README.md000066400000000000000000000065531513043235100144660ustar00rootroot00000000000000# someipy - A Python Library implementing the SOME/IP Protocol ![Dynamic JSON Badge](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgist.githubusercontent.com%2Fchrizog%2F6a2e6f355eedf38ae3af74dcdb7b30a1%2Fraw%2F61630b4d2cc9c04aae78b3cca0cbc9c56e76f0e5%2Fcoverage_someipy_v1.json&query=totals.percent_covered_display&suffix=%20%25&label=Line%20Coverage) ## Get in Contact :postbox: If you want to connect, have a feature request, bug report or need support, send me an email or connect on LinkedIn: > :email: [someipy.package@gmail.com](mailto:someipy.package@gmail.com) :electric_plug: [LinkedIn](https://www.linkedin.com/in/ch-herzog/) ## Documentation :pencil2: :link: [https://someipy.readthedocs.io/en/latest/](https://someipy.readthedocs.io/en/latest/) ## What is someipy? someipy is a Python library implementing the SOME/IP protocol, including the SOME/IP SD (Service Discovery) in Python. It's perfectly suited for fast prototyping of applications that need to provide (server) or use (client) SOME/IP services from other ECUs. someipy also supports serialization and deserialization of SOME/IP payloads, which is a unique feature compared to other libraries. someipy is still under development; therefore, it does not yet support all features of the SOME/IP and SOME/IP Service Discovery protocol specification. someipy is based on the specification version of R22-11: - [SOME/IP Protocol Specification](https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPProtocol.pdf) - [SOME/IP Service Discovery Protocol Specification](https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPServiceDiscoveryProtocol.pdf) The library is currently developed and tested under Ubuntu 22.04 and Python 3.8. Windows is supported as well. ## Typical Use Cases someipy excels in scenarios where a full-scale Autosar (Adaptive or Classic) integration would be excessive: - :test_tube: **Develop Test Applications**: Easily create test applications to stimulate the SOME/IP interfaces of your system under test. Whether running on a PC in a SIL environment or on an ECU, someipy allows you to efficiently send and receive SOME/IP events or utilize/provide SOME/IP services. Test data can be seamlessly generated or imported in Python, from sources such as .csv files or ROS bag files. Explore the [example applications](#example-applications) for more details. - :battery: **Prototype Sensor Integration**: Quickly integrate new sensors into your project using SOME/IP, ideal for evaluating the sensor's potential impact without significant effort. Define the message/parameter layout in Python and create a server service instance in minutes. Check out the [example application](#example-applications) *send_events_udp.py* for a practical demonstration. - :microscope: **Data Recording**: Set up a SOME/IP recording application in just a few minutes and store data in your preferred format, such as ROS bags, .csv files, or databases. Simply dump the received data within your callback function. The [example application](#example-applications) *receive_events_udp.py* illustrates this process. ## Installation The package can be installed from [PyPi](https://pypi.org/project/someipy/). ```bash pip3 install someipy ``` ## Example Applications In the directory [example_apps](./example_apps/), examples including explanations, can be found for using the someipy library. someipy-2.1.2/docs/000077500000000000000000000000001513043235100141265ustar00rootroot00000000000000someipy-2.1.2/docs/api/000077500000000000000000000000001513043235100146775ustar00rootroot00000000000000someipy-2.1.2/docs/api/client_service_instance.rst000066400000000000000000000001731513043235100223140ustar00rootroot00000000000000ClientServiceInstance ======================= .. autoclass:: someipy::ClientServiceInstance :exclude-members: __init__someipy-2.1.2/docs/api/connect_to_someipy_daemon.rst000066400000000000000000000001531513043235100226530ustar00rootroot00000000000000connect_to_someipy_daemon =========================== .. autofunction:: someipy::connect_to_someipy_daemonsomeipy-2.1.2/docs/api/event.rst000066400000000000000000000001371513043235100165530ustar00rootroot00000000000000Event =========================== .. autoclass:: someipy::Event :exclude-members: __init__someipy-2.1.2/docs/api/eventgroup.rst000066400000000000000000000001451513043235100176270ustar00rootroot00000000000000EventGroup ======================= .. autoclass:: someipy::EventGroup :exclude-members: __init__someipy-2.1.2/docs/api/index.rst000066400000000000000000000006561513043235100165470ustar00rootroot00000000000000API Reference ======================= Classes ----------------------- .. toctree:: :maxdepth: 1 service service_builder method method_result eventgroup event server_service_instance client_service_instance serialization transport_layer_protocol message_type return_code Functions ----------------------- .. toctree:: :maxdepth: 1 connect_to_someipy_daemon someipy_loggingsomeipy-2.1.2/docs/api/message_type.rst000066400000000000000000000001521513043235100201140ustar00rootroot00000000000000MessageType ========================== .. autoclass:: someipy::MessageType :exclude-members: __init__someipy-2.1.2/docs/api/method.rst000066400000000000000000000001251513043235100167070ustar00rootroot00000000000000Method =============== .. autoclass:: someipy::Method :exclude-members: __init__someipy-2.1.2/docs/api/method_result.rst000066400000000000000000000001541513043235100203070ustar00rootroot00000000000000MethodResult ========================== .. autoclass:: someipy::MethodResult :exclude-members: __init__someipy-2.1.2/docs/api/return_code.rst000066400000000000000000000001501513043235100177360ustar00rootroot00000000000000ReturnCode ========================== .. autoclass:: someipy::ReturnCode :exclude-members: __init__someipy-2.1.2/docs/api/serialization.rst000066400000000000000000000001511513043235100203030ustar00rootroot00000000000000Serialization ================= .. automodule:: someipy.serialization :members: :show-inheritance:someipy-2.1.2/docs/api/server_service_instance.rst000066400000000000000000000001731513043235100223440ustar00rootroot00000000000000ServerServiceInstance ======================= .. autoclass:: someipy::ServerServiceInstance :exclude-members: __init__someipy-2.1.2/docs/api/service.rst000066400000000000000000000001401513043235100170640ustar00rootroot00000000000000Service ======================= .. autoclass:: someipy::Service :exclude-members: __init__ someipy-2.1.2/docs/api/service_builder.rst000066400000000000000000000001551513043235100206000ustar00rootroot00000000000000ServiceBuilder ======================= .. autoclass:: someipy::ServiceBuilder :exclude-members: __init__someipy-2.1.2/docs/api/someipy_logging.rst000066400000000000000000000001211513043235100206160ustar00rootroot00000000000000someipy_logging ======================= .. automodule:: someipy.someipy_logging someipy-2.1.2/docs/api/transport_layer_protocol.rst000066400000000000000000000002011513043235100225730ustar00rootroot00000000000000TransportLayerProtocol =========================== .. autoclass:: someipy::TransportLayerProtocol :exclude-members: __init__someipy-2.1.2/docs/calling_methods.rst000066400000000000000000000166021513043235100200210ustar00rootroot00000000000000Calling SOME/IP Methods ======================= SOME/IP Methods --------------- Methods implement a request-response communication in the SOME/IP protocol. A server offers a method. A client calls the method by sending a request message to the server. The server answers the request message with a response message. In contrast to SOME/IP events, no subscription of the offered service has to be set up in order to make a method request call. Request and response messages can carry a serialized payload. Typically, the payload is either the argument to the method or the return value of the method. For defining the service interface data types which can be used in methods and serializing structured data into ``bytes`` follow the article :doc:`service_interface`. In SOME/IP there is also the possibility of fire&forget communication. The client sends a request message and does not expect a response from the server. The fire&forget communication is not implemented in someipy yet. Step 1: Define the Data Types for Request and Response ------------------------------------------------------ In this example, we will call a SOME/IP method that calculates the sum of two signed integers and returns the result back to the client. When we are calling the method, we will pass the two addends with the request message to the server. The server will send back a response message containing the sum. For request and response, we need to define two data types ``Addends`` and ``Sum``. The data types are the same types as defined in the article :doc:`offering_methods`. .. code-block:: python @dataclass class Addends(SomeIpPayload): addend1: Sint16 addend2: Sint16 def __init__(self, addend1: int = 0, addend2: int = 0): self.addend1 = Sint16(addend1) self.addend2 = Sint16(addend2) @dataclass class Sum(SomeIpPayload): value: Sint32 def __init__(self): self.value = Sint32() Details on defining data types can be found :doc:`here `. Step 2: Connect to the someipy Daemon -------------------------------------- The first step is to connect to the someipy daemon. The daemon is a separate process communicating with the application using someipy via a Unix Domain Socket (UDS). The daemon is responsible for handling all communication with the SOME/IP network, including service discovery and message sending/receiving. .. code-block:: python someipy_daemon = await connect_to_someipy_daemon() Step 3: Definition of the Service ---------------------------------- A SOME/IP method is part of a service and so we will define a ``Service`` as the next step using the method ID and the major version of the service. In the third step, this service will be used for creating a ``ClientServiceInstance`` on which we can call the SOME/IP method. The ``ServiceBuilder`` class offers a fluent API, which is used for creation of the ``Service`` object. .. code-block:: python SAMPLE_SERVICE_ID = 0x1234 addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.UDP, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) Step 4: Instantiate the Service ------------------------------- The previously defined ``Service`` can be instantiated into one or multiple service instances. Since we want to call (and not offer) a method, we will instantiate a ``ClientServiceInstance``. .. code-block:: python SAMPLE_INSTANCE_ID = 0x5678 client_instance_addition = ClientServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) Step 5: Calling the Method --------------------------- Finally, we need to setup the method parameters for the request and call the SOME/IP method offered by the server. In this case, the parameter to the method is an ``Addends`` object. After creating the ``Addends`` object, we will call the method on the ``ClientServiceInstance`` using the ``call_method`` function. ``call_method`` is a coroutine which has to be awaited and will not block until the response from the server is received. This allows other tasks to be scheduled while waiting for a response. The ``call_method`` function expects a method ID identifying the method on the server to be called. A server could offer multiple methods inside the same service. The second parameter is the payload to be sent with the request: The ``Addends`` object is serialized into a ``bytes`` object and passed to the call. The ``call_method`` function returns a ``MethodResult`` object with the following members: - message_type (``MessageType``): The MessageType is an enum and can be either ``MessageType.RESPONSE`` or ``MessageType.ERROR``. - return_code (``ReturnCode``): The ``ReturnCode`` enum reflects the return codes defined in the `SOME/IP protocol specification `_. For indicating a successful method call to the client, ``E_OK`` is returned by the server. - payload (``bytes``): The payload is a ``bytes`` object which can be deserialized into the expected returned message structure. In this case it will be deserialized into a ``Sum`` object. The ``call_method`` function can raise a ``RuntimeError`` or an ``asyncio.TimeoutError``. A ``RuntimeError`` is raised in case the service instance offered by the server was not found yet. In this case no method request can be sent since the destination IP address and port are not available yet. The ``asyncio.TimeoutError`` is raised if no response is received by the server after sending the request or in case of TCP, the TCP connection cannot be established. To avoid the ``RuntimeError`` it is possible to test whether the service was already found by using the ``service_found`` method on the ``ClientServiceInstance``. .. code-block:: python method_parameter = Addends(addend1=1, addend2=2) while True: try: method_result = await client_instance_addition.call_method( SAMPLE_METHOD_ID, method_parameter.serialize() ) if method_result.message_type == MessageType.RESPONSE: print( f"Received result for method: {' '.join(f'0x{b:02x}' for b in method_result.payload)}" ) if method_result.return_code == ReturnCode.E_OK: sum = Sum().deserialize(method_result.payload) print(f"Sum: {sum.value.value}") else: print( f"Method call returned an error: {method_result.return_code}" ) elif method_result.message_type == MessageType.ERROR: print("Server returned an error..") # In case the server includes an error message in the payload, it can be deserialized and printed except Exception as e: print(f"Error during method call: {e}") Step 6: Shutdown the Application -------------------------------- At the end of your application, make sure to stop offering the service instance and disconnect from the someipy daemon to ensure a clean shutdown of the application. .. code-block:: python await service_instance_temperature.stop_offer() await someipy_daemon.disconnect_from_daemon()someipy-2.1.2/docs/changelog.rst000066400000000000000000000046061513043235100166150ustar00rootroot00000000000000CHANGELOG ========= All notable user-facing changes to this project are documented in this file. HEAD ---- Code changes to ``master`` that are *not* in the latest release: Release v2.1.2 ----------------- - Fix SO_REUSEADDR socket option on Windows Release v2.1.1 ----------------- - Fix Python import issue Release v2.1.0 ----------------- - Support Windows: Use tcp socket for daemon communication on Windows systems. - Add support for broadcasting SOME/IP SD messages over UDP. - Implement stop subscribe functionality in the `someipyd` daemon. Release v2.0.0 ----------------- - Introduced a new architecture with a `someipyd` daemon for centralized network handling. - Refined application API for easier service definition and instantiation. Release v1.0.0 -------------- - Support dynamically sized arrays - Support fixed size strings - Support dynamically sized strings - Implement timeouts (ttl checks) for SD messages Release v0.0.10 --------------- - Fix Python 3.8 issue from version 0.0.9 (Set of asyncio.Task typing) - Properly handle major version (interface version) of services - Handle session IDs and client IDs - Allow multiple asynchronous method calls from a client and handle out of order method responses Release v0.0.9 -------------- - Enable asynchronous method handlers Release v0.0.8 -------------- - Improved method error handling - Update of method handler function signature Release v0.0.7 -------------- - Improved integration testing - Bugfix: Handle subscribe acknowledge correctly Release v0.0.6 -------------- - Pack together service offers in a single Service Discovery message (this requires the offers to be sent within max. 20ms) - Send SD stop offer entries when a service instance is shut down Release v0.0.5 -------------- - Fix issue in socket bind for Service Discovery via multicast to use the right network interface - Add IPv4 SD Endpoint Option to avoid crashes in case it is received - Implement proper SD option handling ("first and second option run") Release v0.0.4 -------------- - Publish library under GPL-3.0 license Release v0.0.3 -------------- - Support Windows - Automatic multicast group join - Support method calls via TCP Release v0.0.2 -------------- - Support TCP as a transport layer - Support offering and calling methods - Add an example of how to replay ROS1 bagfiles into SOME/IP events - Add docstrings for all public classes and functions someipy-2.1.2/docs/conf.py000066400000000000000000000027331513043235100154320ustar00rootroot00000000000000# Configuration file for the Sphinx documentation builder. # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information import sys from pathlib import Path project = "someipy" copyright = "2025, Christian H." author = "Christian H." release = "1.0.0" sys.path.insert(0, str(Path("..", "src").resolve())) # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon"] # Napoleon settings napoleon_google_docstring = True napoleon_numpy_docstring = False napoleon_include_init_with_doc = False napoleon_include_private_with_doc = False napoleon_include_special_with_doc = True # Autodoc settings autodoc_default_options = { "members": True, "undoc-members": True, "private-members": False, } autodoc_typehints = "description" # Show type hints in description templates_path = ["_templates"] exclude_patterns = [] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output # html_theme = 'alabaster' html_theme = "sphinx_rtd_theme" html_static_path = ["images"] someipy-2.1.2/docs/cookbook.rst000066400000000000000000000002271513043235100164670ustar00rootroot00000000000000Cookbook ========================== .. toctree:: :maxdepth: 2 calling_methods offering_methods subscribing_events offering_eventssomeipy-2.1.2/docs/getting_started.rst000066400000000000000000000237121513043235100200540ustar00rootroot00000000000000Getting Started ================= This guide demonstrates how to create a SOME/IP service using someipy that broadcasts temperature measurements every second using SOME/IP events. The complete example is available in the `example applications on GitHub `_. Prerequisites ---------------- - Linux (Ubuntu 22.04 or equivalent) - Python 3.8+ - Network interface with multicast support Installation ------------ Install someipy from PyPI: .. code-block:: bash pip3 install someipy Service Data Type Definition --------------------------- Define the temperature data structure using Python dataclasses. No IDL files required. Create ``temperature_msg.py``: .. code-block:: python from dataclasses import dataclass from someipy.serialization import ( SomeIpPayload, SomeIpFixedSizeArray, Uint8, Uint64, Float32, ) @dataclass class Version(SomeIpPayload): major: Uint8 minor: Uint8 def __init__(self): self.major = Uint8() self.minor = Uint8() @dataclass class TemperatureMsg(SomeIpPayload): version: Version timestamp: Uint64 measurements: SomeIpFixedSizeArray def __init__(self): self.version = Version() self.timestamp = Uint64() self.measurements = SomeIpFixedSizeArray(Float32, 4) Asyncio App Implementation -------------------------- someipy is an `asyncio `_ based Python library, since multiple concurrent tasks are running in the SOME/IP implementation, e.g. for communicating with the someipy daemon. First we will set up our application's structure. Typically in an asyncio application, a main coroutine-function is added which is executed using `asyncio.run `_. Our application's logic will be added inside the main coroutine-function *async def main*. Create ``send_events_udp.py`` with the following structure: .. code-block:: python import asyncio import ipaddress import logging async def main(): # .. our application will go here except asyncio.CancelledError: print("Application cancelled...") finally: print("Cleanup...") print("End main task...") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: pass someipy Logging --------------- At the beginning of the application the someipy logging level is configured. Logging levels can be chosen from the `Python3 logging module levels `_. .. code-block:: python import logging async def main(): # .. our application will go here set_someipy_log_level(logging.DEBUG) Connect to the someipy Daemon ----------------------------- The next step is to connect to the someipy daemon. The daemon is a separate process communicating with the application using someipy via a Unix Domain Socket (UDS). The daemon is responsible for handling all communication with the SOME/IP network, including service discovery and message sending/receiving. .. code-block:: python someipy_daemon = await connect_to_someipy_daemon() In case, a non-default Unix Domain Socket path is used, a config dictionary can be passed to the *connect_to_someipy_daemon* function. If Windows is used, TCP sockets have to be used for communication between the application and the someipy daemon. In this case, the *connect_to_someipy_daemon* function has to be called with a config dictionary containing the keys *use_tcp*, *tcp_host* and optionally *tcp_port*. .. code-block:: python someipy_daemon = await connect_to_someipy_daemon( {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} ) Defining the SOME/IP Service ---------------------------- For offering a SOME/IP service, you first define a `Service `_ containing **EventGroups** or **Methods** using the `ServiceBuilder `_. Afterwards the Service can be instantiated as a Server- or Client-Instance. In this example, a *temperature_service* with service ID 0x1234 containing a single event group with ID 0x0321 which in turn contains a single event with ID 0x0123. The service has a major version 1 and minor version 0: .. code-block:: python from someipy import ServiceBuilder, EventGroup async def main(): # ... SAMPLE_SERVICE_ID = 0x1234 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.UDP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) # ... Instantiating the SOME/IP Service --------------------------------- Once the `Service `_ is defined it can be instantiated multiple times. For offering a `Service `_ in someipy the `ServerServiceInstance `_ class is used. For using a service as client the `ClientServiceInstance `_ class is used. The constructor of the *ServerServiceInstance* class requires several parameters: - daemon: The *someipy_daemon* object (defined above) - service: The *Service* object (defined above) - instance_id: A service instance ID (0x5678 in this example) - endpoint_ip: The IP address of the network interface on which the service is offered (127.0.0.1 in this example) - endpoint_port: The port on which the service is offered (3000 in this example) - ttl: The time-to-live for the service discovery entries (5 seconds in this example) - cyclic_offer_delay_ms: The period of the cylic offer service SD messages (2000 ms in this example) Afterwards, the the SOME/IP service can be offered using the *start_offer* method. When exiting your application make sure to use *stop_offer* method on the service instance. .. code-block:: python from someipy import TransportLayerProtocol, construct_server_service_instance async def main(): # ... SAMPLE_INSTANCE_ID = 0x5678 service_instance_temperature = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) # After constructing a ServerServiceInstances the start_offer method has to be called. This will start an internal timer, # which will periodically send Offer service entries with a period of "cyclic_offer_delay_ms" which has been passed above print("Start offering service..") await service_instance_temperature.start_offer() # ... # Before exiting the app: service_instance_temperature.stop_offer() Sending Events -------------- Now it is time to send events to subscribed clients. First some data has to be prepared: Import and instantiate the *TemperatureMsg* and fill it with some data: .. code-block:: python from someipy.serialization import Uint8, Uint64, Float32 from temperature_msg import TemperatureMsg async def main(): # ... tmp_msg = TemperatureMsg() tmp_msg.version.major = Uint8(1) tmp_msg.version.minor = Uint8(0) tmp_msg.measurements.data[0] = Float32(20.0) tmp_msg.measurements.data[1] = Float32(21.0) tmp_msg.measurements.data[2] = Float32(22.0) tmp_msg.measurements.data[3] = Float32(23.0) # ... Afterwards we will start an endless loop sending data every second using the *send_event* method on the service instance. The *send_event* method takes a bytes-object which can be retrieved serializing the *TemperatureMsg*. .. code-block:: python async def main(): # ... try: # Cyclically send events in an endless loop... while True: await asyncio.sleep(1) tmp_msg.timestamp = Uint64(tmp_msg.timestamp.value + 1) payload = tmp_msg.serialize() service_instance_temperature.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) except asyncio.CancelledError: print("Stop offering service...") await service_instance_temperature.stop_offer() finally: print("Service Discovery close...") service_discovery.close() # ... Network Configuration --------------------- If you are using Linux, make sure to join the multicast group for your network interface used for the service discovery before starting the application. In our example we use 224.224.224.245 and the loopback interface. Make sure to adjust the command for your project. Otherwise, it will not be possible for clients to subscribe to your SOME/IP service. .. code-block:: bash sudo ip addr add 224.224.224.245 dev lo autojoin python3 send_events_udp.py Start the someipy Daemon ----------------------------- Before running the application, ensure that the someipy daemon is running. The daemon can be started using the following command: .. code-block:: bash someipyd --config someipyd.json The .json configuration file is optional and can be omitted. Start the Application ---------------------- Run the application using Python 3: .. code-block:: bash python3 send_events_udp.py someipy-2.1.2/docs/images/000077500000000000000000000000001513043235100153735ustar00rootroot00000000000000someipy-2.1.2/docs/images/pc_ip4_settings.png000066400000000000000000001003611513043235100212000ustar00rootroot00000000000000‰PNG  IHDRP­ÙJsBIT|dˆtEXtSoftwaregnome-screenshotï¿> IDATxœìÝwxÕÔÀñorïín)Ý›¶¬BÙC†ì "(Š ‚{‹þT\¸PEQ� ¢ EÜŠÊ,²¤P(ЖҖ®Ûq{oòû£´v·—ÕÞÏóôi›œ$oÒžä½çœ$ʪU«t]×Ñu€Š~.;MӴ⟫ú^™êæ×Ô¡C‡hÔ¨ÑyY—B!êEQj<­äô¢ßKN/;­ìô²?«J˜ªú*Y¾ì²e�¯„©,MÓŠ“9!„Bˆ"%“ž¢ïý¬ªj©i%QEó‹òEQ ( 8)ù½dRTÙ|(ŸH•ü^‘ó•PÙl6¬VëyY—B!꿲‰SÑÏ•µ4éº^a⤪*º®'XEËå0F¨8iª(�ª,‘ʵ>U•HI%„BˆsU]^e­P%K•ußišVae,›(%I%¦’ßóóóÉÎÎ&''«ÕJAAA©d«¤šŽ‰:[IIIäçç_�u !„¢n+›@U7þIUUL&F£ÜÜÜptt,n…*™H•‡ÂÆ¢¢ùEë4Õ&N𦑗—GJJ ¡¡¡ :”ÀÀ@ CñÆ„B!ê²¢¼¦  €¤¤$6oÞL||<>>>8998/JœJ6)Ë–-ÓK&Je'MÓ8uê¾¾¾\wÝu¸¹¹QPP€Õj-U^!„¢.+J†TUÅh4b2™0›Í,_¾œS§NáããƒÁ`(U®¨¡¨ìweéÒ¥º®ëØl¶rÉ“Õj%!!�#Fкukòóó±X,µ½ÿB!„ç…ƒƒŽŽŽìܹ“5kÖˆÑh,•@•L¤Š’(cÙãe“§I“&@vv¶´4 !„â’b±X((( M›6x{{3þ|‚‚‚*,[”D麎Z²«®èËf³qêÔ)† †ŸŸf³Y’'!„B\’t]Çl6Ȉ#HII)—•ê¤Vt÷]nn.~~~´iÓ†ÜÜÜÚÞ/!„Bˆ .77—Ö­[ãëëKnnn¹G:•ü2–0®i)))Lž<¹ÒäI×u233ÉÊÊ"??_Z§ÎPGGGÜÜÜhР�Ü�(„¢VÈuºb5¹Nçææ2fÌf̘APPP©n–K Ê>® 44‡ ŒkšFbb"NNNDFFâææVêS—3MÓÈÎÎ&11‘ÄÄDäØ!„¸¨Š®ÓŽŽŽ„‡‡ãêê*×¢34MÃl6“””TéuZ×u %''''§RÖ,ʛԒýyº®“��MïÞ½+Lžt]'11š7oއ‡‡üQJPUš7oŽ··7III’õ !„¸hŠ®Ó^^^4mÚwww¹N— ª*îîî4mÚ”† Vz�¶X,ôéÓ§øºŠºòÔ²-P999øøøT¸áÌÌLœœœ¾ÐûXïãèèHFFFm‡"„â2‘™™‰££c¥w‘‰ÿáààPéuÚÇǧÜ8¨’?«egX,–JÇîdeex!÷ç’Hvvvm‡!„â2‘••E@@@m‡Qo=¦©"Š¢`±Xʽ¡¥8�‚Ò/¶Z­•6÷Y,\]]/Üž\b\]]åÁ£B!.‹Å‚‹‹Km‡Qo¸¸¸Tz�6 X­Ö “'࿨¢ïEO$¯ˆ¦i † ¶#—ƒÁPé±B!Î7¹NÛ§ªëtÑs1+{”� ¥_&\ô»B!Äåªìs2Ë%Pe[ ¤ÅD!„‚ [žŠ»ðŠ ”,(„Bq¹«¨å (ÿ*Iží$?ø¼�iÓPBFóÚŒñ4®ì& Û!–<2…UÇ ÑõoòÆ•ûÙu8“ÛvÊeh˜;òI!ê ÜClþòW½º0rPn—IE­¨ë®è»±d�‹PöNæ>òK�ùÑcĉÄÙ’Ê‘=ÛÉÌ3Ê Tˆz&²YÆoÓ(8y„ø�Æî úéïyí‘OÙ£5fÜôç¸*@…ÜãÄ'k ºÓ¸iÆàAÜv{.¿Ÿ§wIž„¨›tÒîå„êŒÃÉ}ìOiJ'ßËïQ eó$ãÅ@žÇîù¯³,>‚[ß}‹››;Ïé9`Ä™Ÿ4Ž­yާ>ÙJb¦cƒ0: ¿›Gn튯 h§øé½WYøÇaNe�‡3¾M»3öþÉŒŽv+< kiìX>›�¾üƒƒ©Vœý¢¸î™·¸¥• ¬Iü±è~»�C) ›÷dÜý02ÊUNàBœ×ÆÍ 6l#ÎÏác6ú¶4’³g{2Íä°�­»N34ÀíDÇ tCÍ"Œ`ÛÏÆ…«ù1Ï¥]W&6=Åï‹–°ag,G“N“c3Ñ |(�¾<žj1_-bÙ·[9œfÃ50Šî×ÜÌø>á8Ÿ©¸º9–�Ÿ~Êš¿’jq#ÐGÃÒ¢-Ű&²ïß,Ú $ôÈ·ìÜ{ŒÖ½Ãq,š¯ç¿õ7vK#Óœ�MqÄÃ7”æí;åçTx]­I™Òåø¯+Ùœň«ÛáY¸Òw®em¬?ƒFuÁÿ"Uì²ùQÑïÆŠ ^PyÛY÷m" ûOfl‰ä©4¯V#¸{ê ø¸é¤l_ÎÌO^惦˘ÚÛ …,âvíâtäL}¬9yÇù}é‡Ì~î}B=A—|öúO~f¥÷¤'¸­¹©¸€z‚ÿ}À¸^f²o[Ï`Ö3³ Xø]�.ìî q)R£ˆòT‰KIçpÜi´–ìÛ±—<ÀÊ�í1˜õÁvô():BZÕ@¡Ü�Úq¶~÷ÿä‚ÉÙÇ|ÌrÙ³ðE^Z�Í莯�™'vñõìI7½Í£=•�Á¯-^µP©+m�ªhæ… ¥å˜Y%"ªéÙk9 ®‘WÐ#ò̯ÍÜ9üÃí|³ç(¶ÞÑg²>—°vté…�ö´÷Ibë½ß²å_+]šüβUqDÞ4Ÿ)ׇQòÏ¢gþÂgkOÑùáYLìÓhúpŽû”w?L×Îl×…¸t™"‰næÄ†”\âÿ=„e�3Ûb²Q#ÚÓ:c1{·“Óר#hºJè–ª”O Š(þ �:“‰Í Ø0œþž¹�a36gü/2*Ì@Êw¯0yÎþúöÒº¥aÒ/lÜ‘�fb賯r{[wr~x•[gý]g¤ QïèY>�€sä`L 5#Òy#bÓiÖ®a©'&Ï@‚ƒ|P $(Ø Ö~;='hÙ3 “eŠ8† náXBQM�ÁšBrª‚o¿re/¤ŠÆ@A™Aäe¾@‘ C¥/,.T@¯ øpé�üŸJ¾ƒ¦†èÊß+§ d�‘©c=ºŸƒy~ôhDÙœÖvì ‡rsIš>ŠÓ‹ƒÂfUpL5ˉVˆ³âDóVM0þCîÁÄîµ²ý´JØàq\}껿ßÍ_»|ÈŒ¦¸Ð¢uãžL&#Ö¸9dÑÑõ,ž|=‹K”PSN’¢AƒG9nÕQ¶¦KËÂñTF‡Ëoœ†ç“–~ˆƒ© hÜÍ»0Y2øÒ¤±'ûÅ’Òº3~•U1ƒÁ�Îü“˜J–†WE—ü²eÊÎw!Œîû5¯m:ÉŸï?ÄÄ% p,ÈÀ åºò…Õ³$">ß—¶Mð*õ¡GÇáÍ?;c‰Ï §©Sá4sü?ĸGâç éq;Ù�æNÓNÁ%zšª)£8àè “�x„„LB'Æ…vw¿Å«0ï«·yöã|Œžaô¾¯#Ý›øÒþÞ·yÅsŸ~=‹©óÍàêGã>wÓ{P4®joËoo­åýµ=è|Otí$!ê#‘WtÄ{ÝzN)Áté~&qq¢õ•�hðÓ÷œVÑ©“ŸýwÅ)t¾kO.gåÛ9t2‹lÕïFMð5YÐ1¢(ît¸ãEžò]ÂÊÍ;8œ’F–Á¯àF„µntÞ÷VˆK[Çc�SàÛžÐr]f naáxo߯¡#Ù4‰*œjPóIÜý»³m8xÕû Ú”î穲ŒâNdÛVÛr€­ÿ†ÔÉ•†Í¢ Üó;‰>ÑDÖ•æ'@™9s¦n³Ù°Z­X­V>Ì+¯¼RaáØØXºvíz‘C¬ß¶lÙB“&Mj; !„—�ØØX:w¾È·“ëéì\»–¸�¡ŒìàSñ¤š”©Œ-™¿×l&«íHúEVöø£³÷÷ßWz�~òÉ'‰ŒŒÄh4b41 Å?KãŠB!ê+Ùié`åÔ¾-Ä£~þ“§s! ”B!ê-“C¿od×iwÿ¦\Ù·M­<<³*åž%„BQcŠ'íFÜD»s-S’êEÛáãi{îÑ�7es¥:–Ï !„BÔ}’@ !„BØÉ®JUUl6Û…Šå’c³ÙPUÉQ…B\r�¶Ï¹\§íZÊÁÁ³Ù|Vº™Íf+e²Bq>988�““SÛaÔ999g}�¶+�rww'11ñ¬6t9JHHÀÍÍ­¶ÃBq™pww')IÞéZS‰‰‰g}�¶+�òðð ??Ÿ'NœÕÆ.''NœÀb±àááQÛ¡!„¸Lxxx`±XHHH¨íP꼄„ Îú:m×s E! €¤¤$²³³ ÄÕÕƒAÞ4…}©f³™„„, (5yµBq”¼N›Ífpqq‘ëô6›�œœ)((8§ë´ÝÒTU•ÀÀ@222ˆ‹‹#??MÓª_ð2 ª*ŽŽŽ¸¹¹áíí-É“Bˆ‹®äuúèÑ£r�.¡äuÚÇǧÚëtJJ ŽŽŽ †r_gõ$rEQðôôÄÓÓó¬v@!„Ž\§ÏÂÂÂÊ¿Ïh”ç@ !„BØK(!„B;I%„Ba'I „B!ì$ ”B!„�*¼ /&&æbÇ!„BQoT˜@õìÙóbÇ!„BQ§,_¾¼Òygõ(!ê$͆5nÚñÑ2RÁf­íˆªf0¢6ðF i†1¢œåÁ…B\|’@‰K‚ž›�å�u(În£»¡xú¡MµV•tkúé“܉vt¦nW¡8Ë˧…¢>�JÔš Ëë0„4ÅØ¬cmGScŠÑ„â‚£o¶Û°ü±Ç>c¤%J!ê9S‹zÏvdOaËS=JžÊ24ïN®XãöÔv(B!j@(QïÙâÿÅØ´}m‡qÎLMÛc;v ¶ÃBQ’@‰zÏ–™ŠêéWÛaœ3µ¡/Zfjm‡!„¢$�õžb³B0^#F‡Â}BQçI%„Ba'I „B!ì$ ”B!„�.ÏJKæ×�§1ã›ãhµËù ¥²ã‹OXñgÚ¥±?B!DW¿(=‡¤=[ØvÄŒnÏrֽ̻}çì$@?Í�ß~㟤\ûÖSWi‰lYµ’Ÿ›ÏÏú*;ÎåŽãYþ=„¸œI=â’pqžD®gòÓ«·óú�iäk ø5"ªCO†Žºšn!N5[�õ+^xžØ1óhîŠRÓí«.x‡„êãVÏ2F@?ͺ)ã˜íø_¼Ø狱ÍÊŽsÙãx¶�:`Ý“Cþ;¦¥þ?A5:ãáFÔsãÚzìX³�äŸÞàÑWÄó¶y¼;&¨NýÏ]˜ý¶‘~`3«WÇ1Iö½žY3n ´Nì¸Nö�õ|òÉj~Ûw‚ô~áD¸™‡&tÆ«6b¼„ê‘—³‹ô*Y™ØZÞÄk·uÀ¡ÀLÚ‰ü¹aÏßµ�!OOç¡+}.Ü…F gäóï2òB­ÿrqÉÇ¢ÿÏ ¼vÇ8˜I?ñ–ÏåÉ¿â™öÁƒtv«ÉeM'ýï÷yjÖ,<èóà|ìw>‡¾|‘©‹Sh1l㹉ÿ`üêDòzúÏÌxú]¶ùfüC·殑ql?TWÜj+ÆK¶ qy¹¨ïÂSx�Å[âHLÉ g|štåº{àÚ–n•ç^‰Dzå–3ä¯[yþÐ5Ìùà&ÂU�#‹îáî¯[3}Ñý´­£o`T<ˆŽnYøÿÙ®3]" ¸}òZ6l¿ÛŸ·ó|ì>øàf"T�ÔµO0až'Ï,y†.`;±ž×ßÜIûÇÅiÎóìªÝÝ©±sÙïN‡æóòr•›f¾ÇРº÷,.kÜNvgû2ðùÉŒi}æ¯K•*TÍ9GKcçgsød͟ĦYqömεS¦sS³xwüSÄŽù¯¥QKZÅ#“>#òÕÅ<Ø&‹?¾Ë’÷q$)‹ƒÝï�gd²ø®GB\.j· 0i$«ï\Ä7¿¤Ðïwö|òÓ60ö¾xÀ'›mKßåýçæà?ïQº8h2ö%žì�Š‚«¯# £‡sçScñvÓIÝñï}:�›,äéžnÕ6‰kGVòƬ?ñ¹ùIÞ¾Â=íÙ~^u3yÒÍlýà)^ýÞ•�“žâ¾FRÿÙÀ’}”H òØ]ÕqtÎ".&†Ó·òÔÃÍpÈ?Á–å3ç… ™ÿ(W˜ ²ã\^Ùrî8k­qøa'»ÒÆžÁÞ=ÇpluÍêÑIßàì„£b%ßb¢õmpؼ‹˜T�_Èa÷ö¢ï§µ3PÇg¯/ {ä«ÜÙÑÆ¢ÚþÔx¿�ÒùeÅ×$‚ùúéñ|tÚ†{DFÞ~£Z5¨]Qÿ`‚ ilÛô'£ºã_.Ç«¦®¸æs`ÑÓ<³ÒJÏ›eb3w Ò2q ¬I÷fþø“Ä�›™òPkÜlÙ¨¡ Qɬ(ÒK¶ q©ªõj¨5¥±›Æßñ'°e¦²r} œÁͽ OÀMJâï›ñó?Ò¥Cá2^¡„‡—[âÑ™îg~iêÎáŸîfãÞxl=[V»“ZF:é¸Ñ±m{Z6qšž÷ý<_ôÌßøò»¢&¾ÎÃ׃6îÚøÿ”(Såqì  àÖ–+:4Ç@;ÚyŸdÛƒßñ×A+W´,\O¹ã\É-~eËéí»ÑÆ8“?ÿÎ`ÄІ(ùûÙý¯BËÛ[RÃÑnµC³b±XP ̤Åǰñ“5Ä9¶æêÖθ8v¥�ñ]þÜzfŸòbø3ÆFËIpW¬ýâV1š7Ç4ÁA©gï³;Ûý¶ígÇž||;àú«[èœÅ?+g1çÙé8ôÃê@?ž4‚G'áåžgâMè:`ǤC�3 5¨+Ñ[X±ú7Îåñ1¡¥[¯ j�‚kxGº´/Ñò}©×#!.µž@Ýzb;ËáÜ\N¾y=Cßüo¦Íªà˜VÕ*$þ¾˜¹Ëbϱ4,&wL¹6Ô––mÞ}57tø•Ÿ¸�ý†3bäPz4ñ,ßÕWØNæ¨Õ—žÑ~•¶��ÍqT‚P2ÉÈ:÷û€Ï.ông`æo“>dî‡w³'¯)#;zÖ‰V‰ÊXþ˜Î¨¡Ó QLx„wá–ÿ=ÈUþ*Š~½Û˜õûV2‡ Ä1æw¶å·æ–nÞ�ò-s?ÏfÈ‹×nlµºv;ÛýV²ÿ"-W%¼û0z´-¼½¡ñƒ·°ãÆé|ÿ{*îñ­Å½*â@è Çø ×Íìýý;6¬_Îs_,¦Å„©üo|kœ«©+ñˆÍóåʶ�ý|P_ë‘—‹ZO ´8hV FEÕ‹þ�OçÆf%OW Î^…'� ÎڑϘöÒjÔa÷ñä}ÍñR޳vúKüVÓ L\ûòºlÿ–/W®ä�{>cõ¤×˜~cs*븪=  £ëU%:ÕÇÓå×j0¢¢cÓ‹‹Ö<œrÓÐe@'ŒoüÈ–Óýh±};)á½èì[û-U1µ½…×î¸g“3Þþø7tú/IUÐ¥_f¿ó¦÷Àóç?Ékwݽ ã›ØšÏÖGF²òLqÍfEÿøVFzŽÕSº×ÒÕÌÙí·‚b6bTt²³Ìh8.ã䃿;KÏêBUHqò#ºßx¢û�æšeS˜üé»|ÑõCÆWWWŽj•pSTlÖó�1_BõHˆËEí&P |;o q®]x¢§7&c$�L«9tÂF@ÿpÊ W°:âèæìÒ­(–Ãÿ§µfò̓èà¡€æB°Gõ@©$Dq&¨ãHîí8ˆ^sîå±/¿aϘæt¨cãb ¡Íhì°š[ã)hYþ†àjŽcuOÛT*>Î5/§àÑå*z»=ÇÆM;Hÿó�®¼’�:~ÞWÜBhÞ"ª’GE(xtL7ÇWØôÝ·xn±qŃWâ©(è½enë¼ÿŠÚâX9õUö÷z‰gGµ¼HÑŸ½³ÛoÀ¹áþ:ëÿÙGÎÈž¸ZÆQâÒ�û]Ô}¨9'Â;µÅwþ*Ž'iZW]WôàÆ„›¾d÷®Dl-Ëtᩞ4ô„äøãX=ûnµK¬ q¹¸¨ ”žq”˜�;q°ærúÄ~¶l\Ç�G=úôôóVQ¸’ë†.eÊŠi¼¢ŽgH+?L¹§8’Äà�-q5„Ð,Ò�Õß/ã˨Dp’ŒÝèI0«Y¿ä;|úDÐÀ�ÂIs—~¥ <à䎟ùûD0�•Ö킈H_œ N±3>ÜàQOTŠ{w®¿¶�-ÿ/q WµñÃ!wÇóþÛ_¥A5DZº�TrœûDÕ°\K§¶ Èý+ß"!»×<Z7åÛÃ¥#Cû4àñaôÈ‹WÞ  ¸úZò Úrð0*8xì}QžÜuaU²ßš2øª|ùÉ\ÞýÊ•±-¬ìX¸ˆ˜ýx¡›{mG @ÁÞÏx{c.-Û5#ÐÓ-3ž?W¯ã˜SK®mj¨¾®4¸’ë†-åÉÅÿã5&0 …7FóIòzѽq(ݺ7bñŠ�™ÑÄÊÀÆî�Gº½½à—[=âq‘(n¨Û—ðÌcKPM.xú7¢y‡xáé’Òt¥Ý]oðbƒ�X´á}^XhW_"{ÝI¯àªzÐó·Ø5ýc¼ð+V— :OŒ¢÷ˆ±Ly …÷–À³_d£™œqoJT�{Å=Qª?ý'\Çï¬çÃõÝisåa~]ñ%db1ºЬ÷<1–ÆuqŽ´¸å5^uÿ˜O×¼Ïó‹³Ð<ð nC�â‡ðUs«Û„RÉq.›@UV®¥ F"¯M‡Uo³#j,ý/‰�Í´ºj‘kQ0d8í.›‘¼•í·Jè詼�ÿs—þ�2¼£úñðËwÓ¥Cég… IDATFÏͺÐt R�„¨ë$�ç—í8ß½ý‹ h3„Çÿw#MëØ@|!ê<©GBÔy’@‰óËЄ ï¯eBmÇ!D}&õHˆ:OF$ !„BØI(!„B;I%„Ba'I D½§Œ`­Ñ›]ë4½ÀF),„õ�$P¢Þ34ðF;}²¶Ã8gzú)TïÚC!D H%ê=5¤wÖvçÌzpjh³ÚC!D H%ê=cD4JžÛ�mµÊY³ØŠžŸƒ1<º¶CBQò(Q¯�¾±°ÅF1šPÂÑ­è)�—ƒ®kµ]ÕE'Ô>è&zâræ> @Ã¥ÿÖnpB!ª$ ”¸$èÖl'bQܽQ½ÀÑ ”:ÞÀªk�Ÿ‡–}ýdèzmG$„¢†*L ¶m«¿]!âòYò]GÏLÁ–™R[áœ7R…¢n«0�êÚµëÅŽCˆ³óy\mGpAøÕvB!˜7o^¥óêx‡B!DÝ# ”B!„�$�B!„rss‰��'77·Ú²’@ !„BÉÉÉØl6’““«-+ ”B! iZ©ïU‘J!„ÂN’@ !„BØI(!„B;I%„Ba'yžB!DNž<‰ÑhÄ`0”û’J!„¢>>>'QF£±øKºð„B!ì$ ”B!„�$�B!„°“$PB!„v’J!„ÂN’@ !„BØI(!„B;I%„Ba'I „B!ì$ ”B!„�$�B!„°“$PB!„v’J!„ÂN’@ !„BØI(!„B;k;!Ê2›Í$$$�––F^^NNNxyy„««k-G(„°—Ôkq©‘ªè:lß½—ø#еî~¡çmÝ©™¹ìܱ�‚ì“ z-¨õ§‘QÓ4bccINN&$$„èèhœ��ÈÉÉ!55•;vàççG“&MPëѾÕu‹¾üš>ÍmÑ¡¶C©ÐW›~§¹gQ�z×v(ÂNuµ^kLÿ`�ƒ\;é¢lólh¼5÷Sº„8Òëªqõ~;—¹]@¹ùVÄÆbËË)5Ýb…{Ÿ|’™o¿†9ùøyÝææ­ùßÔ§YÿÅB@?¯ë¾�4M#&&‹ÅB·nÝÇÍÍ ƒÁ€Á`ÀÝÝ�ððpºvíJ~~>111hšvAcÒuØþÏ~NÄí¿ Û©©Êâ)°Âˆ‰w²tö‹gµÞmûOñÑûÓ±š3ÏG˜Ä¡©L{ýeÈN¯íP„.f½¶·èÀ–íÛÉHN<«í],š?üúi‰ñ—Äv.%µ’@Ù4yÛôêÕ“�KfO»û©—è?h0½zõ¢_ß>Œ9œgŸœLÌ–Ígµ�+Ü7õuzõîÍ·�ÍVa¹¥¶Ñ³wo èFÖÑÒ§< ¿ù.zõêɪ_©ñ¶OgA¯«‡sï�7’—|ì¬â¿œÄÆÆb4iÕªƒ¡Òr%ËÄÆÆV»Þ“§uz\5’義ð#– ¬ððsϱï¯ïíZîB©,U…F¡¡xûؽNMƒÙóæ0ª[k":öF×áái³èÓ·½{÷fÐÀþLœpïÏx�”c‡Š—Óu¸åÑyó™»Ê­óóÍ1ôïß=%¡xZv®Æ{ó—qý„‰ôíߟaCñøä{ÙûçærÛпÆ�aÎ;¯bN)¼¸ÝuýÕœRØðÕB»÷QÔžó]¯+ûŸƒs«Õ©êÿ½.Èʱ1{þrn¸iýúàš«‡1íÙLj߿³¶C»¤Õ©.¼Ää“äåâähÂäàLjF6?ÿ±�ßþü›×§$ÓyÈ 5^—®ÃK³óóz½ê–˜¤“I ëäYL,Zò÷>õ( «7oåôÑýP8‘˜PåzÊn_³Uœ°‰ÒÌf3ÉÉÉtëÖ­FåE¡E‹lÙ²…ààà*ÇN,[·#üs˜¤}Ýå|…]gT˜5mêY-{ >‹ýÛ¿ãåÓ ÿçuHK?M÷è`Æßù8¹6ŽO⫯7°æ¶[ysê“´ê9Ì®m¤gëÜñÈÃäû‡Ñ#®¦Yô­˜-6víÙG^^6P¸ÍnÑAÜ|÷”3ÛLæÓ¥KøóÏ[™?w®nž ¿úF–­{›!cï“ÃYí¯¸x.d½®È¹Ôƒú,5ÓÆ�?„õä~®uáÍnãTF«×oà¶ûà­g§MŸµæ%©váé<:q$ëׯcÕ—‰hß›f`éŸ� îxê5zõêÅü7§/ñîâ ôìÕ‹§WÜÊðÙÆ¿ùnõ|\��‹“¡Ê$Ÿ:IQ‰¯~ø�¼„Ã@á'þe+æc8“€%¥¤¯ßjƒ—|ɵ×�§ÿ~ÜzóõüòÍç…™S V'†N¸ƒ^½zñL‰ø4ÝÄ]O¿F¿þý¸iÜh6­^Tjy›¯XËèq7Ñ¿?&M˦¯–”*“žmcêô™ >‚Áƒúñå¼·¨zoëž„„BBBªü„Z–Ñh$88˜„„Ê“Zs¬]³€GoG£¶X±rq©cg)€Þ£Æ²iÅìâiq‰ºèñ?ž™¢òâìôêÕ‹^½z³ùs ðoóþ¢/9fýû÷å�»náàö_‹×£i0mæÇŒ7žþ2p@?ž}ìÖ¬ÙÈ­÷™©Óg°sóêRëV��ÀÂÂÂðñ*5O×!?ÏŒ³³;ñ )¼üîúkSñ¼—Þ_‚÷ß$%á(NŽÎ:v’ioÀúE…ÝžšO¾ò?­_I~v:nn 9~<¾Þ%PiiiøøøØ½œ��iii•Îÿú×ø�B÷�ùaô8Öþ¾ ËI{û÷5î¹a ,`Á‚…4ï2€7>YÅÚ%3¹oÜÞ|ó]<Â;qï”)$ïߎ¯Øºk'�{3ãÍ7xú¹él�Ïæã9¯1v`wÞ|m:�Œå�¹ 9±û·â­unÉKS§0çƒ6öÞ[ö{~YWm—ª:›@išÎ¿qIüüýZ ÄÏT•]»`qp".á4G÷“š ÷þ�Éh¡[÷Ø4xiÆrN1íñ'pò¯ú7MƒŒŒÂê–kFbsñàó › #‹«–á¤ä3þú›±**© i?ecýW p6å³rîû,[¶„Û}«nbÕš/Jµ2 ùÌ}c‹/æágß*uWœA-àÓ·§±fÍW4êØ›fä—_ Ç{?eåë¯bT xgêdÖ½ž‰“_Ħ™ûÙg`ÎàЉvþ¹ £¡€yo¾Àª/Vq×”7«Mëš¼¼¼â»rìáââR|;tYš_|¹‚±ûƒ³ý¯ˆÂàÝœ ß|f÷v|½ADD$Ž®œÎ‚5«ç3ù¦Ñ 5ŽöíÛðÂàÞ‰eËç—Z¶qhmÚµ£o¯Î »öfTƒ…!W�¢}‡öÙÙÙdggc6gUù¡´&çƒêêdMê}ERr)Èɨ´~µŠôÅêà‘£qÅûPÝñ(Ò»c;rŒ^lûëGróáà�­tîЩڸ.uj T!…—?\ÉË®,žb4ؘ0æFP ù@Ëv=8ôç·lùã²ü­òÌth†[hS¾øq±Ûâú~WÐ¬Û öÿZõTšÙY§QhîM÷>#øëëEÌš3‡ý;~¦Ot#ZuꃮÎ";7lÄ<‚!?—<Ý�á·ü7¨PŽ%'Ÿiò¬ynjP!*ª q[ íôibÆhÉÃÇÓ@ûÞÃ=¨7³g;�‘�GòÑ8Ý“µ?o"Ú^ €Éáòùd ë:J%ݳ{âÒ9þï/ ~bŽ&2d «¾y‡“ãYo÷ßø“(ù§i×îŠâiF´iÓ…Ý[‚Í JùªåçëGvn>äç€É£zù“•ýß§¿�¿îäó¥óHˆ�ÃÅÁ@vŽK´»]ñ8z%/­T|ÑuÈÏÏÅÉ©f Tá2¥»¨{µ gÂ]OR²³aó¶X¾\ðR©òÕô¢…ÉØºŠË7�äíi¯à^8 prr!//¿ÆñŠú§ªz}®zcQÈÊ{6gšgg,àïo {"œ²ùö늻¹ fçƒGS«¬“ç£ÞŸ�’Ç£ìÐ{_OhÝ¡›ý‰+†�g÷¡d y'騩×�«.IIIÁÑѱøÎÑ’_u0�£AÅd2ÑÐÓ�訦\í54k_8QQ`Pÿ¡ÌþkßýòVŸ<Œh ë?T6}‹AÓX¹i+7>3Fv<Íøë²dÙÆRÍ�šfs&ª¢áææÆ¸kFóˆå|¾~-NªÆ¸kÇàì(hš æL4]Gœ5n¼î& Jôñ{yA5”¸`(å.:q8Ód¬_pjvÑ�«�úôÈ‚²œœœÈÍÍÅÍÍÍ®årssqt¬8ZõÍ7�g`Ø„;JMWU+±Û~¤I×Á( ¨ª«µò±çóDn2 ÿδP* Œ&4­ðo·'.ƒ_x”Û†÷£×ƒ÷`U\˜òÊkvÇ£×ðAQÀÑѹƟöÏÄfN'¼Q£â-xº;]ªÜÞ“ÿÏ _ Nnü{ð ]«Y¯váÜt÷ &#~>Þx4ô.5_§(á»ðqî.D½>WFè(hzQ;½N—6Qüu$…—ޞΌ·>DqóäžñÙ0¤3ªjã¹uÖTU'kRï+èãŒÑŃ}öqE÷vì‰;…Á’KXh£ #(<þ£(0dà>xm5SN'óû¶mtˆÂtŸ[Xøûû†Ñh,LšŒÆÿ¾j;¸òtž¼}ƒÇ?Xi‰«zvâƒ|ù{ß ÆÜ]lôí Á>X›4).›‘�Ç©“'pvP oY˜³3pWtœ�]i×Ô›¦m{ptû�„ù;Ó¶Ç0Ró h(hº‚ÙœITx#,F¦+áþÎô1T•Ôô,ÜUÅÙ ŽØr�=r€èFQX­˜Œ5;ä­›D`up"%#‹?­£ý€Q¬úö'œ­<\UüšÑÒÓ«Ñ�ÔL3[¾]E׫n´ûh× 6$%%ÅîmJJ ^^^妛óàÇÍ«™|Ë5´íuuñ‰CÇÄsoÍbí7kx¸Ë TU¡�§GŽ©pýŠÎde•Ð,ÌÍÁ“�;ÿdð™»ú¬6Øó=G‚ÁÈÙô£î9t'-�['Ý^h8{4¬6ž²š„`3y°sç_ÅñUÄ ‚Ÿ_Iɇ*-SÄR³>~Ÿ W�+Ï´ˆÖ„‹#tïy+7-åÚÑqkZiYOwg𷬼«Ïfƒ”SÇ èWãí‹Ús¾ëõ…Ò2‡›šÆ]ÝÅKÓcêËÐ$,Âþ³ZÕgàšœªª“ÕÕû"%9®NЧïHV~÷)#¯Ù‡gD‹âyV˜»àc‚Ü5®è>˜šÞ^r;Cºµá=÷p¾ûvü±ŸI={�Zó›.uu0�ªž‡+ô8Šï?›ƒ^`áê�Ý¡aa7Äÿœü÷TÙ5¿ìãõgï¦Y˜/¿þa¹?~NhÖEÇäà„ªÂ¤ñX£f1ºgptÆY]QÐ5•œœ,7w¢÷ ëøóëe<7ãÜ>\Š®š0›Ó˜÷Ús4î:#´jÝ•Ø-ßòЋ3ðòZ‚‡sÏ[ TßÍâkdÈÕøaÕÇLžöî3æ‘™�…�I£G�›'®ÐwÈX~_·˜'_Ÿƒ÷ÜäX´º;°­þþþìÞ½›��Œ5L0­V+'Nœ uëÖåæmþk/jV<#®zS@£RózõÆÚùÏòpz2††þôì1€/–¾A£¦‹ lM\‚õÌ Äh€Æ�[ñå¦iÔâ²q ÈS¥ItgFŽº•w¿‡ââ‹ox+Vmü‰Ì#3îáwÎú84kJî,XøÝú]�fp!ßœ4¬2žˆ�K­Ç§ >�·|D..D´ìÀéì<šºÒ¤ôñjÑ¢ÛÖn,¼«¦DËlJº™˜;ȳÚ8rü$k¾Ù@ʑޜú$ïÀ*/(%) )Ù§è9哳=Ä—¤z™@Ütí(6|µW[×_wóY¯'+ÇŠŠh888Яs3úužQ\Æ`£Éͪ’›“…¢À+�Þͼ¾ÿæ+’âq0Õ8 Mª*<ÿÈd¦¿�Ïþ�‘–vŠà¨ Âñ1jõ ”¢ÀÔûn" ¡+ß®]IzJ"�‚|7ê*†�žX\fÚÃw0׿!›¿ùŠÔ“'p0ªD„ѱC[¨'÷ã¹»»ãããþ}ûhÕªUµÝTº®³wï^|}}qww/3Ö»žî-WØÔ<¤g|äÂÏ?®¥×µ·sß�W“›y’™ W’›õ1 Ü]¹¢Es\ú£(ðèÝw0í•<úÜó4p1ñðmãhÝ™Ço�‡#¼·äşçÒ²I(³_}ÿg?À²]S/˜ü<+—~¼•p4ðöjH@páÝk•ÅY&�xúîñÌõpbÁW«8ýñb|<]™rߤr Ô€îÝY1ÿeNØŽÿ™OÆ xòǶü1y2&A¾tïØž±S'ãÚØîý öudÁœ™·hËÖmætÊRM7 ¡åèá5þ/Ýøëo4ñv °yÝ|ÝŒ(í|Öë’~ßÏï�—¾-áÚÌΣziSfΜ©[­Vl6V«•ÇóÑGÕv\â2“——Ǿ}û0�´hÑ¢ÒO¬V«•½{÷b³ÙhÑ¢NNN9ÒK‹¦Á­O¼@{�TšúnÍF{ׂœ<¸vÒD&kÇЛ*nu�Ôëú/Ï×Nº…W&§ýÀ1µÎWüsDDwÞy'‘‘‘Ž�ªo½=âåääD³fÍ0™LlÙ²…¸¸8²²²°ÙlØl6²²²ˆ‹‹cË–-8::Ò¼ys9Éžª ÷Ýz7+ÝEüÎ_j;œJÍýük¼m'zÍ-µаƒÔëúkÿÁCü{0Ži3fÓÄ5›ö}FÖvHuN½í—WWW"""ðõõ%%%…½{÷ß!æääDÆ iÑ¢nnnì.�ËQç–þÜv×ãèö?³çb ñsgàcO�{ùÁµ¢n“z]ÿXmðì³H?´‹+Ú6ãÕgÈë“* ”¨S1™L¸¹¹a³ÙJ–Å?¿~]jÞ¼•_áî€Eu"³DµpÍÏ\5r}úöeô5W±üã·A³…ã¦Íü˜±ã&ÐoÀ@èÇC÷LäØž­X  ÷¨±lZ1»x}q‰ºèñ?V»~!.5 „„„TÙòT–Ñh$88˜„„„JËx5p!ºM:ulÏè‘Cùdö»DvÎÔ×§cKMĦÁÈÛîgÕ‡¯…-WK×þȨ&Чo_®»öj¶løï¼Q}½TØô×~®»ñúõïËí·ÜÀΟ¿©r? ¬0sþ ÆŒ»‰ûóÈý·qbåÝ€¢~’Aä¢ÖYvýRnšâê�×ëë0ø…àrÍݤ=1='«ô²1å—HKO£Uc/Z…�aî’Oy·çU`0’”¦±aí§¼}ÿý<>÷SN§§/Ó¹U$­§NÁÙ͓߶ÿË{Ÿ¼Aë¦�‰î=غk'Ý"2ø±‡ÉʳññÒÏxâ¹'X¶è+0Uœà•TÕú…¸Ô¤¥¥m÷r>>>ìÝ»·ÆåMFxà¶»™xë×üöÓ:®¼æŽRó÷ÄeðÞ;ÿcʤiÙ¥Éi™„ùýwJMê¥Õ’Í]ãoÁÓ/”/¿û•‡_x‰oºÖ¾g…1½öÑrö|¿€Çxß>X¼‚Çžy„e ¿W;�ˆ¨«¤JÔ:[ʉrÓœ®¼º8y0ø‡áÔ}xùeO•_ 3#�†înL;–mÇÍÄþ]8jÉšõ´ôVèÜg(®nžœ>}ºx™‘!´ïôöî;>Š:ÿãøk¶d7½�BèIh�PDEŠ ¢ Ø@ÑCôìÛá�íÔ³œw§"þT„óDQA—Ç$˜ IDAT±!Vlˆ ½„j !=ÙÝ™ßÁ¤.$lïçã‰;³ßùÌì7É{¿ó�Ùž´oß–?]1„¸ä®ü¶ò×ÃÚmÓ"‘n§œBŸ3{rçí÷³%ÛÃöu¿Ôh?kҾȉ¢¨¨¨ìj;„„„”Ýæ ¦Rš†ã‹fó–-G,Ë•s¥G�î<:þvµîÅÌÙoWXËþ˜?÷ÜwßèÙï\Ò:¶aü¸ûÙ˜m²aÅ·~í—Ôo�’À3Žü•Gé9³#Y]�Sþ¹¦ ¹¹Y„Å…Ó4ÞAŸ�#yã�7Ÿv.óæNåÉk¯À ‚Ð�äü1q}á×ËxwÚÙ±5�� ;y%”t¬|d©eb#JŒ rs²ˆ¯ÁnúÛ¾ÈÉȲ,ŒŠ~'Ôày9=­íN9�1w�ç‚�ý6l8ÍÛ¤•-÷÷çÒnƒ»³æ§iàóräŸÑõÛvcsïÓ¯ÀÓ“>jàöúØ·o­ýÞ3©¯ $àì�š”› ^ôÝý0ßü<‚é3fpåõ72þºË¹àªÛŽúçÒ4Í ß÷XXØl^ž7ñíº¶$¾Q´_û%õ›”œ³sïrÊÊÏaÿ}CpŸ1€¢oç•›ÿàìT~‚iB~ÞB‚ShÛ<ŒN=/dÞü÷øÛ —�;p¹CÈÍÛ ÀÊ�›q›Ù\;æ&ˆˆÁ4!8¢æ¿ìl6ˆŒŠgó–Í.¯iûf…£l" Ott4™™™~¨ÌÌLbbbj¼~‰^˜ü4 59³oùÓüP:ÈÝûÔ4zŸšÆ£/NçõY/sÁå7ÕÏ}±–/ûŽs[·»¾gúýg·u³ÆøœaìØ¾žSϹ¸Æû! �”œ³ß%έÜãVA.…ŸV<Ï tpöQþa ŠŠòqœapÃÕWòQD‡Œ*[Ïí!7/,‹¶-›S@8¯O�Äég_ˆi¡8ÿP³e·ÁY½2kÚ3´ló&‰­;’¾#ÛÁ_ªÕµo3 <¢ß.ý�¾Û7ѨYr�¶+R_%$$°bÅ š5k†ÃQ³?5^¯—ŒŒ :uêTé:™Ùù,ÿåм>6oßÍœ‘¹y9ÿzð/Ø%â;â=ȦŒ,Ö,[Lë”vz 2¶¬#&<l¶ÿܯ۲ƒ_YJ^±ÅÛ̧dç ®øë @ùŸÝØfÉœ?x§OÆc�¤u§SÉ-ôR”³ƒ�ç ­xÊ‚4H PpA-ÛcoÙßÿîeo™JP‹vå7-(*Ì'ä� ¬]Û&Òõ¾‡[/$$˜œÝ`YtmÃmw>Â{Ó¦ðß÷>Âå´Ó(&šÆM»Ö¸ž[F]HaÎn&L}�ÂÜÉD†‡Ò3µ¡Ñ 4oUuû6ÜpÍžÿ÷£|:w—ßô€_ÇB¤¾ '66–Õ«W“––Ví¼&˲Xµjqqq„‡W<):2Šï~Îà»;ï$Èi§Iã8Î8¥—=x'±ÍS*|Ξ¬<^›>›½[ r@ÇvIÜsÿc`wTûso=ºtãço>ãã{î%È]R[óò¿ÿClÛÊvÿvóh&E3mþlö½6�ÈP7ç÷;•�ç^¤u1&L˜`y½^|>^¯—M›61iÒ¤êŸ)R‹Šs�{Gßß�ÜIøó‹q…GÖqe"r´ŠŠŠX½z5‡ƒÔÔÔJG¢¼^/«V­Âçó‘ššŠÛí>Î•Š”JOO/û>))‰?ÿùÏ$''ãp8°Ûí8޲/ÝÆ@êWx$Áÿþ {Ëö”›z( ì-R }v‘“H=çv»iÛ¶-N§“%K–�žžNnn.>ŸŸÏGnn.ééé,Y²—ËE»v힤ÁÐ)<©7B£áøÇl<[×b~=ïoßàÛ³{|3i½±�u1Îæmý¾JGD#44”¤¤$âââÈÌÌdÕªUe÷yr»ÝDGG“ššJXX˜~®¥AQ€’zÅåráLIÃÓ¢Ÿ¯ìÞ.†a`·Ûq:�Øl8iH\.N§“°°0|ú¹–„”Ô;6›MïDEN0ú¹–�"¿ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤�r‘z'??Ÿ;v°ÿþÃ>t4&&†&Mšà EDäd§%õ†išlذ�={öЬY3:vìHpp0ìÛ·�_~ù…øøxZ·n}Ô>jY0íƒ�hå¥g¿!µ¹ ~3MxsÖº5 ¥S¯­¥"õéX‰ˆÔ':…'õ‚iš,_¾œ’’N?ýtZµjEXXv»»ÝNxx8­Zµ¢W¯^³|ùrLÓ<ºmYðÎÜÙ¶vy-ï…ÿ|&L}÷]vl\Yn™eÁÒßÖ�‘¾¦Îë¨l[õéXÕ7Çóõ‘úGJê… 6àp8HKKÃn·WºÞ¡ëlذ¡Òõ–­ÙÎÍwÝÏ9ƒ.`À€þŒu3^{¾tȧ�ðxaÜC±ú‡ÏN¨m�(tÌDNn:…'—ŸŸÏž={8ýôÓk´¾a¤¦¦²dÉš6mZnNÔÞl¸ý¾ÛéÚØÍßîº WD ›¶î Ì– 64œ %""õ””ÜŽ;hÖ¬Y•#OGr84mÚ”;vЦM›Ã–ý¶i+VÞnþrëÓ4íÜ€Ó{Ù‚Á»ŸüÄ”/ÆS˜C‡6-¸çÖ[iÞñT¦Îù’Sž#?'‹F‘!\:dW\{Øì˜&<ÿÚt¾_´�=;·dððcé9è <^xé�|õñ‡deî s»VÜ}ëm4m߀¢xþÕÿ±øã9x ²éÒ! +7«Š=µñè‹3xôÅ€ÉÄGî óÙ—â3á•·f±pλäíßE‡Ö-¸ý†ëiÓ½w…­ÔlýòÛêØïÒj�UUû\Õ±:²¾)oÀ‚Ù3ÈÙ·‹Äø(žúÛ}4KëUmí¦ ÿ˜8™åß-bÿÞ=ØðqZ×vôìs1³ÌcËÆ5D‡qÍ¥C¸pä `˜&<õÒküúÍçìݽ§Ý¢K‡6Ü|ÝXZ¥õ Äç\~^Þ—�—ß@úÎFŽ>—wŸy„„´~•¾>GsLzœwÓ?ü‚÷ÞšÌþÝÄF…qÏ WÑkÐåUô ( ¸ýû÷Ó±cG¿Ÿ˪U«Ê=Þ"!¯=”ù/àúÔàtUøü¶-b¹ðÒkðn&½õ÷=tÓßøBÂé‘–L§ÇÅ7K×1qÊ3tj“BǾC±€/¾ý–ÍB¸ð®§)òAëæ±<5émV~ö:÷Þ6Ž�¸$^zs÷üí.¦O��Ác_ã×O¦rûu××*•ŸVlàûUUÍ¡1¹éŠAô:$`Ñ$¾t;ÏL™Éâ™/0îÏ7—Ô‘÷>ZÌÍãÇóÖ„ç‰oJ¹Vj¶~ÅÛªîXU¹ÏÁ•«C=û¿Ù|úÎsÜ:f ÍÛue÷¾Lbš´ªQíðÓ¯Ë83¥ƒþr/ûr<<3qË_~Š›¯»�„ëÇðñw+xæÕ—éž–FÓν±€ï—þL¯V‘œw×íä™Lÿ`>7Þ}oMœH£6]ªxMª}Žæ˜¬L?ÀÄçfü˜Qt8ílöìÏ¡E|H ë‘ãMJ®¨¨¨ìj;„„„”ÝæàP)MÝÜ}÷ßyyâS|üÍ0.8÷†^4Œ˜¦­YË¢K»Vô8ýL‚c’¸å¦¡l_÷ ͺö!5¹$7 MÛ¶|¸è~[ù+û-{~jR3ºtÿ#¬ìÏ�ùsÿÇ‹ãÆÐ½ß¹Œw?#F~ʆß•:ˆÏÎà‰±—qöˆQtîÒ�wÌ©r?ãE’””TöÿY¹0çý×xxôÎ>€N�;sYúF¦¿ýwV!É}ªÜ礞ƒ*�öƒ.Î RÓºñáǰbùÏe£’m[6¡û©¥#N={žÆ¥×ïáí¯qËÏUùšêÈcV]?¨ì˜,ÿe+v<ôèÚ•Ä6mh]ã D¤®ìÞ½‡ÃQvAÓ¡_ PÒ`Y–…a.»dÐé\ÐoŸý-sç~ÈÔ÷®æÎk.aèèÛ€òÏiÙ8†#ˆÜœÒÓi ¿^Æ»ÓþËŽ­é„ÙÉ+(¡¤cx•õ¬ß¶«°˜{Ÿ~žžtðQ·×Ǿ}{Èܾ »7—´´ŠƒDM­Ûº£8‹®]{–=æ°CçΧ±bÉTðyÁîðo}?~z¬2ªÙç¤*[*µvËnŒ¢ý‡ÕçWíFùÚããâÉ+,†âpá°CtL¹y¹•Öá‚.ÝÎ`Å/oû}LU]?¨ì˜œžÖ‚v§œÇ˜»ÆsÁÀþ 6œæmÒŽª©±±±4mÚ´,D9Ž?¾]œˆÛí¦°°�°°0¿žWXXˆËUñé9€·�!ÏbÈÀ³xá­ù<;åQúœÞ—ˆ”ò§gìv°00-“•éxôïw3vÈÙô¹ý&¼FãŸxªÚz,,l6/O�¿›øvÝ[ß(š_7`Z5ŸÅ^Y@¬ 5Ý֡Ǫº}® ë(ª­šÓéÀ²¬²«. ì'¦Yõ¶l6ÖÁU l6;^¯¯Òõ+:fG{L\Nxõé‡ùæçLŸ1ƒ+¯¿‘ñ×]ÎWÝVeÍ"º��\tt4™™™~?/33“˜˜˜­Û»G/Š,»vn®vÝ•7ã6³¹vÌM´nŸJÛ6- ލ> ´nÖŸ3ŒÛ×Ó¢E‹C¾Zâ� m‹Ì h~üñ›ÕlLnîá£&¥íD±lÙ÷e�y}°bù¤¥$6úTÓõ+ÛÖ±îsÍÛˆ`Ù²Ê-ów_�…Ï„•¿ýLû¤V`w`³AdT<›·l®pýÊŽÙ±Àާ¦ñâ3�1ðÒ[x}Ö{à)©�‘Z¥( ¸„„V¬XA³fÍp8jÖ%½^/têԩܲVnçë¯sJ·DDDzï@!oΜM#·—ä¶ÕOnÛ²9„óúÔIœ~ö…˜öŠóU‡¨ØH8ð(&NŸŒÇIëN§’[è¥(gÏJt¸ÁÅ#®eÂ[ÏQL(mºœFn¡ _a^…í9ì�’’ÆìO¿ eêWäD“(­;ö`èðkyþ͉!qĵJcæÂÅälþ‘‘ãÊÏ݉§Úõ+ÛVRj�cÚçŠN—VØÆ�«øÏë“($„¤ÝÉÊ+¢ubÍZwòk_ýcðÑ7?Ù좚3ûÓoÙ¿ñ{FÜT:Úh·ÁY½2kÚ3´ló&‰­;’¾#ÛÁĪ^Ÿ£9&›2²X³l1­SÚQè1ÈØ²Ž˜ððÒ[oˆH½£%Nll,«W¯&--­ÚSI–e±jÕ*âââ/?/Éd##ËËç^&÷À>‚ݤ¥¦ððÓÿÁÕ¸ÕÁ‰Ñ•ëÚ&†Ûî|„÷¦Má¿ï}„Ëi§QL4�›v­v_þvóh&E3mþlö½6�ÈP7ç÷;•�ç^†Á=×'.ÂÅÛ³g�ùú ‚ƒ´m–H“Vm˵ep÷�×óØÜýÐ#D†87v$­;öàÞ±#ˆpÁÄ·Þ%?ëU:´n΋O>IBê©ÖUÝú•m+¹šUí>× @üõÆ+y5ÂÍëÌ$kò›ÄF…2þ–14kÝÉï}õ‡ÃÊKoÎdÿîm¤4Oà?ÿ�ÝÎ*[~˨ )ÌÙÍ„©ïQ˜;™ÈðPz¦¶#4:¡Ê×çhŽÉž¬<^›>›½[ r@ÇvIÜsÿcµ:Ê&"µÇ˜0a‚åõzñù|x½^6mÚĤI“ª¦H-***bõêÕ8RSS+‰òz½¬Zµ ŸÏGjj*n·û8W*'Ÿ ï¿•«{6aÄ  t9"RO¤§§—}Ÿ””ÄØ±cINNÖ$r©¿Ün7mÛ¶eÛ¶mew���%$¤ô>8dff’‘‘A\\Í›7Wx‘€Q€’z#44”¤¤$âââÈÌÌdÕªUe÷yr»ÝDGG“ššJXXX•W߉ˆˆÔ5(©W\.N§“°°0|>_é¥è”^.n·Ûq:�Ø4©VŽ‘ÝL™è2D¤S€’zÇf³i„IDDê5½•ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄOŽœœ¼^/>Ÿ¯×K~~~ k©×‡¨ÐÐÐ@×$"""R¯éžˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“#Ðøk_N!Ë~ùOÞn�? lå3`MÖ9Z .Y|þÓz~ð¯Ì›5°Žz‘£ðµk¿IïÁCéÓç,¦ük| Ë©VÀÔ›ÌÖ— Ìüd1Þ=Û]’ˆˆˆH•:*¯>œû.G :õç—¥_1wÎ4†]÷—²u²ó|üûÅùñ«O±Jòˆ�oŽqD;Õ­ã3áß/OaÅ�KØ™± |Å´O‰eâ‹oáµ1åíÙ|4ç]r2wÒ²icF^ÂYƒ.£´•O¿û�ÿM~‘ŒÍës‘Ü2–ÿ<ñìQqU.óú8¦¶EDD¤~ h€úpñOxöíd@Ïöœ{åMü°ì;ÞY°�aWÝ îPLþòÄ3¬þz>vÄÄı}ûÖÃÂQMÖñú`æÜÙ¸ r qasGâ¶ö ž|i:¿ó2ÁNññMذu>ý,ÏÙé:`8;÷™<ø÷¿T˜K‹&‰Ø\aìÎÜ‚=4²ÊeO¾|ôm‹ˆˆHý°å3áý¹ïâÀËEƒ†Ð±SsbZ´eÇ–ßøå«yt;ç26f°ìûO µ{˜òÌ$�ÚŸiýÌÿ=1®¬�š¬ó;›Q”gž¢qÚéx<¶ïó1ïƒ×‰póÞ«¯‘”ÊÔ¹ß1é_ã™9g]û_ÌŽ½û±Š q•ðÚóÿÆß �× ;öfVºlûÞck[DDDꯀý¥þmc›WýH³H]z�v0à"ÞŸ²š÷ç͡ۀKX»uN¯‡øFA$u9g�ó°vj²NEœN'ËׯÃ^\H‘Ä�kn([f¶íÙ¦�ÔV±4j–Bî–µ ¹j4çô=“+G]Eã¤öU.[¾~ã1µ-"""õWÀÔû- Èçeo¶AŸó‡”=nß®Ø@Þ¶u€�x¼>ªºAMÖ©ˆiY@°ËdÔ%£ñØíeËb"`³â†×_x�©oÏàãùðÁÂ/ùtñb^Ÿð<ñí»WºÌ´B�¹m©Ÿr^A|±h6š$ÄÑ¢E‹²/§;”�“O>™MǤVxAìË1YòñÌ ÛêPƒu*Ó¾UKJNJ<­‚¹îÚk¹îºëvÉå 2l6<^ —­€»n¼†™ïÌ¢q‡žäÁ�?|�·Še©ÇضˆˆˆÔ_�úìÇÕxöï"*¸„·_}¹âìñ—ßeá´˜óÙ"†]sý]Æ·¾É_þù2�^�AA‰yXêKJtU»NeRš¸é{î%|?:=;…°W¦aÙœäçïç¿O=DJ¯óXºvwÝ~­âã�fwúF äI“æü\Ųäcl[DDDꯀŒ@-ødvÓ¤o÷Î{ز úŸ�Çî`óÎ\¶®ø’ÇÆ]Ïco#®IK²rr±¼…$µhÂ)Ý{†AµëTÆ0à‰»oäÊ?ßIBó$ò‹Kð–Ð>%‚‚0Íb’Z¶açÞ,6m\K³¸î¸îJº�=¼ÊeÇÚ¶ˆˆˆÔ_Æ„ ,¯×‹ÏçÃëõ²iÓ&&MšèºDDDDŽ«ôôô²ï“’’;v,ÉÉÉ8ìv;‡£ì+àw"ih DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@Õ3y…>>Y´LŸ_ËDNE%ðÎï‚§8Ð¥ˆˆTJê8ñ™ðß·gòígsÀ²*]¯¸ÄdSúú שj™Hu¼>˜ðê$¶¯[~Øã ¾ü‰åK>«öù¹>æ<·Î¼×{öîR??ɘü¸|5oL{›W^y…)“_åó�?¨²¿¯>)RG  8Y¬NßI8%¬ÜšIÏœý8"º$9 Y|´ø. ‹ ªI+¿ž[â1ÉÈØV7…ÉIoÑ’eìßò+C $:¡)EŲ²ö€Qùû|õI $¨ãÀ²`ÅÊeô;µ?mÍeÕêetî5 lùšM;øþ»Åx óˆ‹ÄnšÕ.+*�÷?œC~Ö^l†ÅEÎ"¶e;ÖoÙÍ�K¾¤¤0ŸÈ0çôïOX£Æä™|ôéÇäíÛ�ÍfpÞY= mܶÜcñ­Ú÷ã#Ç�Íðræig3wÑgŒz ްÈrëTÖ‡ ‹m¼ùÖ4ÀäÂ�} ŠiÅ̹³ðæåàõzi�-8†];¶a™ztjGÚ)gbaðÁÇ‹ÈÝ“�Ïç¡k‡dºöèC~±U®†$üѳrJ˜ýá» 9³'q-Û¯Ã$ÇYN¾Åêߖ𧋖зËIbãÒï-‹ û”ï“‘‰­*íÃs>û–”ˆ:öèG±&¿ù*c‡^„;&�åv’±rç_8ŠÙŸ¹­¾¼ÿÉW´�òѱg?æ|ö-m"=¤žÚ7‡Lê¨ã`×¾BJl#±Õ@:‡ñÅÇoÑù”Þàt‘•ëcÑrùyçÓ$‰�Û÷ñÙÇÓª\æõÁ¾ý[¹uôXpcY&Ùy>¾þj>W\0„à˜8–,ßÀ×ß,bÐ…W°zÓ6B}ûqõÕXX–�¥kÊ?&'¾Ö-âØç9“Ï}ÄyC.;lYU} ØerÕ•£Àf ¯²³3¸õêëñ9ÜÌœÿ )î]=š½Ù%¼óÞdRÛuÄÍÐsûaùEo½û:íSÚ³zwQ¹>XppêSAž‡¹Ÿ,à¼Óº*<�àvïÏ"ÌiפÂå†A…ýGL¹>YUnÕ2‰m«¾ £e‘±çf‘‡�;·�“ÀöŒí¤4o¶Š·•’Üš Ë>¡cŸec÷®túw<ëx&©g Žƒ_W¯¢KJ8œ4Opâ ŠeÇæµ4iÓ™-;wÑ<*˜˜&­À€¨ˆ,èrY)«ô7 `6¶ìÜAI~ïô ¦iávzÀ2ižDzŸ<|÷Õç¤vH#*6¡ÂÇäd`qF·ö¼›±…5¿|‹�«lÉ–�»+íCÕ±Û qbs¼9À0ˆ‰tEA~Á!Ñ|¹äGvn݈«¨˜Â¢<š'$VØ}>3çÍáŒ.)4IéX7‡Aê «‚ùnE%ðúôW¹~Ä¥˜ÁQöÂbÊ=¯ª>œÜ4‘ï¾:ÅElÉØJ§¶©lÞ¾�V©=Ù¹c=ýÏé�×G…ÛjÛ"…o¾öPœ•I6¸) <¾i�©¿ êX±6mø�݆Ŋ�oà+.á·Õ«hÒº†a`Z`ÆaÏ­jYE,Ë".ÊÅðË®(7o ¡QW]qkÖodÖ‚O83-™vÝΨð19ñÙ 8§ïÙÌšý&1a±Ð$¨º•öCªœÜm·ÛöÙÒlo·;0M“¥kÒÉÛµ–Q#.Årºycæ, *î—ÍÚŸ�ÍfÒ&¥=?¬ø•æ-ÛâŠ,ÿ‡RNñ1Ñäy `ÿnBbÿ…*.)Áª¢ÿ”ý^<¤OVÕ‡CݛĎm›Ù¾m-— Ì[óÞ&uç~B�b‚%ðÃªŠ·å‚äÖÝX³vy®fthѼlÔKNNº ¯Ž­Ý²“&ápÍ5W3zôhF�͈ËþÄú=ûñäì§Ubcväxرi pø;±ª–U¤ebcvæzÙ¾a%X>ÓÂSR@±ÇƒÛiеc[:v=ƒÍÛ¶à)))÷˜®|:yÄD89¥çvìÚVÏ«êCÁnÅ>(>°ËŸ×Sãm™>§ÃŽáp–>p°›UÔ/ ä×)i´J=ƒ9 >À*.¬Å=—ú&2ÔFR›SX¸è3òöïÀ4ÿxÛXYÿ©¨OVÕ‡ Ú¶éÀW?ýB¬ËÂB\ãö|ñå'tNIÃVé¶NíÔ‰ŸÖoaóÚ¥´k«‘Ñ“�F ê�eÁšµ+éšÒú°wBÑávbâSX¿î7:ôèËyçå‹oSøÅw4ŽŽà 2ÌV鲊D‡Û9÷œ¡|ñÝ—-þ§ÃÆÀÞ=hÚºkÒw±ôÛϰî zŸÁªÍ»Ë=VYÛrbêÚ®ë6´)ûQU ‚Î�ÏbêûsqØà¼>§Ñ$­FÛéÜ6‰�¶oàµ×§ätbÇ‹Ý骰_š¿wAÃâôníù`ß^¾ýúÎ<ûBõ-ìí IDATÏ”aÀyg�Æ’Ÿ]¼7ïc¼E6ƒfÑQΠJûOE}²IJZ¥} Crs–|W™ÝSÁ€Ô¶©|¶q)íÚŸ TÞWE:IhÞsßÂtúî¤gL˜0Áòz½ø|>¼^/›6mbÒ¤I�®KDD¤^ñúàý�Ò»}357ï„”žž^ö}RRcÇŽ%99‡Ã�ÝnÇápüñÀ:EDDê=Ó‚éïÏÁ—·�S:¶%1¹C K’z@JDD¤ 6®~Q Ë�z& ª°PBEDDäØlÛº ODDDÄOõâžišdgg“••EAA¦YýMûDDDäøHHÌ�– ÃÀétâv» ƨGWâ<@y½^ÒÓÓq¹\´hÑ‚°°0l6 ŒÉñ·dÉzõêè2DõG©_ÒÓÓiܸñqß®išx<òóó)(( ** ‡#àÑp€2M“ôôt5jDÓ¦º§†ˆˆˆüÁf³ár¹p¹\äååqàÀbbbêÅHT@‡z²³³q¹\ O"""R¥°°0 è7¢4@eee‘˜˜ÈDDD¤� S€‚ÒÛ„††²i OÍ?‡³.4@ù|>ìv}šµˆˆˆT¯>]dV*i  DDDDüT?n¦ """'¤x€M›6‘““CDDÉÉÉ<þøã�.ë˜)@‰ˆˆH�ùñÇy饗p»Ý”””pà 7º¤Z¡%"""µjóæÍ,Z´ˆåË—pÓM7¶|ܸqtéÒ…¾}û’””ˆ�Yƒš•·ü%†µåœWva•[êeïOoðàÕçеU,1½ÿÉZ_ésÏ<=òTšG¸ ŽIá¬k'òýþò-”*&}ÞŒîÝšØP7¡ñméwÝÿñcöë[»^á·�aüñåìðW~ò–¯ië;WÓÚåâŒo¤²Oø«íöª=^¾ >zøb:'†ÞŒS®ø'_î­ìxÈᎽÔüõ>¶‡ú£È è†nàí·ßfÕªU._µjÓ§OçÆo<Ε՞1åËZÎÌçáágç²>ßNÿrkòëÄKúx½Æ^Ïß&=LR‹Ö´°¾uL¼|(�g�ä…¹¯Ò©ä;ž½ínÿ)”_f�¡ù‘2w1ÿ¼÷ ²/¼‹—îo‰µz:øvF8Ú°úåsÌÜòìݸwÞdF5)mÀp'Ðö°£i±wá8ß¾ˆâàªo9_ÛíU}¼<üö¯K¹ôß¹\òÔ[<“¸ŽÉy�‹¯Šäç7�Ô "uÔBÿ¨Ùë}’lOýQä„sÞyçù½þÂ… 먚ºÓ”�ô×îäÞ͸mÆÿ±lôíì>b�‚¯dÔ?<øÍ÷ŒM :üÙ«gð¿ïÂ5çYþÔ7èÆKO/!åòI¼½ñjîmsÄ}¨ÂÏe²å8ƒœ¥ÿ?¸Î¥ó¸|É·lô�Cg;X²È6šÓùÌît�¬¸jïúI\3ö úÿ÷UBïÎâ*ö°vÛ«æxÅK/þL“ñò­gàÎp¯¡ýðç˜ôóXžìѺD ÕBÿ¨Éë}ÒlOýQ䄳páŠüÑÞßÙi}秤ÿ0•{4%èÈÅÖ^f>3™tÇv&I¢Qt¾ÿkla=8½Seó+JX7y$çÞ³�!o}ÌÄ +>PŽ(Z÷¿™—žAð¯ïóáz/™ ÞfáÞ5<Û/·Û�;ìLžY[Ä÷÷w$îê(®jgj»½ Øâ‰g»öøþx°h;öÄ'Æ7üq\mÿðù·ü$Øžú£ˆ4T †fX*i­,^ýæ{rniF`î]Éo»�¤´iNÙ“-„¸–É”lz�QÏþL“+eptÅï|s¿üÃïZÃùo.bÂ�JþxÂ4?hÐèÒWùµwþ· ðýƳCGóãˆ9L»ãôòs¸ŽC{‡²'÷â´„>[ô Åç÷Âä}ý)Kxbပù>c{Žå» ßá‡çnnå�G_bGï¿sM‹Ý,_vð6ÃMBÛö$mdæ?ß%»}wRblX÷/?þEÝå¢6vìŽæ´;ôÊ#o�‚ ÜñÉ´m™ïsí¡ÛóÕr{Õ/×YÜtKw¦>~·µþW$®gò½Ó(ì÷®?¥áw‡:wŒýƒj^ïÚî�õ~{ê�"Ò@�¿¡ì´¿c³ î`üÃ8=ÓFÓž#yeο8?ÊŠùâ�þŒœJrç39ÿÑO˜um_š2tcYÖ#<žü°´€¬¬{8kÁ!›qtà¯K~å�óسr>žÿ÷•àŽmM� žäÃÜAÇÍögÖr{Õr’vÏ»¼“ ÷=x)Só#é0øaÞáÏ$ëí~õ޵xª^nQËý±¾oOýQä„÷ûí Žü·¡3&L˜`y½^|>^¯—M›61iÒ¤:Ýhaa!¿þú+½zõªÓm‰ÔÔ’%KÔ¥ÞP”ú$==�Æ�×xýšÞêhîµk×®²Z‚ƒƒýznuÒÓÓ˾OJJbìØ±$''ãp8°Ûí8޲/½Ç‘ZζmÛðz+¾Ü×ëõ²mÛ6Âë�xRo�§ðDDD¤>6lwÜqùùù•®ʈ#ŽcUµKJDDDjÕ•W^É•W^è2ê”NቈˆˆøIJDDDÄO Pv»Ÿ¯²»!‹ˆˆˆüÁ4M £~|üS@Tppp•ÌDDDD~çõzq8êÇô퀨èèhvîÜÈDDD¤�ÈÏϯõ{?­€¨¨¨(JJJÈÈÈd"""RÏåååašf�(›ÍvØ¿U®[gUÔ€Íf£U«Vìß¿Ÿµk×’““£9Q"""”~ôSII YYYU§s âãã±Ûí$$$T»nÀO$:RRRÈÊÊbÛ¶m(DIÀ,Y²$Ð%ˆ”Q”ú"!!�]»vdÛN§“àà`‚ƒƒë|ypp0-Z´¨ÑºP†aCLLL K©–î%"""â§€Œ@eggb³"""r äy PQQQ�جˆˆˆH­Ð)<?Õ‹Iä¦i’��MVV˜¦è’DDDä š\Ö_ ÃÀétâv»�ËUxþx€òz½¤§§ãr¹hÑ¢aaa5º�•Hm[²d ½zõ t"@iìÑ£G Ë`ëÖ­4nÜø¸o×4M<ùùùUo>Ê% U˜¦Izz:�5¢iÓ¦�,EDDDê›Í†ËåÂår‘——Ç�ˆ‰‰©#QêÉÎÎÆår)<‰ˆˆH•ÂÂÂ0 ƒÂÂÂ@—8@eee‘˜˜ÈDDD¤� S€(,,$444�%ˆˆˆHáp8ðx<�.p€òù|Øíö@– """ D}ºÈ¬þT""""Ò@(@‰ˆˆˆø©~ÜLADDDNH‹-";;›ââb\.ÑÑÑôë×/Ðe3(©3;wîä‚ .Àn·cš&óæÍ tIµBJDDDjÕ�ؼy3{öì`þüù‡-ÿä“Oˆ��§eË–DEE¢Äc¦%"""µªºQ¦½{÷²wï^V®\ɨQ£ŽSUµK“ÈEDD¤ÖL›6­Nׯ/4%"""µfÔ¨QL›6­ÁŽ,Õ”F DDD¤Îü>Âtä¿G~ßÐ(@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDD¤Îü~;ƒ#ÿmè DDDDü¤%"""µ*((ˆœœLÓ¬p¹išääätœ+«=º¹ˆˆˆÔªvíÚ±páB<O¥ë8�NÚ·o«ª] P"""R«:uêD§N�]F�Ò)<?)@‰ˆˆˆø) Ên·ãóùY‚ˆˆˆ4¦ibF Ë ‚ƒƒÉÏÏd """Ò@x½^Žú1}; *::š�;w²i òóó t@€TTT%%%ddd² ©çòòò0M³Þ¨€ŽƒÙl6ZµjÅæÍ›ÉËË#11‘ÐÐPìv{ Ë‘zÀ²,<ùùù˜¦ITTT½™ð‰‡ƒ””²²²Ø¶mšX.³dÉ’@— RæÇ t "$$$°k×®€lÛétLppp½ OP€aÄÄÄèRDDDDª¥û@‰ˆˆˆø) #Põe˜ˆˆˆÈÑДˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøIJDDDÄO P""""~R€ñ“”ˆˆˆˆŸ DDDDü¤%"""â'(?)@‰ˆˆˆøÉèDDD¤~)Y¶˜Âùÿó~fQ>x<`ÔñF-ÀéÄ‚³MwB�ÁÙù¬:ÞèÑS€о|ŸÜÿþ+ÿÀá ê(†;Äï箢Ÿ‰=©ciˆúëˆÚ/ò((@‰ˆˆœ„Š¿™ƒ§Žç|¼žÃÖ:ö6úõëÍû¯ý§ôÕ8èíO~¡wŸ>\1¼/xJؾ'�žø7C.Aÿþý6t0àvoZyÜ÷SDDޝÝY½å¡q£Á4ýz®Ç ãzˆÕ?|VGÕù§²zl6hÙ¼9�â}Û¿~…™—}¬%VËߌ NgÖZ{®®}±Å5ÁÌÍÆ³üëZk÷hljמ=xŠ q9 #+§€%?¯àÑg&rß�c ?ç°õMÓÆ„×gòãÂw+m³ n¸k_~ô¹Y™ìÏÎcñ7_á2}uº?""xÓ?üˆ,^¾‰]« t9uÂnƒ{�ó.ûóQ·‘ÿáäZ¬¨< 0-qkÍ&Œ×”a2üL òç¿V{텟³¸ûOC™7ïCæ/ø„ëï|ŸÃÅ÷+¶2cê„rkûL;?û»Vÿ\ak?¯Í kûö¦>÷-ZÄÜùóØ“ÿ&*9­®wFDD(¿æÎy�»Çޤe—�ÌxïÍÃÎZ”x ïðËøtÆ‹e�¥ï,¡×À~lû勃�ØxôÅôéÓ‡>}z³üóÒ7í>þï�Y ½t$ôç¶®aýÒ?F@L›0™KG^É€�çpÎÀ³yàž›˜3g!×Þt;Î=—K† aî´—«iêœ/’nÝ:ó÷ûn#¼Õ©LûðÓH)ÍÓ¹kWú÷éÁîÆf/aÐ…ÃéÖ½w\5VD"+–ÿq%5¹ÝNíIûömùÓCˆKîÊo+­²ž#eçÁ¬™S7zC.¿†.]»pÄT1GÊôú}\jÊ:äËpÔþ8�áp–¶ïó`YVµëוz Ì²Pd•;oêtøxbüxB›¦ðþç?òý§3»‚À0àáۯ湉“9û‚aXAá,Xô×Þr;KæM;nû ""Ç×Êôl¶¯ûŠó Àå„Aƒ.eæÇŸ€§ø˜Ú^·u7Fq]»ö,{Ìa‡Î�Ocņ�à«8ŒÄÇÅ“WX ÅeωŽI 7/·l�…_/㺛oç‚!rù%“·m=%%%~Õ·vËnŒ¢ý‡ÕW½ºþdàÃÎTÖrÃÛ¶ê~ªRïÔ’ï¿Å°,šÄÅ@Hù¤aðÀøÇ(±‡ðý÷_WØNíÔ†GÆ�cÖ{³éÔg0Ÿ�ÉÓ§VÚÉED¤a›¹`Ù¹àªëÎêÃû“ŸbËÎ<6üüPú&Ûf³ãõV~Q‘Q‹ž�NGéÉÁ�ûÉi–&‹•éxôïwsF»&üëŸ<þäó„&~º±&õXøŸT ûñ™Ácykÿï®õû•úu0ºå�z 2³òyáµ÷øö£·±#Î;Î ×=³KsÎq]¹*Ÿ }ö1Y{vàrÚ‰ˆŠ ¿°ÈïKZED¤þË/‚/>Ÿ;¯¹˜ÿN™Â”ƒ_“§L¥qûÓ™»`X6DFųyËæ Û1  &77÷°ÇÛ¶HÀ ŠbÙ²ïËóú`ÅòHKI†£ #+7nÆmfs혛hÝ>•¶mZ]m=Gjݬ1>gË–ýPãmÁÇ~_¦š°êàV ¿·i‡ÖzÛþð$rƒNyŸg^›‹ÇS‚eYØ xz.uK•ϼóOWðíד¿}CÙcËÖeòÈãOäób·Ù°00M6Î>­g¥�LDD®ÏX…-w+ ~çÆûô¿€¹¯=À¸ì=Ø£8«÷@fM{†–mÞ$±uGÒwäc³Jß\;ì�’’ÆìO¿ eêWäD“(­;ö`èðkyþ͉!qĵJcæÂÅälþ‘‘ãž;êºÛ¶lNá¼>u§Ÿ}!¦=„âü@t•õ$¥ö8¬�ØH8ÈUüçõIBR‡îdåÑ:1Œf­;U¸mg›î/]tÔµ×TáÏ‹pY­¶YðSé}±‚Úv¯Õvý°Õ´q"ùÛÖSRT€ÃnÑ(:‚Ô¶) >ogô\z§°*„‡Àm7ßËãÜ ”vþÈP bå¯KÉÊ܃ÝfѲY"çö;ƒ+Gÿ¹vïE!""gY0ïãyœÑ!g|órË�Õ›×'…ðåsé3ì:nu!…9»™0õ= s'JÏÔv„F'`p÷�×óØÜýÐ#D†87v$­;öàÞ±#ˆpÁÄ·Þ%?ëU:´n΋O>IBê©G]{×61Üvç#¼7m ÿ}ï#\N;�b¢iÜ´+@¥õ$ þz㕼áæõf’5ùMb£B˘JTðàk(‹ºše�=s"¡g_Z{-‹3_Ä0 øü?ÕN›Gɘ0a‚åõzñù|x½^6mÚĤI“Z”ˆˆˆÔ­Ìk»bæÖÍ ›ø, � ñ¾†»kßZi·èçÏÙóÄuEFÑø¿K±U3Ør¬ÆŽKrr2‡»ÝŽÃá(ûª7s DDDäø ¿ö±£˜~^3†qpÒ¾»ÿ};fQÁ1·iæ³ûÙ;°1æáZ�ð4 DDDNB®Þâh•ZgíØ   ‡�\Žå;ú�T³|^v>pæáNîHpï‹j¯Ð£¤%""r’jôÄûØÂ£«_ÑO¥£O†àdÓol¿w(f‘ÿw7‹ È?ÏæU8Â#‰yt6›M#P""" N1OÏÅY'ÍÛ0°à´x7¯dóugP¸ô‹šÝeÓ²(üùs6�= ÏÆå8ãˆz.6÷ñ¹CuêÍgቈˆÈñg‹kJìËKØ÷·áøÒW¼(ïØ¯Î3þdžQÚžÍÀS�CÆcc°Ç5%öÒ[ =õlŒ°( gém†,�+/›¼?cß{ñíÝ�Ý€à”ŽÄ=:›;Ã0>ú P"""ä¦Ñ3ó)þn>¹“ÄÌÙ_+Íþ~*�ƒ!ʰx- _f»ÿïþÒÏ´;b4Ê0Œ²ç¹"¢ˆºöaBz_ˆÍf«§î~§%"""¸N¿×éPòë×.x Ϻ¥˜…ùàóp´—ì•͇ÂÀ0,l–�Ï*½Õ�‰…e¥M`w�;w›n„œ Á]Î<,8Õ—ð P"""r„ .½ êÒ»VÛü}¤É²,LÓ<ìßC†Q˜qªOá À‘““á7ÒÌÏ÷†¼ˆˆˆHU @v»˲*½æ¡£Mõ-8ýÎqX€ ì‡ó‰ˆˆÈ‰ëÐ`täèÓ‘ëÔg:…'"""Ñ‚Ret(?)@‰ˆˆˆø) §ðLÓdÏž=dffRPP€iš�,GDDDê!›ÍFHH±±±$$$Ô‹S P%%%¬Y³—ËE‹- «t6¾ˆˆˆœ¼LÓ$//��;w²wï^ÚµkGPPP@k Hb1M“5kÖШQ#ÚµkGDD„“ˆˆˆTÈf³A»v툉‰aíÚµ•^ÁwÜj ÄF÷ìÙƒËå¢iÓ¦�ؼˆˆˆ4PM›6%((ˆÝ»w´Ž€¨ÌÌL±iiàÉÌÌ h  P………ºa§ˆˆˆ•ÐÐP Zƒ Žÿ�¬|>v»ý¸nSDDDN v»ŸÏw\·ydVÒÌm?)@‰ˆˆˆT ª3t¶úp3*‘úîÐÌd«èA©\¹Iä R""""~œÂ3Œÿoïr†a( ;v8Ày¹(b ;ÒY@"“º ‹IG�ù?©JŠ éòÉqK"@<ùläçÚ >Ë~¿_m=°-³§çž½Þ} ªsU3›…'ßæÔ*P¾yüx<Êý~—RJß…)TKóŸffr8†]lËÒ‹/ÃFp’¢ÃÌfÚ½T z>ôÌ^¥Ú”¯>ýV€Ê9»>Ø–(@E/ _ª>EU¨¨‘|V�Zº�”R M5D™ÙKxжñF¨œ³ìv»a×Ûµ D$ OïªR}øÊ}‹¯=R¥”v^{§|hZ³ÿI„ ø^ôgÀï@ KžSIDAT¶ó> R/[xµºÔ/ê›Ìë¶ÝÒö]ýl (ð�O·ò¢ñmʇ¦–êuÛ®¯<õ(ÿûh>‚™‰™ ]lKôRðèi¼¥í¼OÆ/èX=ïù,IEND®B`‚someipy-2.1.2/docs/images/rpi_pc.svg000066400000000000000000000165051513043235100173770ustar00rootroot00000000000000
Ethernet
Raspberry Pi
IP: 169.254.54.11
Standard PC
IP: 169.254.54.10
someipy-2.1.2/docs/images/service_discovery/000077500000000000000000000000001513043235100211225ustar00rootroot00000000000000someipy-2.1.2/docs/images/service_discovery/multicast.drawio000066400000000000000000000202241513043235100243360ustar00rootroot00000000000000 someipy-2.1.2/docs/images/service_discovery/multicast_service_discovery.png000066400000000000000000000517021513043235100274510ustar00rootroot00000000000000‰PNG  IHDR¢ñ‰f³‚sRGB®Îé IDATx^í}|ÕöÿÙ’Þ+I Tì¨X©‚ ˆ°‹‚ÈãÙ `A%ˆŠ>@à)"Š ±"U}x*"¢€„IHï›MÛòß/¿ÿëº!»ÉÌdgæÜχ�ÌÜò½÷Üï=çž9Ç@\F€`�DÀÐ�msÓŒ#À0Œ1ñ"`F€èP˜ˆ:~nœ`F@ëDd!¢"J'¢üžîÞDô?"Ê!¢Ünž`ˆ^&¢‰è "ÚË€tr‘ѵùÿƒˆî$¢,"Š&¢R"úŽˆž!¢ßö“Dìj{ÕÈÔžÓ£ÞZ":@DÓÿ-t�!JýÓµð+ˆh¾L}áj�ŽBÀyÇáp]GD'Þ=BDŸÑlaŸÀ8Ñ×€vѹƒû‰ˆÎ~ÖOØ[¾q½3à Œ#¢·…ßosµyEQ6=MD«‰èz�¶Åêš„~B¶ŸoaO™.ÔÓR–Ñ OÒ"rÑ ·ëssr&“R.L.ˆ š ä„M»-ÅäZ8ö¶¼(Ã;"}%,Ì A8Bˆh¿ Å2´Û‘UbãÀ¸=I¸#ûÄmw,¾Ê{�N'¢F"ÚMDØà{Q$H%×� °Î°WÁ’‹JWáñwžD’úà $¯ÑV¡¾já@|¡°Wy#"ô ăÉ�¸ÖÑ•^ꉘï½üm£J•X"*!¢-z%"˜¡@:·Ñ{ê �7„…-56µÇí &´Ba¢f ï`�}KD›ˆh£pry…ˆ¦Qaã NS�ÑkDt· �¸›æ°ÐQ/Nb˜ h.ø¿Ø?Ô3Bh‚Rç�µDôð HSÜŒÏt�¤~:Ò]8Ý�æ¸UDt£€…§i'¼„ß… ‚3ÇEÒï¸�é!qßGD™.�ê˜ð»çˆ¨Yxæb†ÏÑE®SZ�«­ß\‚2×uÒ\! H0ÌCˆ!@_ø÷tinØ^$¢«\ö¹êÊկυ6pZD2˜1®%"ô?óÈ…“+N•8]rѾÊ;d–�Ä07bId{Æf—vs™íq­%Èׂ¼ÑÉ.€@æ°&=‰è"Â>ÑR9…ˆ°Î—¸öœ»„µí�ˆp�Nt«äTAÆð#o&‘ˆDÍÊ[ûƒ…ý¬µý«5¹Äžˆº Ï· rY%È2¬1ØËDû�ýb'Mua»k?î" Q0-êˆå*§Fô‘°áCµÆná â�¬wm¶o¹lµ7ï�w‘Ì›® ó|8œ0l® š6Ù]„“*¨Ö8ý `qãÔÔW8�xÞáÔ�…Žz@VÐÌnêÃÉè¿DtHX˜Ø¤±!ƒÆ´0AÞˆ�^*œB@ñD„ºÜ‰È, 4'˜*¡1BxÎý»—ˆºÙAA`.NTøÌ ÿÈB³Hí‰&ˆ"Ä€üQp¾XŒ01€”°˜±xwÅ�µ8G8¥¢ Œs»:ÆÑ‰ˆ*Á<*hÁ0Eâ4ÉEø"ï8ˆbýÀLïí r�°þ€ÖÈûs�iR±æQ mtÖ?–þÑ-D´’ˆî!¢Å~Π¡ý…,¸_ˆu`?kmÿjM.ÅßCK\#Nq¨Gý8äëG„}„�*Þ�rð’ë™O…ƒöÉÂÁ²�­âEN"Âà>6` j0 €�ê" NØ8A8ñãôŽSHu¡¸´!ÜKÁˆ�³Þušñ`óÿEØXqŠ%lâï u@¥Ås o&¶–ˆÚÆè7ÆåND8MaÓ†m|�Ðo,ÌÎñàdÁÃIQ20ˆ & œâ@2Bhu8-¢Ü,hx /Øß¯ææ�þ.¼°àÔ“ 2êÄø±˜ÑOô v‘ �a1Cc‚ÙÚžH0°wƒ EÒ–¸ÿÂhr\ôƒ€/òÂBñ¦M`mB.¡ÙÆ D¹,Ö<šV¡h3ÐV¼‘7äݵÑz‚�û’'�ˆ÷SîïÀºçX1°�`<â°Ø^kwD¢å¤µý ϵ&—°X –„ˆä+ äWÔŠpÐ w÷8ˆB«Ä~RÅ +•âEN"Â`°�°ùaR±™ãTBÀéš&³¥ûh¡³cq�@Ä"&ël·…í‹Å�ˆ°àp²B]Ý[�Y ª··‚q`3÷,-6xL, „j¶§iBlP &Hh_P“!`¸KC�@ø< H§B� .zQðü\|8‚xbRÙ ]تÑ6̆ 4o$ Õ_$"h”ÐÅÒG¸ Ís8d€ÄpÃå2}!К¼ƒdD"ÂaîDmZ6LH�‘ˆ µÀ4�?ä2˜ï Ñx#"owD°:À,ˆÃú‡œB¶Z""o3ˆ‹lü°Øx–Öîˆ KІZÛ¿|‘K‘ˆàrAYà"íûݬÞˆhˆpÐáo1€1´(Å‹ÜDä9 L:È`¨kcü·p’‰‹Ìì^°qÃ+¦%·gØx¡¾c󅚉S„û…¦;aÓ„–óƒ@‚ÞÀ‰=0ѹœ@ ž¥%"ïaÐ� úæ9LX J˜ÂPàUÓœh¯yã¾Ê³ÀT�ÆÝŽxŸ�E¼Ð…VáíòÐ\@Ð\DÓ§¸à1vü̽ MØçE"ÂbÇ¢w/PùqîÐÂP.ž¹0žòŽu ÷³0�‰V)Ñ <,�‘ˆp‚<ÀŒÍëÑ*à¯iýÀÞ#Ê\KDä~�DÐfK-_LsâxO´ù"—"á®ç]¡R˜Ü`�À½îŒ4"< ™…õû"H°Wà«h‘‹ˆà@U0Y˜ûÉwPq×nÑ4� —h¸3Áý ÌR0µ�èûÑSjöc‚½ÀŠÅ�ˆ ‘@{‚†EŽS>$ƒMv֑© u¢€ ±™ãŽË“(ñ{oDÇ î…DÇ Ïq`âaz„¦'j08ÙÁÖíZÌ0¡‰B†"êÅɽ0�á�¹ÌepUG-,J,*QÈ`æ€[+4àŒy8!âN 8ƒd!Ø#.0Að 4hj'""˜*p·‡l.¸£Âÿ¹èä]<±ã…;Oѳ-I8Lâ@À]®h/þaŠïjaÞǯx7å‰w¸#‚¼ øbšóeFý!¢í_¾È¥?D ^±GÁ‚�‚}ÖìQ¸ƒïÜ}¯$ÏÈEDè4œÔ±ÙÜy˜¸ Úbâçð~ÃFŠ�ê6~Ž÷Ä ùêÃBÆæ ÃÂÄÆ/OglðW *þ—ÂóØpEÕ'\‚‚¬pšÀf íZ43o.ãîîÛ0ÅÁ|‚ƒ9 ÚÌ‘ø¹ç80áÐ�@‚ظAŒ ‹è$zaŒÀš$ì¼8ýà„vð] lΨýʼn'*hŸ(˜g@@À 'Q�†X`ZC½°/ƒèpÿžèÄq""ÁÃ܂Ō#ìæ P.úBÀWy‡–³0´fœ¼±éA~!ø´j&q@ó$"˜â`žCÁ¿±‘¶DD-¹ooîfAnpÂÁ ŠÔDÔ’û¶»y°µý«5¹ô…ˆ°ßoì…ðt޽è!‹}"Xl A¡àîÎÛ5€¬«YN"‡¤8c3ƒé ‹ öG Þ"Ã.ŒÓ<4lbЄpO‚…��­µˆ°oâÎ*4ˆÃÝ|æIDØ ¡éÀnŠcƒÇ.ÚW6Le¸ÄÃ] š6÷–î²<¿¥�ö Ú¹8©ÞÆÇhrh öZ�Æç�5濇] }À)')Q}†Ðb�AÓ�¦íÄŽç^f uág¸à‹Zæ$ 3 <倓¨îŸˆˆPžÃÉ®¢ý!ૼ˜Œáh„Ãj°Ö¡!�°Åï =‰Ht´A�u ["¢–fmàÐ ‡†€Ã°DÔRûžîà'Ú¿Z“K_ˆ˜#ðaÚ+¬AF8|âp*:’�Œ`ùQ¼ÈIDŠ†ì°†`RÑb±ãÒ“ #À0>#ÀDä3Tü  ™A#ÃÉŸ(´ È0Œ€W˜ˆxa´˜ át�‹NxúÁ¬Ê…`¿`"ò .~˜`F@j˜ˆ¤F”ëcF€ð &"¿àâ‡F€`¤F€‰HjD¹>F€`¿`"ò ®ã{óÝ÷¬Å—güo™ß`%¤ÌÎJŒ·ÃÛÐ2¹GÁE|”*Dû†Çb½á£8üíkñ$D*@pRDäs(!Ì:b9!d )U>£R@p;ºA¶ŠÞšˆò�.bñAÛ`”ÈììÙ�K„¨.ˆî‚èº*z "D>@¸ ÄV£ ÀÕ±îð|ÕÝ"B”�“{Ò®ŽXDªÈÄØÀp›šF@"êÀéL˜ˆ:}Û5"1»£û#æN ˆq… "lää©!á„… bþw�ÑÜóî >Ä\ófšCœ8¤¨@Œ-Ä›Bè „ï#l#Ð+Bõ Ø!ÂáQ„AÆ"Âî zBà(†ûAho™uw²’q=qÕ�‰€?D„¸�øæ áÅ|›?ŠAN€ùÁPÀ„) 7'B�o+!&‚£"²?"Vœ'!œ=ÂÆcQŠ‹ñãÄ`ªˆ^Œô X 8!ö¢Z#+„ýEŒ<įó Äuƒ9Q½ebóI¼l¸:F `ð‡ˆÄ48Äဇ࿌€«k…ÈûÞˆ¨µÌÎb¶W݃<"î"žÈ~Œ˜v8|‚xð{ «8(#¾$,5ˆN‚¬8ìb?Á!T î0@ËÙ=N)H… ©ÿŽ ¬bÊL>4¡¶‚}Šù?ÜMsžD„ö�ûCÌ‚9ERdcÅ‚Š!Š5"î"P!´+ÌNc¤Š” È5„ÄsH逻)äAšd¶õ–KεÃu3�€€?D$†9{AžÁ±qhƒuÄ“ˆ|ÉìŒÐVÞŠ€ÎÐnÄ´+ÈiË Èn¹pPŵ,/8lbßÁa².jElš „U%aDÓˆ‹õ)!B54¤™@þlâJÒA ÷�gÔkq¸ˆFŒˆÙèú bÑ  ŸH«àî|�(æHÿ€ÛÈIMЉHÂÅÃU©�¶} ÀÌ ùB¤h(žDäKfç,Ál�…ò‹häHâ‡t*Èó…´è+HLHø‡üJHއÂD¤š%ç_G݉vaL46{hGý³ '‰Î ¢c´¨ÒÞîˆ|Õˆ ’#IÌiÈùãY`nƒÙýB*d´‰ÅŠ“HDx'­k… M˜ 8b‚A&"ÿÖ?­ Ä»]ŒÆ=;3þëÌoÐ|`þö–ŠÅÛݰ¿™�¡ A!Ç8â¾{ƒHDè î¦�îÿÆsLDÚX�…;Á‡tHZÇ1M±;aÓào\8B[‚mWL ÜÁ ›0ЧiNÌ™ânšÃ½îŽ@<0ÓÁNŒ\!PáE�A]0@•G¶UlÍ(0ë!‰X³�ëI$"÷LŒ�Z#ð@4È* gÈ LñHòˆÄpb†×¶Qk™�‘ŒS4£ã¾bþ.Üå‚}ò Ù…£L†µPÜ_‹D„;aÜ ëªèåŽD„K@˜çà0-§w"ÂÄÃÜB@FC8àÒ§,,Fq‘y’Ì4ÁZÏ.âX$8.À 'æ’Ç%)¼c�$—™X˜ÐÌ@$ #¨èxÞ!¢—„áHÏÛQ©‚‡™[ýíÃ5D„TäÙ~¼ˆ´ÆÈb‰l’\”E€‰HY¼¹5 7ur±�ÒtÇ»Òn¯!¢ˆèUWNùׄí? #•okÅHDŽÖjå÷؈‘vû6…‰Hо·sèÇ_¿Ý5þ"zCŠÊ¸¿`"ò .~XÈMDÐrr‰h¾˜È)¿Ê•Sþ^"ZNDLj¨Â•§ý"WÎ÷e‚†´DØ(ÍÂs‰h})�P”�×=È¥EÝ$¼&­ ¢ÅD4RÐò‰èˆð.ê ˆ°Í!¢®D„vN&"ÔX"ÚIDw9æñÎ×DôœÇ‚x’ˆ®pi{aD´–ˆž'"éL"BNújWÛÐîÂ]Ë®<ö….Èqa2¾S¨ëm!g=Hã�$¢·ˆ(ZÀD‰{ÃCìÎõ»hmÆdú?ÌÕŸ§„‡�õýDô-5Ñ$"–� Ú*ðÂøc[¨+¥ ýÓƒù3F&"Ðâgu�€ÜDô=KD0=¹—Za³ƒFô>íþî+h(0»}FDøÿÙüìªQ‹±éü‡ºA O16ÔíDtp™îúQ¥‹”v»6Û¹§Ô{·›F„z°AcS,´³Ú¥Íõˆo£«®‡\¦ÄßÜ‚í&üu�Ñ>Le%D4ÕÕ÷r"zO !< rúÕE˜' �/ÑOô!ˆfJÔ±RÀ ¢7<<‰h†@^ S´‹:¯ˆã¡ïÐLwÑx×ø‹L@¸¨?OÀ}@¿@Zžu�ÐüíŸ.É�A2ù?ªä&¢M¦þ�"ŠNúžDô½k† 'vô¯I¸? '¢"ÂÔ=Bý‡]„ÖSØì{?Ã}´)w3”'asE?@ œ7mm¿PGœ«Ѐ ÙˆÚLán Vƒ ™ýOxš4� ~òAÁóÐÄ Í�ÀF ýEÛxþV—6†qˆ¥%<¼Ñ]}9Uøˆc!?("úyH I‘ˆ Õ¡ÀÝ}Ùx« Úš¿ýÓ‡$ù>J&"ß±â'u‚€ÜDÓÌ=ØŒÅr½ë:}÷ÈÁÁ¤…S¹{]æÒ\Ê<ˆ?ƒ6ƒ‚ 1ˆG$"ôao+D¢A€ viK³6ÝŒZœ.°‰ÿAD�=^€™ õãYÔ ó$îh@2{Ìq w"ò†‡7"roD„±@ÛL4«É‚Æv� �pAìç Zæ böVž÷·:%Ÿ‡ÉDä3Tü ^�›ˆ �à”sˆ›2œÞLFÐR<‰hž`‚Öp�°iã$î+áÎf3x’ÁÏ0hEîÑ%®ßMtÔ Î "Aƒ€ ë,"‚^¸ƒ©4¤ ?Ç�`ƒf/>üüá„rrßÔqçÍ*T0ýÕ»ÌbxçuAk�æA˜É<ñð•ˆ0F`Z'@2Ð΀ ˆwh�\¦EÜÿ`Ìâ’7"½ž¿ýÓ‹,ù:N&"_‘âçtƒ€ÜD ¡±à›·Ý寽@øƒßy#"¸ƒxpÉóÕáTï�qm¼�ºNïprÀ=.çqÒ \ÉAPpn@;žÑÍ‚³L~6ÁYw>îe¡ ÕÁƒïã® ZHæD´ ï4ŒÁ}SGŸŽ( ÑY lh’·Î Þðð•ˆ.LoV�|` ¼Pp _êÒÊÎÈýÙ€Tq/&jq¢vU%˜,ýéŸn„ÉÇ�2ù?¦” ¢Ž@üp�(îoàÜo2.Œ@G#ÀDÔÑ3ÀíZ%"hÐPà m—ñ\�@@€‰(f�ûPh•ˆ dî #à†/FÀ&"^Œ€²0)‹7·¦˜ˆT0IÜEM!ÀD¤©éäÁH�‘(rŒ€ï0ùŽ?©˜ˆt2Ñ<Ì€A€‰(`¦‚;(0ÊLp?ô‚‘^fšÇé3LD>CÅ2’ ÀD$ Œ\‰–`"ÒÒlòXÔ€‘f‰û¨(LDŠÂÍ�1ÄDÄ‹€ð@€‰ˆ—# ,LDÊâÍ­©&"LwQS0ij:y0R ÀD$Š\#à;LD¾cÅOê&"�L43``" ˜©àŽ LD�2ܽ ÀD¤—™æqúŒ‘ÏPñƒŒ€$0I#W¢%˜ˆ´4›<5 ÀD¤†Yâ>*Š‘¢pscŒGÄk€ðD€‰ˆ×# ,¬)‹7·¦˜ˆT0IÜEÙ¸�Ø5&¢@œ@‡È4/@_è�žž~ksss‹ÅÒÝjµÆ‘Áh4Ú"##Ë"##¯©©ù¬¦¦æ#"Ê÷µR>ÇD¤ÃIÐ!÷6'or]ê´:»;ë�ÇešŒd3†Ê aƽN›s�£Âñ�Ü2ÍD +$Pºe2™nNHHxÆd2¥\ýõ4tèÐè³Î:‹ÒÒÒÈl6“Õj¥Ã‡Ó�?þHŸ~úiågŸ}‘œœ¼5//ïI"ú!PÆ@ý`"  ÉÐcWL¦Ûœ!Ωd¤”°!¡æ�‹‚#‚N2“)ÙDd"r68É~ÌNͿۨáëÆŠ†o#� Æmö"û¹dš‰H�+Ñ·1Ÿœžž¾2**ªëŒ3FŽéÓ[MMM4oÞ<ëóÏ?oHJJZ•››;Ö§õó‘~æ:ÐFz²©“i…!œºEß•:(ħþ9›�T÷N}míR‹Ù˜h\m?j¿Ý§ýxˆ‰È°ôòh||üõ‹eÅ´iÓŸzꩨ¶Œ»ªªŠî¼óβíÛ·—^NDGÛR�ßa"Òà¤ü�L4Â`4|uW¸-r|dx[úë¨uRÕ´šÒ¦=MåŽr‡¤2ÍDÔ–Ñð;)))c+++—|òÉ'Á—_޵־2mÚ´Š… 6UTT\LD‡ÛW›&Þf"ÒÄ4ªg¦4Ó�Ž2Ç«ñÿŽ ¹$¸Ý¯}ÕR]÷¾µÞQã”L¦™ˆÚ=-šª ¯ÑhܺeËã€$ØsÏ=gY¸paQqqñÉDÇ¿£Ñsa"Òóì+?ö¾d¤­‰KâŒÁ絟„Äî×.©«©ûÐZâ(wH"ÓLDÊ/Œ@mÑ����?oÞ¼ä1cƘ¥îä-·ÜR²sçÎo:tƒÔu«¬>&"•M˜Š»k0Æób&F&„]*õ8*Ÿ¨.mÚۼ͞g¿®½u3µA�¼Ÿžž¾ðüóÏ¿aõêÕIr N ]ºt©---AD[ähC%u2©d¢ÔÞMSgÓ«Á=ƒnˆ›“ ÇXàÄP|yY­£ÒÑn™f"’c†ÔWg’Á`(ÎÍÍ5dffÊÖû%K–Øž}öÙ_ Γ­‘À¯˜‰(ðçH =L"wú"Ñ`JÅ7ªòëGÖúš%u¿9J½ÛÓQ{ÐÓÈ»©©©Ï 8ð¾•+WÆÉ=¤ÄÄDKyyy?"úYî¶´~&¢�-uËkœraðýq3åцܱ*º´Ôâ¨r´K¦™ˆ´´úÚ8–¤¤¤ƒï¿ÿ~Ö AƒÚXƒï¯Ýÿý•kÖ¬YVXX8Ñ÷·4õ$‘¦¦30cŒ3þ73¦GÈÒ9(´4ÒšYµÕÖ­ Ë…Ž‡ÚŠQ[‘ÓÎ{I¡¡¡yõõõ¾}ÝÖÎqoÞ¼™n½õÖ½%%%g´³*µ¾ÎD¤Ö™SO¿“ !†¼ÔíÉŠÈtãŽ&ª|²ú7G…ãô¶BÄDÔVä´óÞà^½z}¸k×®x%†T[[K Í ŒNŠ IDATÍÍÍòÕ”�ÿm0ù�¿áƒƒzš?Lz/A™vÖ9©p`I3Ù¨Í2ÍDäßkñéq7ÞxãK|ðA´Rƒ‹ŽŽ®¯­­íFDÅJµ@í0Ðdh´+ãÂ.�73&R©ñö)©wZ�m–i&"¥f*pÛyð®»îzañâÅJu1%%¥¶¸¸ø"ÊQªÍj‡‰(€&C£]y0üưY±ODKþíPKx]VZë(w´Y¦™ˆ4ºýÖ½wÞyçÌ¥K—¶)¦œíüùhRR’¥¬¬ìL�†üa"jË¢áwüAàÞð‘a/ÆN‹nSL9Ÿ-TjqT:Ú,ÓLDmA][ïÜxÅW,^·n�ì®Û"lÁÁÁ¸#‚ýÚ¢-(} ‘O0ñCí@àÆ�>ÁK^‰C~!EJáùÅÍNµY¦™ˆ™¦€n¤WFFÆ×GމU¢—999tÎ9çTÔÖÖÊòµ·chgLDí�_o�^¦Ó7�Ö%*BD¶|;•Þ\^á¬s¶Y¦™ˆZ�Sí?Ü�——’œœ,û`ßzë-š:uêÆcÇŽ •½±Àl€‰(0çES½2:}•bŒ7Ê>.ë§õT»°n“½Ä>¤­�1µ9 ½—‘‘±é‰'žx÷ÝwË DÀkРA¥ÿýï§444¼©!ý ‘?hñ³mBÀÔÉ´1òÎð~7†Ëþ-Qù]eÍûíO9ªKÚÔÙãùɹ0DWŸvÚioïÝ»WÖï`–;õÔS›š››a2hÐ)ðLD:�x…‡}µ¹›ùíä5ò~KtÜ,7²¼Éis¶K¦™ˆ^�Ú\rròóçÏïvÓM7ɦ�=ºlÇŽçääü3PqP _LD €ÌMŒc‹Ê *Ÿ÷ñT»›×Ø íw·s&¢ö §­w‡§¤¤¬ùDÒœD%%%tæ™gÖØíöûÊËËßÕùD0é|(9|SgÓAYæ�ñ/ÇJê‰ä¨pPÉ å5†`ÃCö"ûÛíQ{Tßû8½Ø„n‹ó�¿�ÿ;%%eݵ×^›¶xñâ6»bºCRSSC}úô)¯¯¯_™““ó úà’¼ÇLD’Cªû O(ÓÆãWaƒB;Ç<%É·‚ˆ-WzGEÕÓ [�ía)Ðg"’EuÕq€ˆ2ˆ¨Yè66F±À&÷n—.]z_tÑEi«V­j—f´gÏ1bD…Á`X“““3A]0ÉÖ[&"Ù ÕmÅ­Ê´1ÙØ;ä¬àÔ¸cÚ¥5´QÅĪ 2ÑZûûx©g"’ IõÔƒô ïQyÞb“ ¿ÏéÚµë"¸hÑ¢¸aÆù=ºÙ³g×=ùä“a]ºtÉ>räÈ ~W Ý˜ˆ´;·52ŸdÚÔÅ´–œ4 vJTlH_ÿ½º-Ëëj^¶ŒO:J³¤,‘”hª«®¯ˆh€ÕÑ�IIçÎ�隷¯á”SN1Ož<9éºë®;áq´|ùòº—_~Ùf0öçååÁ;n·º`‘½·LD²C¬ÛZ•iS´év'9f›º™ÍQ·…'†^vb�:ÜY¿¨o¬{×ZOÃ~{±ý.9dš‰HköJ"šLD°ã$DDMDôÝç Ž˜˜˜ ááá÷–——Ÿ~ÞyçYÎ=÷ÜàÌÌÌx×Y,ç�êvîÜÙœ““™’’²)//ïEÉ}­?h}1‘O0ñC~ à·LS�3ÆrV;O3÷4ןn7¥˜Bá]ç°:É~ØVÓ´·ÙnË·GšLíÅö9rÊ4‘³­òGa_%Ñ\—iî"² ÑÏDt®ãûÆÄÄœe0ÒŒFc¨Á`¨+//ßOD{ˆè;êÐû#LDz_Ò�_2™6šétŠ2v%“ÍQMM”ëh&ì ŠÈ4‘t‹"Pkº\  N-wë¨Ýà,"Â…'ù`"’c­· 9™f"Òî’EPÑI¸êÈ›¯ÿQ"šADmŽ¥]ød‘lÐj¾bÍÊ4‘öÖîe‚m˜àô\4Pg–‰(Pg&pû¥y™f" ÜÅçoÏ „¼ñ  ¥þVÀÏ+‚‘"0k¢ÝÈ4‘ú×륂 î$�€^Wÿ�4=&"MO¯$ƒÓ�L3I²n:¤|/¸Sˆh½Ö!½àFýE€‰È_Äôó¼neš‰H}‹¼Ÿ@@§ Ðbõ A×=f"Òõô{¼îeš‰H=BÑW ¸Zãh‘zºÎ=uC€‰ˆ—ƒˆË´€Qà Å%�#ÐÂÀï2÷ð0ñò`™öXLD�+ Nç ´ p»Ê=ó&"?ÀÒØ£,Ó-L(Qà­ô  è"�€^¼.r�Ú�Q;ÀSé«,Ó­LQà¬lh>ð‚ë#ÐK�Ó50If€WÅ2íã1ù"T§ BŸ­Ð-±œo5´üToÁ×M8!À›‹v`" Œ¹e™Œy8Þ &¢–'còñX­Ö>ÕÕÕ©qqqõÁÁÁö¦¦&ceeexLLLaHHȶ¢¢"]׆9E´kh@øx ärÏ–Ú†*ù ÀDÔq“4,%%eLccc?A¦­ÁÁÁަ¦&Seeed:<<üû‚‚Äed™Vpž˜ˆ<ÀNMM}¸±±ññÔÔÔàÛn»-ôŠ+®ïÕ«×ߦä矦 64-[¶¬¶°°°9::zΑ#G@&­x¿!é�|ðŽ£µ—ø÷šA€‰Há©ÌÌÌœ\SSóHjjjÐØ±c£†Ü’LõÕWÖwß}·¡°°°)$$dVaa¡/&r–évÎ)ÑÿðÌÔÔÔ÷ÒÓÓSfΜ™pé¥PT|+_ý5=þøãeyyyEEEE· ¹y<_>[Ѐ®p# ›o-ðSB€‰H¹É<3%%e%dzÖ¬Y‰þÊô”)SÊ!Ó………·°LË;iLD®Ô¤]ºt¹µ¨¨hÙÌ™3­“'OŽn+äsçέ›2eJHttômõœ)Ðp·; dDå¢O˜ˆ˜÷øøø›jjjÞ�9sfãäÉ“#ÚÚäܹsk¦L™ž’’26??%Ët[‘<ñ{º'¢°°°Ç;Ÿ}öYð�!°–µ¯lܸ‘®¾úꦨ¨¨qeeeß~­›ÔؾÚùm ÀD$ó$&&&ÞZ[[û–Ô2m4o¯¯¯‡EƒeZâ9Ô;õ6 ;7nÜh=¿¤¤é¸0"LD2®ÈôôéÓ;ßsÏ=¡R7³xñbÛÓO?}¤¤¤¤‡Ôuë½>ÝQffæsYYYÿܼys²\‹`ðàÁ¥‡~ãСCOÊÕ׫:˜ˆdš²=z¼�‘‘ñ�Í›7'ÉÔ <¸$''gÉ‘#G²åjC�õꕈŒáááÕß}÷]ä9çÀóRž²k×.êÛ·¯ÅjµÆ°‹¶<«°V&"y&�eZ\©U—D”˜˜x×é§Ÿ>ã›o¾I”å”þðÃOX­VNÝ-7Øê¨Ÿ‰H†y ß»wïmݺU6mHìöÀ�ËöîÝ;µ¬¬Œ“QJ4—º$¢´´´m³gÏî;zôh‰`l¹š+VУ�>ú]aa!’_qa˜ˆdX©©©Û^|ñEÅdú±ÇûîØ±c,ÓÍ¥.‰($$¤>///4)IöÕ––â;¥†¦¦¦0‰æŒ«Q7LD2Ì_ppp}~~¾b2�žžÞÐØØÈ2-Ñ\ꑈ²’’’v•””DI„a«Õ$''[JKK'(§Õ‡ù­#ÀD$ý C¦.))‰”¾jï5&''×–––â‚™eZÐõHDýÏ>ûì�þùçx ðó©ŠsÎ9§òçŸADßúô?¤e˜ˆ¤ŸÝþ½zõZ»k×®8é«ö^c¯^½*vïÞ=’eZÄõHDÃúöí»bÛ¶mŠ-ÚsÏ=ײk×.�ÐÓDôƒ4Sǵ¨&"é'nXÿþýßÛºu+¼S)ýúõ«üî»ïpÉÜ–(ÝŠôQM�葈_pÁ«vìØ¡$ÕìÚµk5 $¢\"‚�·JMë…ûÚ~˜ˆÚ�¡g �éÕ;vìPŒˆ.¼ðÂÊ�;wÞ@D›¥ŽþjÔ#�‘žžþÝÑ£G[´Õyyy}‰èW"º‘ˆÆÑ©!�”òõ·ôt;b&"é§¾£eZúé¬F=Q°Á`€›Ál–<²Ïß–�Íf£àà`Ä�CÈ÷¨Û¸è!ÝID ¤´EgëO�Ãe"’~ÖE¦¥™NjÔ#Q§N�~_¾|yÏ¡C‡Ê>Í6l 1cÆü^\\|Z �ÁÓdRBtnhHøÃ¹ŠdŸ�i€‰HØ;uêôÛòåËOUP¦÷êÁEtID©©©3† rß²eËb%Àð„UŒ3¦bݺu ÊÊʦûÐÖ0�� üM��~óá=~D=0É0W‰‰‰Ó‡ öÀòåËe÷†;vlÕÆ�N•a(º¬R—DäÚàÓƒ‚‚•””˜ccå㢪ª*JNN¶577wwLž+ Ñ}E³Ý��>ñã}~4p`"’gn]¦åµFjÕ+QFFÆ×\sÍ� Èæ=÷àƒVúé§�9ïš¶–q)%„M©¢­•ñ{Ž‘LS�™™¹ 2=þ|Ù‘xà�JÈôÑ£Go’iº¬V·DDD©ÁÁÁ¹[¶l éÓ§�ä“ÿý÷ßÓ Aƒ›ššºQ¡ ÀëZÒ·{$hK\Ô…‘|ó¥6™– •Õ¬g"¢Î�;ßc4_ؽ{wl\œtŠQee%�uÖYUV«õ±ŠŠŠ×%^ÈŸB˜ûàØð®Ämpuò!ÀD$¶?!<<|ö/¿ü"¹LŸ}öÙU‡ãÉ‚‚‚We‚.«Ö5aÆ;wîü~ppðå»víŠ�‰i¿F_]]M («¯¯ÿøÀ�ÿ”yU]/ÒYnZÒ™ÛäêÛ‡Qûðkõí“O>yIXXØÈ­[·&J%Óýû÷/­««[“““sw«àüF@ïD„‰¾�‰‰qÄÅÅ�òÑGÅ�wÞy~ƒ(¾ðã�?Òõ×__i0VåææÞÕæŠüD$jIŸ ¤´Éÿjø `"Ränݺ½æt:o�J¦M&Óꜜœ t]—Mè�ˆf§Üõç�ôôôɳŸ|òIËsÏ=íïjxê©§*gΜÓ­[·'rrrfûû¾DÏ#,½HH7- ß'q ˜ˆš‡¬¬¬Çrssÿ5eÊ”êçŸÞoÛ{vvvÍ /¼Ù¹sçÇòòòæ*Ôm]6£g"zŽˆ þ\é6ó'¥§§/¬­­½ä®»î¢Ñ£GGœyæ™-.Œ={öÐ;ï¼SóÊ+¯„˜ÍæüÚÚZ|ôG€¬$|­ RBŸÄ�dbˆKÇ"ÀD¤,þ'edd,ª©©¹x„ öÛo¿=º5™^±bEÝüùóÍf³9¯¶¶ûC È´²È)Øš^‰h¬+ÜΓDw¹2/xŸ�žžþpMMÍp“ÉÞ³gφîÝ»GFFUWW7=zÔþûï¿Ûíöú¸¸¸u‡þÔuݧ„t"ªSpþ|i ^{¢–ô£ð¡ì_^”ð˜@�õaaa݃ƒƒ¡q6UWW#ì>"ÚÞÂtèPÓ¾}ûBív»5::ú‹¼¼¼ÏX¦;Á¿¶ú§LGGGŸd0"š››ëm6[ASSÓ^eZ�D7èo„�Ñ÷gläÏ“JD0}Õ îØˆx€�T,o¸Bõ%¢ga•´Ð¸~ƒ”0QKòFÄR á²ôôôÇŽ;viÏž=kz÷îmìÙ³glDD566:�9býá‡~úé§èÄÄÄßëêê^©®®–ÚËPª±HU‘TH¶½-ÉtÛQhÛ›—edd<^PP0ð”SN©¹à‚ Ì=zô�ŽŽ6766Rnnní®]»šüñǨ„„„ßìvûâ’’’Å­5¥7"Âü½+ŽBsH�†q§p²‡VTÓðüû‹Ý´$>’ýO+}2î�|)祥¥- êñÈ#�DßrË-Æ„|�ÛrY½z5Í›7¯|ß¾}M‹eRSSÓû¾4¤Âg˜ˆÔ3ij’i¹Q=¯sçί™Íæ¬I“&…�=:ØG™.Û·o_³Óé|¬²²²ÅÏLôFD‰h›ŒZËkDT$$À“{aHQ¢[(¡bAKZæ¥b˜Õ¾""DˆÀß-–®]»N/((xjÖ¬YÍ'N„éWùòË/éÞ{ï­4›Íßæää «­Ö ‘ºfTm2-9º'�tÒ³‡~bæÌ™õ“&MŠò·Q¦M&ÓÖC‡!«íߊžˆê!6FÜÉUN&¢]DÔ…ˆ*åjD¦z±@`¶ƒ‡¨%ÚB@¾"jvÑED´Ç[²²²–]õñÇÇ÷ìÙ³]ݼîºëJ·oßžwìØ1�`C»* ¬—™ˆk>Zë�šeºµ±µúûîÝ»¿tõÚµkÚ+Ó7ÜpCÙÿûß¼‚‚‚K Žˆˆùý÷ß'J%ÓãÇ�/ݸqãQO™Ö�"¢…‚s‚xÂoÓÄøøR–Ë„¯Ü•úøN >ìv�d"¢Ó‰(HÈ™´“ˆú‹�îÔ©Óx³ÙÑ,("Ó%%%ˆ`~üÎYËD„̧ð�C€ÂVÝ%–�L":(hEp^Psù�ˆ.'"ÏhV—‰î³ôôtËàÁƒG¼õÖ['v‹kï½÷Mš4iQQQû.žÚÑ _e"’L«Ò’LŸ¶®]»¾9hРK—.õ;…¯óñÞ{ï9~øá%%%ÇeZËD„�6s\š î‡:¢¼$\îwTûRŒwC„»!˜åP@@Јð÷&“é†C‡™222¤h¯Å:N9唊À<·Nֆ䯜‰H~ŒåjA 2Ý6Q&“©Ri™Ö*!Ö²œâ~¨£ <çð�+îŠ :ªílkpJ¨þÆÇ¼–ÈÈÈ{úõë7ãË/¿”==ó‚ šgÍšµ©  À=$S;‡×!¯3uì’4ª™>!&“iÂСC_øòË/ñi‡¬eáÂ…ÎY³f­ÏË˦E"BÔë{çœÜ;²Ìq}³„A'ud'äj»K—.ßΜ9³ßèÑÞ9ÊÕP�=¬ ²5¢LÅLDÊà,W+š–é´´´­³gÏLk�ˆ.#¢Oˆ~ê»åZ‰~Ô‹HùD„�"ÐŽ4U"""ªÿý÷èôt(}ò—ôôôšüü|hijÞÊD$ÿR‘³–i ÑíÒ¥KuAAA_-6{8'<@D«%νUÍ"¢P—ië¡öV`ïÇ…††Ö×׋žt²woðàÁ•[¶lÁG·ËÞ˜| 0ɇ­R5³LK„ôàÁƒ+¶lÙò-B÷ )\Gåjij�ÚZÑ)AR%šÊ«æ¤””” ýùÑÖßqÇõË–-¡«90*Q[@à¼Ç2-Ñ\Œ;¶nùòåµBDo Z*™ÕŸ©xAp¾ßŸ—üÙž]ºtÙ‘——çwÁ¶Žk„ o¼ñîÛà’¯ÖÂD¤Ö™ûk¿Y¦%˜ÇñãÇ×½ùæ›�j�ˆ²cÜjÁ76yD„”Þø¾H ¥sllìþÊÊJÅœFŽY½víZ�y‹Q|U,‘ &ɇ.jR¦ãââöWTT(&Ó#FŒ¨üä“OT;Ýê ;ó¼à!ẇÅÓ‘� #l’+:÷ÝÙ )Û6�6‹Åb’*Uk};묳ªöìÙƒ˜�ß¶ölÿž‰(€'ÇÏ®±Lû ˜çãgžyf寿þ:BÍDt¡àœp©�Ú¡��Èþ:"XC+:_ÈJ*{ƒr7�œœ|àÃ?YTVVÖU±ÉÛ‘¼øvTíš’éÌÌÌÕ}ûöíÿî»ïJütéÒ¥ö)S¦ä»Ë´ZˆèTÁ9‰Øp?¤ö‚ì§ÐŠ�çg—ÚCDæäääý÷ß\vv¶d9L6mÚDC‡u:�΋‰h‡pbÓœF&ÑË04)Ó<ð@âÔ©S%»nI¦Õ@D˜`xȽCD¸ÒJyLøÀU+)°»ÇÆÆþgÒ¤IÙÙÙHJØ®òùçŸÓ¨Q£lQQQ·UTT C¬V kDZ™É¿�C“2ýÐC…NŸ>=¦½Ó&Ê´Á`¸¹©©é/ñ@Õ@DïQ±ƒ†ârZÑÕH0×ÞI�÷3SRRÖ_tÑEqo¿ývrLLÛÖîÓO?]={öì`£Ñx“ÕjEü@-&"-Íæ_Ç¢I™NMMÝpñÅǽùæ›Im•éìììÊ9sæ„FGG�.))ù[Ðâ@'"DM8ÛµQã~H‹e2õ&"µzz�“¬¬¬åÅÅÅ×O�:Õ9qâÄðà`(µ­—U«VÑÔ©S+¬Vëþüü|hЇZKuO0©nÊüê°&eºk×®o—••Ý8mÚ4ãC=â�LgggWÔÕÕÈÏχ£™W™d"‚{3Òlã›› ¿–‚ºÆwE×kèDDÿüÌÌÌ™EEE}‡ V3räÈÄóÎ;�ºvíJÔÔÔt<ÙÝ/¿üBëׯ¯^½zµÁh4Øl¶eee+Õ5…~õ–‰È/¸Tù°fe:##ã_ÅÅÅý†n¹öÚkã[’éuëÖU~üñÇf£Ñ˜_]]=½¾¾þÃÍd bÆlÜ´ÿ§Ê¥è{§á¾²½Á÷WTõd—èèèë"""†744œn±Xm6[�Ñht„‡‡WEDDä455m¨¨¨X£Ç�Ö&‡‰¨5„Ôÿ{ÍËtPPеIII#¬Vëiuuu‘éððpvþº¸¸äã“3V òÂGDS\.θÒC9,|§ .ÚF€‰HÛó+ŽŽeÚ�yD"Ú 6u¹«=”‹Óp<«,>påÏKü¬*`"Rå´ùÝi–i? 4"ZâJëDDãüƒVÍÆ­æZ™ 9ÇÁD$'º�U7Ë´�óHDô8 '¢þ>ö]k�Ý+|àŠ|;\´‹‘vçÖsd,Ó>Îu ¼Æ^.ía[Õk9@DHwÓ$m"ÀD¤ÍymiT,Ó>Ìw Ñ9Bä|؉û!=�pÐêwSzž[qìLDúZ,Ó>ÌwGbÁSlá~ˆ ÑïDÇ�à¾ÎE{0ioN[Ët+u4­uEØOD¸âòŒ>pÆ€h&"MNë Å2@DT*h>Ï }šKD™Â¦«¿¥yâï!¢Gˆh=£9˜ˆ47¥> ˆeú0)¥!§E¡ë£Í?ˆè4"‚7É?…È VŸ¦Q_!5â­D4T_ÃÖÅh™ˆt1Í$Ët.à‘ÆÑi_ ¢'Â)�‹w~pú’ÒLDššN¿Ã2Ý\JiD³‰Qi‘KÚAD‹ˆèá~ȯ™ÔÑÃHˆ{éhÌz*‘fÙûY¦;˜ˆ~""¸i‹¥™ˆðÌOMÀûýèJçþ }*üXmЯkbäLDš˜Æ6‚eÚ tþhDi®-$%%õ5›Í'Ùíö("²™Íæ2‹Å²«¦¦dòM ÓÒ1»ý®Aø?‚š"ÔŠedIDAT¦<ç¸üÜá;D#G n$ÒûˆˆÆ2XªE �ˆ(Õ%³ÃÂÂÎ�ˆˆèi0bœN§Ín·VVVâðˆôì[U‹t`vœeº�Dt}ZZÚ§÷ëׯnàÀ�ñÝ»w'dê³ÙlT\\Œœ2õ›6mªÏÍÍ íÔ©Óš#GŽ<çºlÇÅ( Þ_H×YGDpNø·`š« ̵P½ÚIDÿ"¢ ®o®†÷F/T¹3þ DtCbbâd‹ÅrÎÀ�ëû÷ïÓ­[7ŠŽŽ>.Ó%%%´gÏž¦M›6YsssÍ&“i¹Åb�Ì"¼?—ö#À2í�á‰4¢>©©©¯ÇÇÇ'?ñÄq£G�ÆýÎ Ë¡C‡hÁ‚‹-ŠÊÌÌ\ùÇÀS¡{î&"„£Â»­Õÿ§K„û4ÌÏ`¿H~Hu:•ˆpçÆE�t$õILL\Ô¹sçŒÇ<ö–[ZO |ðàAzã�7ìsçÎušL¦—ñYÿ`™>f^‰¨[·nÏ>:þ|Ä |ËóìÖHii)Ý{ï½¥[·n­+--ADÈ1ô…ÿs§Û7@Ö× ÷hpî!¢PáÿÙD4K·È¨àED“CCC_X¸pað�w"ù±¥¨¨ˆ&NœhY¿~}QeeåH×÷¿úWƒîŸf™ö‡ˆzôèñ¦ÉdºæóÏ?OèÑ£G»VÏ‚ ê}ôQjll¼Üu²ßÖ®Êô÷òt!âH,6—×á4ÁT§?D´1bʼn(,,l^÷îÝÇ­]»6¶½2½hÑ"šû¥êV‰,�h¿Ò�p�ïڵ딢¢¢+\nõ�\p�±gÏžañññÁp½=zô¨e÷îÝMÿûßÿ BCC—åååa³hÒ><ª¡RDôø¨Q£žZ½z5¾÷“¥8p€N?ýt›ÍfKq¥.)—¥íWz\¦M©¦ÇŽ+�IƦàÓƒœæ,sŒ1Ò`tÚ‰ì%ö†æß›ëš³…B ÇÈHKå�ÖŒL'¢èèèòÍ›7Ç÷îÝ[Öi3fLå×_½4??ÿQYÒfå]»v}½¦¦æ’ûï¿ßpç�wFdf"xyËeãÆ�ôòË/—}ýõסñññ3òóóÙÛ®ã׆"DYþÍ7ßÄŸwÞy²ŽxܸqÖ·ß~ß[ú�t†)Å´ÄYïì~K˜9âš°PS*‚Í´\·7QÝ{uå�;›C á†gŽ9þ7xo€ˆ†�qÆïìÙ³'Aîîmß¾�†~¬¢¢¢³Ümi©þÌÌÌñ……… |ðÁº_|öe¿ÊÎ�;éž{î)-++;xôèQ åÓ«_Jú°Dte¯^½VìÚµ+VÒž{©ìûï¿§«®ºêhUUÕ‰OErwDeõ›Lw8j‹#F‡×G?é÷<5ýÚLÕ/Ô”9+�mEvØ^U-Ó†N�:½qß}÷Ý–���oUd/III–²²2¨^ìmãÚÓêêêýè£�"„ßö2qâĪwÞy§®¼¼!ƒð�1å��ˆ"##_�:uêÝ�?®L¾É„„„ºŠŠŠ^yÁ·Ådîb~ÆQë˜7'&2¤·ßŸiþ¥‘êÙµõ묎*6ÕÊ´!))é·U«V�:`ö&ù˰aÃÊ¿úê«O0ùTq =zôxÜb±<ñí·ßÆœtÒI’ŒdÆŒU/½ôÈè,"ª�¤R®Äd'¢„„„½kÖ¬9­ÿþþô«ÍÏ^yå•5ëÖ­CLDÄŽärŒ)ÆGÈFS—ÆÇ˜3Nl†óHËҺ˻ÖZG•Cµ2m «ÉÍÍ�êÔ©“¯ãn×sO<ñDÓœ9s^°Ùlˆ*Í¥eú}½sçΠ^½pØ”®@3Z³fÍïG�EØ.Ê" ;………ÕæææF*(Óö™3g>ÍÞs­.¤>3}�ønBPÐ)î1 [}¯Õ 5liÜg/¶÷iõá|À`0.R0�­†’“¤ûøþàÙgŸ]RYY‰—HNN>8cÆŒ´ &àÛ!É˹çž[ZZZ:'??ŸãÖIŽî +”�ˆ”–éyóæQvvöB«Õz¿²Pª«5c‚ñ`ôý‘éá#ÂÚg�kaØ¥·”—9kólIVU�³‚Óé„l(SæÏŸOÓ¦M{½ºº©Â¹xA %%er�=¦lÛ¶M6wú;vÐàÁƒkëêêंï�¸(ƒ€ìD™v8d0ø“å¥íƒÇá2;;{‘Åb¹¯íµhûMc¬ñ¡ ®¦© oÅË&ÓM{š©üŸ•µÎ§êdÚZç:‡'$Èî4w|¥M›6Í6kÖ¬YMMMˆ"ÍÅ ñññ«V­J4HÞä¬Ã‡/Û³gÏKyyyüA¢r+Qv" ©+((PL¦³³³�3fÌ€©�Íí-¬#cŒ1?îŘÎ!çË¢ ýÙjÅýU¥Mûšç:ʪúTÃ�˜˜xð³Ï>˺袋Å‘#GV¬]»ÑÞV¤Aõ520++kÍÁƒ_NÖ²aúí¶Ûþ(--åÐK²"ý—Êe'¢¸¸¸?Ö­[×ã xCþ2jÔ¨Ú�?þf¹åò·¦ÊšÒMk:}š(»L7þ·‰*§Vÿá¨p¨J¦ ©©©+}ôÑ'Nœ(� G+ë¤K—.ÕpÑÛ­Ê%%s§SSS�3æ¶™3gÊöE¼û"##ëëêê°h‘ý•‹üÈND±±±ËŸyæ™Û|Ωò—´´´ÚÂÂB8¾pj/p›:‡ ½=ú�¨pùgƒ¨ð’’zg½SU2 #òu^xáâíÛ·Ëf»Áÿõ×_é’K.©¨­­UƨĬKÜFrròî+VœuÙe—I\³÷êX±uëVd]£HƒÜˆìDDD7ôë×oÉ·ß~ë÷‡’þNÏîÝ»©_¿~¥µµµÉþ¾«—ç�ñÆ_â^ˆ93äByÍr"žeÿ¬¨lú_ó?Ô$Ó "cHHˆeÏž=aR}«ÒÒ{øá‡k]ß7|˜——�¸xA ""¢úÀ�ÑiiiŠàóÐCY–,Y2³¡¡�ï‰Aœ” "ÅdzÒ¤IÍ‹-BæVÛÕÂú1„ª“?MŒ6%)ã™\=§¶¾þ“†Y‹C5wvÇÝj²²²–ôéÓgÔ²eËdÓT*++)55µ©±±ñ "úC™W_+J»ÞÎ�;OóëëëRZªì±DD!!!/Ž;öþ×^{Í=±¢¤€!sZZ‚žžBD‡$­\K•È‘öc')ãÄH–åV²¼^·Èaq¨Æ‹Q„&.444óæÍá—\"Ï7Ž.¡(ÛºuëWG޹]KkLâ± ƒÍáp(´d AQiêÔ©‹-Ë=�…«óŽ€"D„dŠ�é-[¶„_|ñŲÌÅøñãëßÿý7ùû¡ÂkD*‡´Ÿ:)&Óu+­T»¸îuG­C5ŸÈü N—.] �¾ÿþx©?n}ï½÷÷Þ{oyUUUW"²Ê"©4((¨¡¼¼<$*J_¸Ó7¾ôÒK/×ÖÖ*˜L#óÔŽa(EDèâø“O>yîo¿ýc2Ië‹´råJÒ-¬©©éFD�íÀCó¯ÌÔ�òMrˆ!B.ª]l±×½_ÿ’£ÚñˆZÀý 2Ý»wÿ0++ëÒ 6H渰uëV|8i·Ûí¸}ÿF-ÀtT?ãââŽlÙ²%Cê°>-�çÆo¬ZµjìÒŽ³ÎÚU’ˆ(&&fiß¾}¯ÿüóÏ£¥ÂyË–-tÙe—áCxÚüVªzµZ�1Æp4áµøt©Ãú´„WŔꚆõ “Ô$Ó£è®]»®ïÖ­[¯uëÖ%‡„´/ ÷gŸ}F×_}sllì?JJJø$­sçΟggg»ë®»¹ÙìÖ­[ÕáLJ Ù}è!?ÒN%"ô5!!aíùçŸ?ðã�?ŽqY=ÚÕýO>ù2m·Ùl7ÑGíªL'/›RL_DMˆ¸2|”,Ѻþ†bñð²*û1»ªdÚ«®Ø½{÷wm6Ûð7Þx#vÈ�!mZ.�?þxÕ‚ ‚ ÃÍV«õó6U¢Ï—Æ:tîúõëesa=tè�qÆ–úúzeì€úœOÏQ+NDè@dd䢄„„Ño¼ñFt[? ˜6mšsîܹµV«õ&"úЧÓG‚h\èùÁsâÆù�KÌÇþ|Ì^`§’ëÊ-ÎF§ªdºE£eRRÒ���sû÷ïïxê©§}�¼ðÚk¯5̘1£Ál6ï>|ø0òüSçÏãÛ�Jx$%&Jf!õ ivv¶eÅŠërssoÔ9æJ¿CˆHà-QQQ †üÈ#�Dù"Óv»�–.]JÏ=÷\MCCö²²2\€S0 ´u\¦S¶$‘1N^CGí+–jë ëíEvTSZ»=3%''g766Þ“��|ÕUW™úôéÕ½{wŠ��¥ææf*..¦ß~û�\9†*6nÜ‘��ðSAAÁt"Ú ¬£™™™ÝtÓMCgÍš%Û©�nããã몪ª�´æ§ƒ@ËÝéH"®Ø 'GGGOJJJ 1bDø\™ŽŽŽ&›Íö§LoÚ´©vݺupœù¾¬¬ ©À7iybä›)ÅôaØå¡C£ŽŒ‘­'QÑ€’:G­Su2ݹcÖ7--í‡Ãq¾ÍfËhjjŠ0�öààà “É´Ïjµn®®®† ŽCÅ´¥õ0�û÷ïßoìÑ£GûkóRäI“Ê׬Y³óÈ‘#WÊÒWÚMD‘i—ÑÀÄÄÄv»½«Ýn�„L›Íæ2›Íö«ë�²E0Á±Ôþõ܃ ´?ù“D£9]ZF±k5ó,Uõ›vØ�Ù¯hw•­Á"R¶g:o­K—.ÿÊÈÈÿý÷ß'I ÅæÍ›iøðáõ���ªŠG%5T_ QA ÏfÍiæÙ†$ø¤·¥OѸ³‰*¨ªw6©+Æœ¸˜ˆX&233¿t#àa" ¸)ùK‡‚SSS6lXªdôÓO?ѰaÃj‚‚‚fÀæÏEy˜ˆ”Ç<�Z 6& ½$$-öéèv{Ñ5ÿÞLå÷WÕÃŒsl¶çi þô…‰È´:æÙàÌÌÌÍiii§,[¶,©­�i/^l}à�P×”œœœ¹3nÙS] äXîô½‚M©¦ÍÆ$ã)qÏÅ$™3ÚvgT·ÚÚXý¯Z“1Ñø¨£Øñ’š!e�PÉ쥧§¿�ŸŸ?å‘G±Àõ69Ù·¨û›6mBPÓòÜÜÜŠâââ1D´]%CÖj7™ˆ´:³~ŽËœfže+´=y[DMä¸ð_]»w4QÍ¢Ú2{�£ÂQî«™f"òsñtðãY™™™3�=zÝe—]V1jאָ .¸À”••…P.Ç]o‹ŠŠhïÞ½´iÓ¦šÕ«WÛkjjêÌfóœâââ—;¸ïÜüÿ!ÀDÄ+Á�,SÓ,{�}TÈ!åaCBƒN"S# Dv"{™�l‡ìÔ´£ÑbÝÔØì¬sX(Ìð’£Ð1O+P2©s&ñ-µ�;w¾ÞjµžUWWש©©)Ôh4:ÂÃÃkÃÃÃs�FãwEEEÑ6uQ³½f"ÒìÔ¶k`1d¢¦8ÓHg³ã§•’�ÍÎP2�Ãj¨1„Ž V§£Â±Z‹2ÍDÔ®µÃ/3~#ÀDä7dü‚Ö`"Òú óø &¢@›îO‡#ÀDÔáSÀÐLD:›pnë0µŽ?ÁH‰‘”hr]š@€‰HÓȃPLD*š,îª20)ƒ3·Âˆ0ñZ`<`"â%Á(‹‘²xsk*@€‰H“Ä]ÔLDššNŒ0I�"×ÁøŽ‘ïXñ“:A€‰H'Íà �½¸0Œ€€/F€`�Eàÿ®õO Ý?IEND®B`‚someipy-2.1.2/docs/images/someipy_v2_architecture.d2000066400000000000000000000015101513043235100224550ustar00rootroot00000000000000classes: { daemon: { style: { fill: "#44C7B1" } } app: { style: { fill: "#F2A900" } } } grid-rows: 1 ECU A: { Daemon_A: someipy Daemon App_A_A: someipy App A App_A_B: someipy App B Daemon_A.class: daemon App_A_A.class: app App_A_B.class: app App_A_A <-> Daemon_A: Unix Domain Socket App_A_B <-> Daemon_A: Unix Domain Socket } ECU B: { Daemon_B: someipy Daemon App_B_C: someipy App C App_B_D: someipy App D App_B_E: someipy App E Daemon_B.class: daemon App_B_C.class: app App_B_D.class: app App_B_E.class: app App_B_C <-> Daemon_B: Unix Domain Socket App_B_D <-> Daemon_B: Unix Domain Socket App_B_E <-> Daemon_B: Unix Domain Socket } ECU A.Daemon_A <-> ECU B.Daemon_B: SOME/IP (SD) { style: { stroke: "#FF5733" stroke-width: 3 bold: true } } someipy-2.1.2/docs/images/someipy_v2_architecture.png000066400000000000000000011573721513043235100227570ustar00rootroot00000000000000‰PNG  IHDR ¬VDØ0-eXIfMM*D2&v0.7.0 Ä®ˆsRGB®Îé IDATx^ìÝwü–Óÿðw”¨Œ$ãK2›²BD²2"Ù_Šd|�¬l%”Yöe„¥HfYÙBC’)«”J¿Çõù=ºu×§>ë¾*}ž×?<>÷9ïs®çuîN¯û\eæÏŸ??\ @€ @€ @€ @€ @€R(#°š’¬² @€ @€ @€ @€ @€y« @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€¼S™ IDAT @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ @€ @€ @€ @€«Ö @€ @€ @€ @€ @€@ª«©ò*N€ @€ @€ @€ @€ °j  @€ @€ @€ @€ @€¤* °š*¯â @€ÀŠ(ðÃ�?ÇØ±ãcÜøI1~ü¤˜8é»øá‡Ÿã‡Šä³Ù¿Ï‰?þü3æÌù#æÍ›—w eË–�Ê묕+¯5kÖˆ¦MÅqÇ4�Š+äôçÏŸo¾õ~¼øÒëñÑÇŸçÍsú¯3c�5ÊÇFn›o¾itÀÞqÐûĆ®_â±gΜÏõ{)fÏžÇ{xTªT±Ä5WÖ½û ˆË®¼!æÌþ#šv@t¹öb^+ëÃv_ @€ @`°§õÏC±§õÿߌ›Ã>Ç�ޱßLˆñ¾�)SˆŸžüñgT¨°FTÛd£¨[g»Ø¯é^qèÁMc�5V_W·) @€ PZVKË“vŸ @ ” $¡Ó$�ùîÐ�bä¨11zôؘ6ýלhÔÚ~ëxgÈsyaÖ’^I0¶ÇcÏD·ÛÈÛh.èZe•UâÄZÄ•—·‹ 7¨ZPó|?ÿeÚôØy·Câûï§æ}~ÈÁMã©Çï*V­•½Ó#=zÅYç^‘u›;6¨ƒ^x/ëï­O:*’ÀcA§ª.ZlΜ?b§†Íâ›q3 }«_Ô©½íRï)9•õ?›5È \V¯^-F {-çÉI“'OÍÔòZïØ±AÝœ�“낟|úE4Ú»EVÙV'¶Œ»n¿.ïo�®½5n¸ùŸÓl·Ùz‹øøý�¹ž†z @€ @€�°§õÿ‹ 4íi%'¬6Øõ ˜8ñ»|¿[l¾Y|öñËQ¦L™"Cïùlœvæ%™~û4Þ=ú÷}¤Èut @€ @€@qV‹£¦ 𯸩ë½Ñ±S×ÌÜÏ:³UÜÐù²ev/&|;6lɆó‚ëÄZÄÝwt.ÖærRã©^ÏÇ)m/ÌÔ{ã•^±óNõ–zOù�Ðpxóâñî·çÔâ³ÏGÅn{–UsØGƒ¢æ–5r:NÅŽ<æ´øÒ™ÒÉ©µÃ?}56Üpý¼¿%!áÚõ÷Íz`ÿÇbÏF»¤15  @€ @€�R,`Oëÿ~iÛÓJÞîóp÷§âÑÇŸ‰/G�ÍúÔ®µM¼÷öóÅúVôî3 Z�r~¦oIjk: @€ PªVKõãwó @ t ´ns~ôzf@æ¦oïÖ)Ni}Ì2C8ôðÖñÚïdÆÛ}·�âÅç{ùdÕ…'<þühqTÛôÊ�¨X±BŒ1$*¯³öRïéÑÇûÄg]šÕ暎ÅùíNÍ©Åõ7Ý×\wkVÍñ_¿U×[7§ãäºØç_ŒŠ†�²ƒ¶‰Mb´ðÕdÿcâ½÷?Éüé°C÷�ž�Þ‘ëé¨G€ @€”r{Zÿ¿JëžV²ÿ—œˆúÄ“Ïe¾ % ™ÞxË=qõ5Ý2µvÚ±n ~µw)ÿ–¹} @€–•€Àê²’6 °ÜvÝãÐøbø—™yôíóP4mÒh™Ì«çS}ãÔÓÛgÆJÂ¥Ã>ÿùÏ%îܹ1ä­÷£Fõj±y�M ¬wAûkâÞûËj7 o÷Ø»ñnö-Jƒ=Ÿ‘Õåç)_Äê«—/J™eÞöø“ÎŽ¾ýe=«‘Ÿ¿ëU©œ5—GzôŠ³Î½"ó·UW]5¾übpNžé2¿i @€ @€+¬€=­ÿ4¥yO«Ïs/Ɖ­ÛeÖèöÛm¼ûÏó »x“ðëN ›Å¨/¿Ît9äà¦ñÔãw¶„v @€(‘€Àj‰øt&@€þ-ÿýwTýOݘ3ç�̔ߧÔÚ~ëÔoáÏ?ÿŠíêîß?53Öu�ÚG»sÚ¤>v~4oqJ¼òÚ[Y%AËjÕþ“³ùLš49¶©Ýx±z¿MeÊ”ÉÙ8¹.”¼^mÇ]Šdó~ÁuA»¶Ñ©ã…‹ •¼–­ÆV cöì9™Ï.¹è̸òòþñ ×óS� @€(]ö´þyÞ¥yOëõÁïÄ!Í[g0jnY#†}ôÏ® û­¸óîîqñe�³š·¿àŒèpåy…-¡ @€J$ °Z">�  @€�‹À¸ñ“¢V½&YÓ1쵨^½Zê·ðàÃOƹçwÈŒ³UÍÍãƒwûG¹råR;¿êí¸Œùz\æ£ädÐi? �俹ººÞú@\Ùñ¦¬rÉýNÿ1ûÄÕ\�—«:'ŸzA<Ý»¦\… kÄ—ÃG•u³OW]Ðà”¶ÆS½žÏ´ß`ýõbôˆ!ËíÙæÊA @€ @`ۧõÏs(Í{ZŸ1*6:,ƒ±Ùf›ÄÈÏ^/Ò"}࡞qþE�" A/| }«_Ô©½m‘jiL€ @€�â ¬WN? @à_%ðÒ˃£ÅQm³æ—^q}Ö-üðݰ¨X±Bª·ÕÀ+qÌ ÿËŒ‘œÔùõ—oÇj«-ŸÓUçÍ›kUÉ>1aÏF»ÄÀþ�åÌaä¨1±SÃf‹Õ[¯Jå˜0öýœ�“ëBgœui<úxŸLÙ²eËæy7Ùd£%•œH±MíÆñÝwS2mš¶<ÑãŽ\OO= @€ @  ØÓúÿ‡^Ú÷´¾ÿ~jl¹m£¬=Ɖß,}ŸmÊ”¢Ë�wÅ#=zåù-z­¹fÅxeà“Q»Ö6¥ð›å–  @€X^«ËKÞ¸ @€À2øù—iqbëv1xÈЬ1›6:Ê”)“ê<þÛêÜx¶ïÀÌíÎi×ujŸê˜K+>sæ¬Ø°Zý¬&7Û7ž~âîœÍ) 'ÿ˜²èµñÆÆW#ÞÌÙ8¹,4qâwQ{‡¦‘œˆ»à:á¸#â¾»³CÎù�yõ5ÝâÆ[îÉ|T¾üj1î«¡±öÚkærŠj @€ @€¥LÀžÖ?¼´ïiýðãÏQ£fà H6�2)ÿ7ýúëÌèrã�qß�ÇŸþ•ï·f«š›Gò¨zu·+eß*·K€ @€ÀòX]ÞOÀø @€@jÉIŸ]o½?ú<÷âb›³IPu×]vˆä¤�?þü3æÏ_ò4Ö¬T1öm²GÜØåò"\ûmVT¯Ù0fÏž“)þÎ�¾Ëu#8ù‡ŽM7ß%ëf[¶88º?Ô5'Ïa֬ߣæv�"Ù_ô*Ê«Êr2™"9ëÜ+òN›Xøúè½cÛm¶,°ÊØo&D�šfµ»çÎ.qâ - ì« @€ @`Q{Z‹¯‰Ò¾§µèý'?˜þeêðÅ ^}ýíh{zû˜úÃOKüb%}OnuLì´cÝØ±A�ØbóÍ|  @€ °ÌV—µ� @€�e)0쳑±W“#³NÌ,éøúv�½ïVè2ýžÇ�xv¦}ròÁä Ç*«¬Rè¹n¸èi Iý“þ{dÜ}Gçœ õÀC=£Ýó­µnåubÒ¸r2N.‹|ûí÷±}½&Yk¥i“FÑ·ÏC…¦a£Ãâó/FeÚ7Þ«a¼Ð¯G¡ûkH€ @€Hìiå¿JûžÖ´é¿Æ&ÕwÊà$?ÆOÞµð5yòÔ¨U¿IüñÇŸEú2Õ®µMwLó8îØÃc½*•‹ÔWc @€U@`µ¨bÚ @€ÿ �»îéí/½.§sí÷ìñï>{ºæ¥W\·ßùp¦ý~ûîÏ=ó`¡û§ÑpÆŒßb£MwÈ*}zÛÿÆ-7^YâáæÍ› v9(Æ|=.ßZ*¬?Nþ¬ÄãäºÀÍÝî‹Wß’U¶O¯ûã€ýz¨k;ß]n¼+Ó>ùGƒ1#ߌäTY @€ @ °ö´ò—*í{Z‹V¥?�ŠUW]5öÄ“ÏEÛ3..ìR[¬]òcûN.Œ¶mŽ/v   @€ P�€ÀjAB>'@€þ•ãÆOŠÆMŽŒŸ~žVâù'›µGÑ,nïÖ©H§£î{À±1ô½�3ã_|á™qÕíJ<Ÿ’øë¯¿b�ªÛg•hsò±q[׫KR6¯ïÃÝŸŠ³Û]µÄ:Éɲ3ù²ÄãäºÀî{5Ï;½dÁµÉ&ŨÏß(Ò³îÝg@´:åü¬©u¾æâ8÷ìSr=]õ @€ @€�•XÀžVþ·´ïiýüË´Øtó]²p’†'?_p=ÞóÙ8íÌK²Ú$?ª®ºÞºQ±b…˜;o^üôÓ/1{öœ¥~ƒÎ<ýĸéú+Vâo™[#@€ @`y ¬.O}c @€© L™úc\zy—èõÌ€¬qön¼[ÜzKǨQ½ZÖ)¹žÌzÕÉÚNN1MN3]Þ×ZU¶�ä4Ô× Ç÷Ý}}‰¦5kÖïQg‡¦‘˜/¸Ö^{Íøõ×™Yuýid”-[¶Dcå²óƒß�ƒ›·Ê*™œ"ÑíæEfð�¡Ñì°“²ú4ܵA¼úÒ“Eª£1 @€ @ÀžVþk 4ïiMž<5jn×( æ»ñÅ:묕ùÛܹscàKoÄÌßfEÕªUb󛯦Õþåʕ˴ùûï¿cä¨11àÅ×â±'úÄøñ“òžëöë¢Õ‰-}  @€ �s�Õœ“*H€¬HIXµu›ì“/ß§\]PP IDATÔÚ~ëT§9sæ¬Ø°Zý¬1z<Ü-ï¤Öå}m±Í1eÊ™iÑüÀx¬ûm%šV‡«o‰›»Ý—©‘„UÛ�Ó&®¾¦[VÝï'~k­U©Dcåªsrªê¡‡·Žä„Š…¯�wª?pKTßl“HN¡(èš>}F\Óù¶¸÷þDzš&'ÊNû^¬[y�‚Jøœ @€ �%`OkñQš÷´¾71j×ß7 eܘ¡±~Õ*Åþæ$áÕ>Ͻ—\Ö%ëGèIÁÊ묣G É;™ÕE€ @€�\ ¬æRS- @`…xè‘§âœóþyM}òš¬¾V¨ bInf„oc»ºûdÿCCÏ{¢ÙAMJR6'}íÝ">ùô‹L­}ïýû>RìÚïý(öovB$›Ü ®»ïèå˯§´½0«îg¿[nQ½Øc•´cNýt؈xqàëñH�§ãÏ?ÿ*iÉ¥öèþ›ã˜£Mu Å  @€ @€�•OÀžÖâÏ´4ïi}öù¨ØmÏòPÆŽ~'6Ü j‰òcìÃ[¶‰>–UëÎÛ®�Ö'Uâú  @€ @`a�Uë�X©î¸ë‘¸äò.™{¬^½ZŒöZê÷üù£¢a£ìMä{îì'žÐ"õ± à˜þý¼’iVsË1ì£AuË÷ó3~‹]ö8$&Nü.óù�ìÏ-[ÝêZìþ: @€ @€¥SÀžÖâϽ4íi-z÷ƒ^G´<5ëϹ ¬&E“·E%�ØdÿlÁuè!ûÅ“�ÝY:¿€îš @€�ÔVS£U˜XºÞú@\Ùñ¦ÌTêÔÞ6†¾Õ/õ©�ùz\ÔÛqÿ¬q®º¢]\|ᙩ�]ЉGâ²àZ}õòñó”N\-¨ÿ‚ÏçÍ›—HMN+]pm¼ñ†ñî›ýb½*•ãõÁïÄ!Í[g•{äÁ®qÔ‘vˆ·Û¶ÎÞYaÚ,b�uÖY+&Ž}?V]uÕ"öÔœ @€(Íö´ú¥iOkÑ»ôñ>qÆY—fýyܘ¡±~Õ*9ûšôxì™8óìË2õjT¯×Áÿsv  @€ ð¯XýW<&“$@€Š+pëíÆåWݘ龬«Sø)6ßj·¬i7;¨IôêyOqo%gýžyö…8éäó²ê}=ê­Øh£ Š4F» :ÆõÌôYmµrñêKOFƒêäý-¿Sf;_sqœ{ö)E§¸�çÎ�k¯·]q»çõK¼k­Y)V-[¶Pu~ýuFüþû쬶ƒ^x"öØ}§Bõ׈ @€ �ØÓZ|”–=­ü¾�¯¿#®»þެ�¾ŸøI¬µV¥œ}aÆ~3!êìÐ4S/ùöŒŸG嬾B @€HV­ @`¥¸ç¾G㋯ÍÜcÍ-kİ�¥~ÏóçÏ� 6©³fýž«êzëÆø¯ßK}ì‚øzìø¨Û`¿¬fÏ<}_¸ÿÞuÍ|~S×{£c§ìWÝ?üÀ-qtËC2mò ížsÖÉÑåÚK =NI6Ú»E|òiáO�ÝnÛšÑæäccÏF»Æ–[låÊ•+ÒÞ|ëý8ð�ÿfõ9ïÜ6qíÕí‹TGc @€ @ t ØÓZüù—¦=­Eï¾íÇO>—ùs™2ebæ/_Fòß\]“&MŽmj7Î*—¼•)ùA·‹ @€¹XÍ•¤: @€À )�lä&º ® 7¨cG¿³LæÚxß–ñáGŸe�õÊÀž±[Ã—ÉøK$ Ón±õî‘J\íÎi×u*\¨ò†›ïŽN×ÞšUþª+ÚÅÅž™õ·dœÊë׊¿þú+ó÷æ‡íOôÈ> "MŒß~›½&~sçÎËêý÷?‰—_}s±a¯¼¼]\tþi‘œQ’«ÅQm㥗gJìØ n y­wIJêK€ @€”2{Z‹?ðÒ´§µèÝïwÐññλfþ¼öÚkÆä çô[‘ÔOÆYøúeêð(_~µœŽ£ @€¥[@`µt?wO€Vz�×Þx'=¼uæ>“3§ÿ8b™Ü÷•oŠ®·>�5V«[Æ]·_·LÆ_Ú gž}Yôxì™L“-·¨Ÿ}ür�óº¢Ã�Ñí¶³Úµms|t»¹C¾}kÕkãÆOÊ|V»Ö6ñÞÛÏ8Nš }¥^2V.ŸËƒß�ƒ›·ÊZsS&}â4Š4ªÚ @€ @`%°§•ÿ-­{Z5·k“'OÍ lºéÆ1êó7rºê;_G\wý??4¯T©bLýöÓœŽ¡ @€V­ @`¥øfÜĨ]߬{LNHN!HûúèãÏb¯&-³†©X±B öZ¬_µJ·Ÿ;wn ~ó½øõ×Ñ´Éž±ÖZ•–8Æ€^�£�Ï>uÐ OÄ»ï”oŸ9sþˆó.ì�>Þ'ëóc�>,¸÷Æ%¾~ì°#NŽW_;ÓgEØèNN‡MN‰]p­¶Z¹õÅàHNßÍÅ5oÞ¼Xãz‘˜-¸^~ñ‰Ø}·üms1¦ @€ @€ÀÊ%`O+ÿçY÷´’·%o1JN˜]pm¿ÝVñÁ»r¶èúyZÔk°_L›þk¦f�ÚÛÆÐ·úål … @€ �¬Z @€ÀJ-ð÷ßdžÕvˆY³~ÏÜgß>EÓ&�R¿ïdyçÝŽ‘£Æd�uÚ©'D×›®ÊéøÉ)¦GwFŒùU^ÝäÄÔdÓzI¯ìúã�?£æ¶�âç_¦eæ±ë.;Ä+{Æ*«¬’5·A¯ ‰‹.¾6Æ~3!ëïG4?0º?Ô5V]uÕ%ÞËeWÞ·ÝñPÖçߎÿ0*¯³vNï¿(ÅNhuN<×÷¥L—f5‰^=ï)J‰Ûî¾WóöÙÈL»N/Œ Úµ-°Ÿ @€ @€�DÀžVþ¯¡/�{Zɾ_ò£…¯ý›îÏöÎ~³Sq¿9‰i³ÃNŠ¡ï}œU✳NŽ.×^Rܲú @€ @ _�U ƒXéš·8%^yí­Ì}ìáqÿ=7,“û~ºwÿ8ùÔ ²Æ*[¶l ~µwÔ¯·}NæðáGŸÅ‘G·�ä$„…¯�ßÛl½ÅǸ¶ómÑ寻²>?á¸#â¦ë¯È;�õ­·?ˆ.7ÞCÞ|o±ÍÛ?z<Ô-’{YÚÕïùAq܉gg5ùô×b«š›çäÞ‹Sd‹­w�)SÌt½ãÖNqr«cŠSj‰}Úžqq<ñäs™Ï<`ïxæ©ûr:†b @€ @€ÀÊ-`O+ÿç[Úö´’¨'?Š_øººÃqáy§•ø �„U�ûïYñÒ˃«õöàçr¶Yâ‰*@€ @€ÀJ# °ºÒ¸Ô@錿E½÷‹©?ü”5‡äÄÔ5ÖX=~ûmV¾sKÂ�·ÞÒa©'«.è8{öœØzû½2'¹&µ'}óA¬½öš%ºïâvþzìø¨Û`¿¬îÉI´ÉkÔryÝuO�héu™’UÖ­¿y?—C¨E€ @€¬äö´òÀ¥mOë«1ßDý�ÈÂHÞ’´[ÃKô ˜9sV^XõõÁï,Vç ÷‰ÞOÞ[¢ú: @€ @ ?�Uë‚Xé’àåvuöÉ„&“^sÍŠqÓõWFËÍbõÕË/fðçŸÅäÉSbÒ·ßÇÄIßŨ/ÇÄÈ‘cbøÈÑñÝwS2í ó:ù/G��Ýö<,’ ¾ìP'z=yOl¸AÕ"?ƒú%.½¼K<ùt¿Åú&aÐ�ý�ºu¶-°î W†D‹£ÚÆüùó l[®\¹¸êòvq~»S l»pƒdÓûÜó:Ä´i¿FrúÃ)­s{šiQ&“|Ï8ëÒL—ä$ÙïÆIˆ9—קÆÇ��È*ùŧ¯Ææ56Íå0j @€ @€+±€=­%?ÜÒ´§õí·ßÇÖµöʘ2éÓ¼ýÍâ^Ÿ|úEœ|ê…1æëq‹•X¿j•x÷;±ÑF·¼~ @€X¢€ÀªÅA€” �žOõ�SOo¿Ø½VªT1Ö\³RÞß“Ðæœ9sâ÷ßgGX-̵CýÚñÖ} lÚç¹ãÄÖík—lüö|ôŽBŸö:}úŒèþh¯¸©ë½‘üÿ¢W~íÓë�¨Ww»ç´ Á#=zŹçwˆyóæ-±O£=vŽÛº^[oµE¡ë®ˆ /½âú¸ý·3SÛ¿é^ñlïr>Õd-m±õîY§×~üþÀØfë·_Ρ$@€ @€–*`OkÉ<¥eO+Ù§\o£:™½» Öˆ'g¿Í©°_£$¨š¼èéÞýóý{òãîçz?»î²CaKjG€ @€�" ¬‰Kc @àß,põ5ÝâÆ[îÉé-Ü{×õñßã³OÒ\Ò÷?øDœQ§|7ƒo~@œpÜÑp—‘œ�ºàš={NÞ ¯Cßû$Þ~çƒè×ÿå¼@m~W²‘üx÷ÛŠuúAr"èM]ï‹·ßþ ¦ÿ:#Õ7�†»îGÑ,vÙ¹~NÝ–W±ÿ�syt´wføk¯nç�Û&•éÜÜí¾èpõ-yµ““)F�x3V[­\*c)J€ @€¬¼ö´–ülKËžVËcO�¾žQ¦L™¸ ]Û8þ¸ÃcË-ª/öæ ä‡ÔÉþáÌßfÅøñ“â«1ãâÃ�†Er*íÂoŽZTµZµÿÄ3Oݵ¶ßzåý2¹3 @€–»€Àêr&@€,K�Þ}ÄeWÞ“'O-ѰÉI™W_uAÜlß"Õé÷ü hszû%†N“bI`µüj«åG sÒk¹rå¢ý§Gû ψ²eËi>¥­ñ¢�Õ·?õëÕJ…áï¿ÿÎ; wð�¡qѧÇ>�wOeE  @€ @€�•_ÀžÖÊÿŒ—v‡¿L›�¯¿3x¨gÌ�;7«éê«—�J+äYgý>{©ûŽK£õIGEçk.‰ä„U @€ÒXMSWm @`…øã�?ã¥AoÄ˯¾_ &LŠ3Ë7Z¾üjQ©bÅØxã óN,Ø¡~íh¼Wè_oûbß[r²Áÿν"/ÈXÒë ÷‰k¯¾(¶ÞÊ«æ cùÙÿ±÷€òTÕáÿÙòú·¢ÆŽŠ"‚‰5–Ăƞıl(ˆ]A[ˆc711F£Ñ[lDXƒHQA Š E¾ý}_ÙòÿŸ;sggvgwî´­ŸÕ/ï½�[?÷ž9÷œ{æÎ¥WÈÓŸõbùù/®–ãžò8yÛ›_í’�4€ @€ @`äði�|FÞ€?{Ø“ä¼o^TH;jµš<ê/"/?å¹rä/¤L � @€ �D€€Õ$B\‡ @%8÷+ÿ'o}û{S®®¬,Ë£ÿò¡râ³�“?úÃ#KjÅB€ @€ @ —>­ÑÍŠ_y•û¤“ä‡?úI¦Fèi¬÷ºç]å;F÷ØGÊ¡788S9d‚ @€ �•«YÉ‘€ Dàšk~'Ÿÿâ9ráE—Èeßÿ�üú׿•Ý{öÊæfC–——䆇"‡Ýêær§;ÝAîsï»ËîwoQç2@€ @€ ŒŠ>­Ñ�o6›rÖÿ~Mþ笯È%—^.¿üå¯åú�»ÌÛ£êõºñnYY–Þðrã*·ºÕÍÍ ªGu„y{ÔüüÜhN­€ @€D„€U¦ @€ @€ @€ @€ @€@©X-/…C€ @€ @€ @€ @€ °Ê€ @€ @€ @€ @€ @(•«¥â¥p@€ @€ @€ @€ @€ V™€ @€ @€ @€ @€ @¥ `µT¼@€ @€ @€ @€ @€ @À*s€ @€ @€ @€ @€ @ T¬–Š—Â!@€ @€ @€ @€ @€Xe@€ @€ @€ @€ @€ ”J€€ÕRñR8 @€ @€ @€ @€ @€«Ì@€ @€ @€ @€ @€ �R °Z*^ ‡ @€ @€ @€ @€ @ `•9@€ @€ @€ @€ @€ P*VKÅKဠ@€ @€ @€ @€ @¬2 @€ @€ @€ @€ @€J%@Àj©x)€ @€ @€ @€ @€ @€€Uæ @€ @€ @€ @€ @€@©X-/…C€ @€ @€ @€ @€ °Ê€ @€ @€ @€ @€ @(•«¥â¥p@€ @€ @€ @€ @€ V™€ kë-i·Û&¥þWõÿ4ß›¿ýrìß&­Ÿ¸sM¿óËñËèÎ)7(ÓË×¹Ö[Ÿ½¦‰l½6tåó¯Ûö%õ£{l}]ýÚâ[©xt~z_èíwö—pZ?›Tü/õG\¶ìpºH}¦¿Î˜¶eÚ6;×gûÕUvR}~=‘¾v·/Ô~qýëæ·¸Pu˜õ$� @€Æ‘À�µ¦´Ú"­V;øÙý\‹ù.’οÞlj9miµ$øé¥ó¾36e`ûö¯oö°±oC¶¨µ“û¥KÈïÙÜ![;\^¤=ÑtýÚùÞ7†­]Ÿª1íÛàÝívmO8]´<7ÞýëñÎú,¥ óŽ´ÇúBþ ókÈ·úÓ»¤íø?ÂiÂþ•ØïýDHÃ>•�ymž>í´åDÛëe ûA";ö+K™ýxng¾}Ú¹¾ÑÇ[š,Ì{>ŠÁ~¯é=>¿Gý|=��)®ün¿Ð€²‚òƒ4}ÚcËŒ)«ÇïåZV¥büfQFéyôïC´ð°ol�ÍN¦Þ¶õñ»…f_R¹Ýevœ†áyâ3Hšæ�mŸaž’ýÀ¶ZŸ_Ÿ2³ÌñÁmM‹`RÆpíÛVKÄËãýóæ¨þ^­V¼ï¤ó»~áýí§Õtú](Õ–c®uÒåûß™2ü1 êë®;TŸ©»o}^=ÝõÙ¶uòFÛÓi»-»ëº2ðÖöqPûµÏÖ½Þá¦eâãKµF£ @€°ê‰$€ÀøX]kŠn¬4u#ÅÿÙl‰4-ó�þn6^ôw{=H×–fÃË«Žhï§¿#ÞÆ�~¯4ƱúÛnØè&P�Góúˆ&¯:¸»Êè.Ón.…ëuÉÓÓ.Ó^¿-±mêí—Ý|ˆk“¶=øÞï‹–¯ ’ú<ˆ›iwPžåÛËÐÔéO\>?¿Ï8ÒŸPûìÆÕ1?¾FË àF@7—ºÔ‡rÈ‘lüÝ!G¶qj[uWº°Ã{Pº¾åEê 9�Öã·/ä̶›B®í § ;—Ã�ç¾ïÈ�ôq@ÛÃAÝi¸Çµ?è[—#½__Õ®›fÂn>T=ç¾Ý”Ò˜´ç½ùÝOk6´œÐO»Ñ é¼ÍñÓwÒÚ45[®ßS®¿iaò÷©'؈ðÓØ /½ßÖPý^ûý²ýMŒpÙl ¸Ý#H@ãC@ÄSÛ·¡vq—­l¿3öµoC‡¿³v·~gmèî@Gä zôlÞÎw^zÏV[ÆXFÊPnwY Aš^ÿl`fÿ Mm·m¯µs�ß \þ€ QMÔÕÅÁÔòAxŒ:mÑqâ@€ �¢ tûqÃ�Ä6X¿‹ó·Æ÷|¬ fîòyZcØ/ðítжAÒqetûfƒ jë“îÝãÛ¶ÁØí·~ÕN]~ð{È÷hƒ¼­ßÑs͆|¢1í³~õÀoÚ'M\ v8Ð;ZÎ`ß|l¹$n}·ÝeGýÊ?r?ß÷À1 êJng¤Ç}�î`r;—ú—ÕñAkð }‡¢<@˜%¬ÎÒhÓ×T.þþ.9ý—Ç>%^T#b@àK¿@üWÑ]�Æh›2Úú»´ÍW�£:'TØx'6zYÍOýŸ(Y1U:§=ꆇWºý¿Dé¦"ú ‚ý‚+¼ïMРþÏüôÿ‚¡`N?ÑË ô´›Q&(ÓSÚôAcEš­–©ÇlT¢� Ýã@€&‰€n„ƒpÃÁ±6€·;Ø×:–»¿×ue\pð ôÜ›÷cƒ‹kµNýAŸBËö»pаæé Pö„;AË¡ àªˆ¶YóYg}ljß?ð<º‘â ÞßÙ�;°¾Û1nƒ«»N‘Ô7ËÇdwƒG‚¾CÁÕáÀòØ p »ŠÈÒb-ïT™ÚüïÿÄÏå·×­ý;áñ‡É šŸÚþѱ°=íɲWªÝ¸êù.¸>Ūs"T8¿±9Õ6¬¨ÝëÙ¿žÕÚ±�=ó·¼ÁØÈ~ǼSó|ûØÏ|gO�4úv²ob;(jÑ`¨ßwN�l0šÔZvpÝÚì½§“Ü>Ô:QÒ|²Ï=;Ù+Ó´Å/»cÛîz��š½ÑÀ†.b>S @€ @  n�óÙy~ÓÎ� ÿ«=$¢�ÿU}¨aÿ çk½n�Hðå†}¾Aù ¾\­³^O_nOPr\t—7ˆíH8ø$ˆ±çþY}¹aÄÏŽ/7�è�,/þä‘¡§â "@Àê M.�³¿ù{yôÉç›Ý§Š–ú›]&HÔüîý¨˜�-ïh4û«IámÓ ·õÔ@€ @ 8áàë°ÓT�°öd“î““Ãw{jK÷wá›»�âÁÉ˾ƒ¾;`»ÇÜã@�P:}9.¸:ršrptEûà›ÈSO¹H~ô³}Ìï|æ¹ÍÍWŠƒ;…%¹ØÓÆÎ6ñ”ÖžîØÖž=m�ê)D— @€ @€ 0Å\ÞÎh<ƒ¡Cú$a1 >ÕÙ; Â+³÷й2íÿNgÊ5é=Ÿ¸}›b8ÐùøÇÜRÞòþãOžâ¹M׊!@Àj1)e œùõßɱ/øVçx—)ì#]‚ @€ �t.ÿƒäf7^J—iÆR{ú…„^2cè. @€ �†# IDAT@€ ¹â‹&7½Ñ", �V™èCà‹~Àª} #œ¬ÝnI¥RkvúúA}²c’>ÚfóâÆÙêØiò¨Ù´ÛM‘vS*Õé{•è°ä£óz 3¢æ)&s8“ybÊlÊûÊo�[Þ£N:×ô5&‹ÿˆ•¹ä}zêª#AáríSY6¢Ý>=ÕÖ¼Föürüìá¿;í =åe“òÛï÷À/Ç+DÅCO¡ªVjö*sê”y‚+Èßi»í[øI2‘íhP¾×w}MªÞÛô•!U¿¿ü€­Ï¹ëµ®ÞiÓvh ÂO–¹óÇÃí�áï½Ñ5�V«aä£^_ÃÔ§åkn¿�×8£4ŠC¸Õs-��”ùœúØ9 Ü;ñÛ›9Áüñþ é?Qôõ¸úJZotoËôîÕ�O'�­«S‡Ikëé­:hgP¤_˜wš¹÷*];ÿ#•šwäŠØtúÚ[¯w^ÆN[ý\]åyiü´*ó~Ý€Q§MÞ+uÛúÞ]{“ µ-ÈnÛn«4¯îÄé„©ý 2ÛvûýŠt6Ü} pSZ­¦TkóÁC5Á˜´uܺÆÇ¾*9Ô_Ýü¼qêÔc›Ý=æá¡×zÂãæý^wøeú…}öÞÚ™£^õzonù÷¢Ðum¿ŸÇŽm/W{BŸÍסÐ34©9¿3` }­´ã‡õU<(ÖWŽ(G²a­¯r4ÑÈՍרiÛŸÕþ¸êœ‡È!;¦oŸ–ß ôØÓEÒt++ë|v+ÝKÅý> ­li¹ßgã–” ùH"4ב�rÆ ù(‡ë°KE>Ê!Ž|”ÃuØ¥"åG>Êá:ìR‘�rˆ#åpv©ÈG9ÄgI>Âñ'—3Ÿ(u² °:ÙãGëK$p͵›òú÷üHþýÓ?�Ô2‹“¦ˆT'jÃØÛøÒ µ|�ÀúªQSŽ´�ÙmI[ª¢¯µG¾ÛÁ5éLМyg7¡?ÞÅð¼ :´¯°4¯³4�w~ЋÉâEÙÙ�¨ Ì«6¤Z[ô®Á\^È )Óæ÷:ã³±Q>ÞOÜô6È 7¥åc®´™¦>Œ¦ÁO^z�÷òB|ü€'3$¶xԖ͆ÿ»…` õIj ›Ÿ…ýÞê|ï3A€¡ žQùt˯Íç†Tª ¹ïð6 m\‚gй‡4¶€¢ôòQÎø¸–:5òè;_�ë‚pÔmðÜ@�щ6�§G#1ÀžZ¥ñWÜ63T�`êÎÚÎkO�ǶÏ„];šfúAìf}UóWeáÀpW +?ݬ­¯~ýõ‡Ë–åZù`'¸ìéáë¡l¼±Òs›µû½+!ìiWRÙÓM�½�A)9ÑÙ°¢?ÒsCÄ3C¤ŸKis ?ÒsK�þpãÔ� ý‘žúý‘~Ö“ýQ ÇÞû`1ñ ƒZ7.ë«î6âO.gNQêd `u²Ç�Ö—H`}Sä]¾JÎx÷e¥Ô2?W•Zµ"ÛW­Vüß+R­éé†�¿kU1×tc»Vó~×45=ÑÏkÿ®ÕôÄÁ¦ÌÕjR3ÿ4ME굪÷{E¤V«šüu¿NýÞ¦Ó²õÔJýi¿3mñË1iýzƒë¶Ó¿Ý6½ùÛ«Óë«×æ -¯ªmö'ósõH[LÚ Ÿ×Ž¥…líVKª6šµ”u+´ÙlÊÆúº,-/»e˜ÒTëþI†þ „öÆà”?ÿôBdœÐè݆OôÒx'ý¿[næ?ÿZ[d³ÑðN$­Tý"£§7ziõ”??_PŸ÷‹ù>t2_¸Ý�¶†Òú!¿áþLÚ¾®¶…Ûnë×d:wÛ­¶™¿A}¡>›¢ü¶ùÅFú­Ï A¶¬ ¦v[šMïÔèði–]']z§3ú§Nv÷ÃÄ9u�¼Ø/m¨\=¼²ÙlHcsCêóK‘>ùëýÍ�ð˜‡Ol´}ö®wÆßãÞù;n^ãžW]ó¡‡y×<êðë³?‚ö„æUdìÂãhë´qðöZxž‡N© úl™ú×"òIïǽ…ÚÞj6̉¶ÐŒ(’-NÎìœtís˜¸mÊhcÓ»/¤ùx†§>P�M7¸Ô5.Ž ïdîb‚¹]úMš(Ï9êé�Iù “2RÅ·Ó®3"' �PuŽŠ„¾Ú`k?(ºsÍ×éöªÐË>Ÿ¤'´«|Tí“Z~�³ÿŒTèQ2ûÐS(²Û_7xòÕ•1t­ÝsͦõƒmcB�6ëšHqèHø–Ê´x�Ö¡`aóà–m¸*û u�Òž‹ÿ¼ø�›²ãìéí[æäð[mØÓ4/ I—Ö-Ø[Oú×{½Ëý¾ŒúÓ•é¡ôh›Àö~·Þwüì.'n=”¥­‰Ó<¡PsÒ|sSjs‹á÷ä-¶“?E§R$ ž¯Hj¨ë8™ûWš$Uì_O*2,iêO*×6¯ŒþÛõPu€|õ§h@¸ÿƒì…fKuIg y~‚Î7–“õ„Un×K¼ç¥í—öùŸVSÍM©Ï-†‹í¼Î$\[¸îˆ´÷•¸Iß‘Øö†ïÙ˜¾ìæ`/õëÐû°·ÿüV¤ Ë TOЭÐCPÝõzÉû P¸­=;_ØßÔž¶ú#¸ê/W|¡·Lt �´3Àä}×ÇðÈDޮѯ›0$;$žþ�j-xÓEØO]#ù~¬®ççÂmˆ  ª ½¥,4†öyý £þèž×Ý ,Ò°ü$ ¡ïjJSõG=ú ÎîùLÝžI�Þñ�ŒKL¡±m´þÁÎsj‘1�bysŽ?Qº[ˆxð,bÌøw‹yp���±}6”/nÌ#s×úœÌڻמË_Xnˆ\÷í°ûö•é  �þÇ m0¸7_þ|“¨¿©+SdþE…²3e{�w|¥ª¼ªÆã-~ø›º…a¸ãoŠç�| wŽkmÈò1®ssÚ…|Œ·|èiaÝû–ø“ÇArhø `uÜF„öŒ Ý`{Ó¿^)oyÿA›pÏË»_s×±icwC677M ê8fºBÒNýh»ËúŒS°êæÆ†,.-9uu\ÚíÔØ H„|ÄÒ¸Ì3½ £¤I’$Ûh4Ì>‚ê�H`rhÓ'òö£›uK мö6 ü`*?žKç¥ æå³Áæ^zÿ_W€³ÝÍèþz�ð¶¯<¤+>Òf“²Ñhš`î…ùÅNp~8;Ôgm_Ðî®@~ÛÛv¿A‰Áð¶ÿ‘>G‚ﻂáÃ�á1ïÝÖa¦ŽîÀô �Îßà ‘wÚ N?¬¶ÆÀT ¾ï /"ÍÆ¦ï\ðN'÷¦É€`x¿Q‘~„öè»Û×çAsŦ�€‡"1è«çgôð 7ÎÁÍù–Ùtôx;ó¶7>ò�?vá9è ?¨Ï¦ÍM‘êBä�Œ¸>›ÓSýv÷ÛœÝ�x2kn·þÉõ“Ìí«:<ì ó(.( cò|ÅžNfTD ìéþÇÅÎ)bœÇ¡ŒI²,/äù–ì ñ¤Çå>Œ¿iX’_òQ¬|þ“._‹­Å}w§³1·ß”ç äcq)ð}…}�Áï»PôÐïP…Pp(87|B§?@·ÓÈÈ¡ �OÁ¿}¸?”)¸îýbžèø$¢õ„t‘ý7ÉÄøª‚2»ê Aa¿Žáa�;/Ý ú81:FDÆÄ¯¿¡þ¦ª·ŸöÙ½¶Ž¥ˆO©CfÕÉÓ ŽîŒ{è»°_&2&>×p¿" ñúi×WáüºçU¨ûÑy:L¡û Ë_ÚÃ5ÌwÁƒ¬Îßlh¼zæ_è¥7qóªû�μò m5›Òjl˜‡�–]þ½ðümë‰Á8ÑyÑ#ƒ¾_Ñæ˜AóáþvævØ¿Ü#«}d(2/CþÏpÝaþ¡i×yئëÀ_Cþî�LDƤ#¯}ëë>”ÃÖI71™‹m¡vžö‘­ÈѺ#žôeeótê Þ�7׺e³ÝôïoÑýîî¹?&¡ ÿsïwº¾òö+:� uøDe½3GܯÂ/‹›ö>Ðõ3íÃã„Þ§;÷õ´ûc³ȸÌ3ó°¯4{Þ$Š?9ëÈ’oš °:Í£KßrÐ ¶¿y÷å>ü£ œ‡Þ÷äm§Ý%U¹ý69Sâ�Ø[¤ê“Ê)Ž„p(·Ì$jÜ*Ÿz½^f5¦ŽQsѾêÍÍÍ9õUÓ«£¢¬v�Ë|ÖØŒK�ßO„|ô§…|¤™IÉi‘�þŒ†u�4Jè�x:ÃäùÐSácƒn»7>즊"«tNk·ñžÀï˜@ø¸ xã\öŽú1ƒÑßÝ6“F7IÔ¡ïŸ „6º6¾¼îP ¶Ã‰ð*�#L»‚ð»N·3©'@ÙAÇÁýõé èïÎÄ¡GOS�{÷Ô¶TÕþ9⃓ﻂ×Ï¿ä:¹ðÒë"‚ o¤¸þ[�LV°3ž{ºü €½€½ÀzhðÀßÏ{ºØû3ööBš5.óý�þPø›ð7¥¹Ù9ÃúŠõUY{–a²ã¢/ÓÈöy‡–õ¥Zo¦Æá´åÅ/˜€ÝÐÃö»H`w(ø8ìõ ðê²ÅxþIï-$¡¢n4�{Poä|ý NëŸ�P¢u´L›m;ÑÌA y×Û;»ûïDÉ÷>„Ð N®ï=$¥Ã&&HÙ"ëKîá\�i{Ÿì¨'=`åCß|bÇ9Djo§ÐÎ8wñ·mï�™}Lô°DäÁ’à�]½o MÁÈÃ&vœµ¯ßºôZ¹ø²Ý‘[þä4wTÒÎVgi´ék*ºÁöŠ·_.ÿú±Ÿùþ☛Êß½ì�R•Câxi"“Ì1­¡¢§ê‰�e~Z¾“tï$�–¶#ý©!YfÔtåA>��éšÑÅöù@>Š�QÓUZùxÏG,ïúPçF%²¸P“ß�÷ðé‚SBo°§K€*2Ë|.·E啎=]Ûi-ù`=4­s»ˆ~!ÈGóhZË@>��i�ÛEô ù@>Š˜GÓZò�|LëÜ.¢_³(ïû¯«ð'1y(c&°:ÃL'³Ð ¶¿ñ{òáÿþY�ý±¹¹œñÂ;97.¯=rjì�iÀ™ò™ŸŸrÍïNbxêªlÊ��´w_ÖW¬¯ÐèôGÿ9€| Èò‘vm¥égu}…?9Ël!Ϭ `uVGž~'Ð ¶“^w‰ü×™¿Ò>éÏo)§ŸtTbÞ²OLlÀ'˜¥ÅIÚ“L766dnn®´“U777MÙE4©8mð+ò�qk •4'ý"c|cRÓÐýA#Cš„c\ ò�|°¾*g}õoŸø©¼åýWD ß±uN~ñ•‡Žña<š†=]Î8p¿ç~Ïý¾œû}9[^©ø›âÙ"Èþ¦Ás Ì7z•wÇ+¿dÖW¬¯Ðèôú#‹¶A ?Ðè�8ý�?9Ë•<³J€€ÕYyú�H@7ØžñŠoËgϽ:H{ücn-§<ëójP :\OÔLlÈ%P6ุ¸8E½êï$OŒ·¾¾. ¥qÑ`& VՀآ>úT¥–©ÿ\?ÈGRÈG6ȇ«„Mo:äù@ ?²l ?¦W/¸ö,¯þøà§¯’¿ïå‘êÙ1/W�ó×&Ìl:ìéâ‡>ï|.¾E啘6�û}yc1)%#Ø Ø Ø Ø ƒçûñ|Ðèôúý�þÈbó ?ÐèôG?ý�?9Ë]•<³J€€ÕYyú�H@7ØžüÒ‹ä¬oü&H{±·•û¾y5(PO¯$Xµ‘Y¼7²¸´”È~Ò¤}mùÚÚZ©A¼:/Ûív©±.c†|$,Þ‘�X@ȇ‹tMwôGÿñE>¦{î»ôù@>X_•»¾ú�ÿþ™¼á=ß�Trã,È�¾ô`�é4ØÓÅ?÷{î÷Üï˽ß+±å•†¿)ž-ò�|ØÍâ4o•ž.ï^5)%³¾b}…þ@ ?úÏäù@>��,k:ÖW"ø“³ÌòÌ*Vguäéw"��M‘Ç>ÿ[òÕ ~¤=ù)·““ž|xO^=iruu¿,--§~=zbC¦ Á,-NôY}bÝõ³và@©A¼jTêüå©¶ÈÇàÙ€| pŽ"®·’©M‡| ¬¯pŽ*ÖW½ó€õÕpÖWýüÏåŒw_©ìf7Z’Ë¿ø ©Õ½Eu {º(’"¬‡X±b=Äz(~°Îz¨8�V^IØ Ø igë+ÖW¬¯X_±¾b}•Vwhzôúý�þHÒø“³Ü]É3«X�Õ‘§ß‰6"?á›ò­K® Ò¾øiGÈ3›H^=¹r÷®�²uÛöT�Љ auøuJì8¿¡È~f®««²´¼œ%«S}-b«Ù,µŽ¤† ›ÍæHŠûµùHšÝù¯#ÈGÖY„þÈJn´ùм¯²¾ê?–ÈÇhçyÖÚÇU>>~æ/äµïú^¤[·ºé²\úÙfíêÌäÞ®2ÖÜï¹ßãoJØ ÃžŽÄz¨�[ðÐ ×õPÑ Šìg–¶!Y¨�>O‘ó†õë+ÖW¬¯²ÜÕÐY¨�>úc8c€| ‡sѵ EõÊß\WJ�N¬Nç¸Ò«èÛ1ý ¹ä;ƒÒ^~‘rÜ£‹”¾{÷.YYÙ"i^9Ôݼ"y»žöõbƒêÓ²´oóóóy›UxþQ3_Ý¿_–WV ï—-PƒU�M37GùA>úÓG>ú³A>Ü¥vÔ÷²pKÑîã–'%òáNùpgUTÊQ3G>ÜGrÔc5)úãS_ú¥œþŽK#`¿Å¹øÓp‡=£)±§ó<ööö4öt–; ë!wj¬‡ÜY•rÔÌ‘÷‘õXMнàN49娙#ÉcdSŒz¬�÷±**%òáNùpgUTÊQ3G>ÜGrÔc…þp«<)ñ'ç¡GÞY#@Àê¬�8ýu& l÷~ÂWå‡Wí ò¼úä£å �¸Eð·j jšWÀw7`œ'útñÜÜœ3£A õULÚ·¢Ê+¤Q~!i_UdÝz¢âÚ�¥žz:.ÁªÈGÿ™ƒ|ijA>ÒÝmÐéx‘ýQÅä2Ðè�äYM�þHG ýáÎë3g_-¯xëw#ޏÍV¹àã÷w/dFSbOçxììÖC¬‡ÒÞEX¥#Æz(¯"RcOA1¹ ôú#y–`O³Ÿ×;K°?°?ÐèôGÈò‘F>ÔŸ|Ú[¾#•J%Ȇ?9 AÒÎVgi´ék*ºÁv×Çœ+?»z�ïŒý¡<öÁ73ç îTǨ~ªÕb^˜ªs1‰u±µ°°�·“_û¦ÿòœ:[HCº Qç½¶+�C"O»´þõµ5Y\ZÊSÌÀ¼:Ž››²eËÖÒêp)ùèO ùèïüA>\¤Ë»Ç¢?ÜX• ýQÉärÐè�äYMÁúÊ�úÃ�•Mù¹s¯–Sß X=úvÛäÿ>z¿ô…ÍXìéì޽€½ÀzˆõPÚ;ë!wb¬‡ÜY•{º(’Éå ?Ðɳ{:-#›ý‘•\ö|è�ììÒæD ?ÒÎìwbèwVE¥µþøì9¿’Sÿþ©T;q7ø“‹]Ê™6¬NÛˆÒŸÂèÛù¿rÍïׂ2ÿþ”;Ë#p,”'ÐTóë‹ãrúèÚÚšÌÏÏçêSü(Ÿ˜ï7F½é§õ«ÑWTPp\?5Xucc]¶nÝV˜d)ùL ùèåƒ|¸KúÃ�UQ)ÑE‘L.ý�þHž%ÑèwbèwVá”_üêoä¥÷íHæ;¹]¾úáûf+p†raOglììüMýåù@>�ä#�†Å^p§…½àΪ¨”ø›Š"™\þ&üMɳSZF6=ú#+¹ìùÐÙ٥͉þ@d™3Ÿ;÷rÚ[¿�?9-<ÒÏ$VgrØé´ Ý`»Íƒ¿$»voÉßyú]äÏîó.Ùû¦)jñžw‘d8îÁªEôSËЧiFu²jQc>hâi°êúúšlÛ¶=×üuæ¢X1o”òQþŒ(jÌ‘÷±B>Ò±B¸óeÊ¢î%ȇû(²¾rg5ê”ÈGºß¾ôõßÈ‹Þ X½û�’s>ð'é �ÁÔØÓÙ½è`¼"ô÷ûlc9Š\ÜïÓQG>ÜxáoŠr*bÞàor›{ySuOÄßä>ÈG:Vø›Üy�2eQ÷äÃ}±?ÜY�:%ò‘nЏ é˜�25ò‘Žþ4Éǹç_‹?9Ýð“z† °:ÃO×Ð ¶›Ý÷‹r`½$ü§×ÞMîÿÇ7ÊŒ®¨Å‰nbU*•Ü'¢®8 sóó…r½¹Öh4¤^¯gæ­ÇáI³²�Oºy°¶v@¶oß‘‹Õ¨3#éFùpã…|D9¡?Üæ úÃ�Ó8¤D¤ô‡/ôúC œsÞ5ò¼3.ŽÀ¸÷�–ÿyß}Ü&Ò §ÂžN?øØÓ½Ì†±Çýžû}ziõràoÊJnøù°Ò1Ç^pã…þ@¸Í”øõ�Þ—òî{䩟ý 7zè7N6úÃ�úýá6SÐY9�C>ôGºQ˜6ý�?9Ýø“z¶ °:ÛãOïÐ ¶Cþøs‘ï{Ã=äÞw>47uèT^G„–¡Ÿ¼§…¬ZTßÂ`777 + ÌÍúQVÚ¶¼Ì³Ö¯uë¿<¯+Kª[�ÛVM°jVIõ”}½¨9„|¸�òáÎjÔ)‘�t#€þpã…þèu޲¾r›;è7Nã� ý‘nâôǹçÿVN~ÝE‘‚î{÷Èçßs¯t…Ï`jìi÷A/JV±§Ý™Û”¬‡X¥Ÿ5^ÖCYÉ ?_Q÷XüMîc‡|¸³uJä#ÝàorãÅúŠõ•ÛLéM…þÈJnøùÐ阣?Üx¡?Ðn3eüõþä¬#I¾Y$@Àê,Ž:}v"°oµ%7ùÓ/DÒ~èÍ÷’»u°Sþp¢¢N]Ð'Lô“7³È`Uí›.¶Rsé—A¥sss¹=GmÜc@Avñ¾cÇAè®´:��th‘7^ÈG”úÃmÞh*ô‡;«Q§D¤ô‡/ôú#Là«üNN|Í…(ÇÜóPùÌ»ïé6¡f8ö´ÛàcO»q*#÷{î÷YçöBVrÃχ½�Ž9ö‚/ôúÃm¦ô¦Bd%7ü|è�tÌÑn¼Ðè·™‚þÈÊiò¡?Ò�´êüÉéæ©g›«³=þô~�ßïÜ”Û<è")>öŽûÈÑ·O÷Úu}Òlcc#w@§iYș糶¶fÊÈ{B«¶A^ëkk²´¼œ§I‘¼º8Ñ€Ü<í+*0+Ü0e?N'˜ê8®éɪ;«v¥�ÈG:bȇ/ä£×ùƒþp›;è7Nã� ý‘nÐn¼Ðè�î™ò�‹/'œ~AäëÿÉ�ä'ۤšáTØÓɃ�=�̨¬Üï¹ßg�[Ø YÉ ?öB:æØ n¼Ðè·™Ò› ý‘•Üðó¡?Ò1G¸ñB ?Üf úcœöáÓŽú#±iÖø“ÓÍRÏ6Vg{üéý¿úíºùð³")>ýO*·?l[*nVWstê ¦ºÐ™ŸŸOUwwâ"OVÕ'‚×ÖÈÊÊ–\m gV£MƒUóœ [T`o¸]Ê^?ã²PVNV÷ËŽƒ›6e�ȇ;9äÃ�òå„þp›7š ýáÎjR¢?ÜGýáÆ ý�þˆ›)ßüîµòŒÓ¾¹ôˆûßX>úÖ»»M¬N…==xð±§G'Üï¹ßg�}Ø YÉ�&ö‚;wì7Vèô‡ÛLéM…þÈJn4ùÐîÜÑn¬Ðè·™‚þ—=ø¬ã…þp'7íú²û\ %Xe@ �+±*wyô9‘«_xïýä°›»h®îß/Ë++¹k°‘nf-..æ*§È`Uu²Ø`Õ¢�Ú¾Z½žëÙ2œ? }œNWÕEÜêþ}rÐÁ‡L|°*òá.Òȇ+ä£×ùƒþp›;è7Nã’ ýá>è7VèôG¿™rÁ%×Éñ/??rùQüùÐßßÍmrÍp*ìéþƒ�==:Áà~Ïý>ëìÃ^ÈJn4ù°ܹc/¸±B ?ÜfJo*ôGVr£É‡þpçŽþpc…þ@¸ÍôGQ±Yyç͇þp'8 ú²û| %Xe@ �Ë~¼Wîý„¯D®žõ�ÈÍn¼ìÄL'‹KKR­V�ÒÇ%Ò`ÕÆæfîZ‹xRŶOÛ¤Áª[·¦;iv}ê¨Z«ÉÂÂB.Všynn.sãžÑ·z²jžy5ýD>ÜGùpc…|ô:ÐnsGõúÃ�Õ8¤B¸�úÃ�úý1h¦\tÙõrÜ˾p™AL IDATIò؇ÜT>ð†»¸M°N…=?øØÓ£ î÷Üï³Î>ì…¬äF“{Á�;ö‚+ôúÃm¦ô¦Bd%7š|èwîè7Vèô‡ÛLA°ß-B<ˆ»´LÂú ²ûx’¬2 ЇÀßÛ%:þë‘«_ýȃäЃ“ƒ*õé�ù……\A…ªp76ÖeeÅýD×î®´Z-Y_[“¹ùy©×ë¹ÇZOê;p`U¶lÙš»,[€·úä”÷fýlll˜2¦=Xuÿ¾½ædÕI_¼#î3ùpc¥Îä£Ã ýá6o4úÃ�Õ8¤D¸�úÃ�ú£wóû#ÊäÛ—ï”§¼ä¼È—Ç>üfò¯gÜÙm’Íp*ìéÞÁÇž�@p¿ç~Ÿuöa/d%7š|Ø îܱÜX¡?Ðn3¥7ú#+¹ÑäC¸sG¸±B ?Üf úƒýn/X¬›ÄLÊú ²Ûx’ J€€UæúøÚE×É#ŸÝœ<ïã–[Ÿà©†Èüü|® Â"N]ÑרïÙ³Û¼¬ª˜ÔpÏXÚ�Z�[mçòÊJæy8 ‹ γèž*ãùpžëȇ*ä£×ù“÷lô‡ÛÜF*ôG‡2ë+÷‡þpc…þ@¸Ì”K®Ø)O|qÔ&|ò_ÜBþù5è’}¦Ó`O÷?öt6‘`=Äz(ËÌa=äF�õë!·™2™ÁèôG–ù�þp£†þ@¸ÍôGž}Á¬Œ‹Ì‡?Ö�&úÃ�úýá6S&[àOÎ:Êä›E¬Îâ¨Óg'gýßïåqÏ??’öâO?T–k}óõ$¦žbºmÛv§vöK´k×Ns긫*«F³‘ë´ÖõõušædU ÄÒÓX‡õÑStjµþs&©ºxß·w�|È r½&Õc¯çuæªùp/8ùHæ…|ô·è�äy£)ÐnœÒ¤B¤¡ÕI[tðúÃmÐè·™"ò½í’c_ð‘äÇ=êò�¯"`5‰!öt”÷û¤{:ºf(âM>Ø ns{Á�SšTØ iha/d£ÕÉ…þ@d™CØÓnÔ°§±§ÝfJo*ÖWYÉõÏÇú*SìólÜX_±¾Ê2sfq}…?9ËL!Ϭ `uVGž~'øì9×ÈSN¹0’îò3Ñ7Ÿ>=µ°¸˜+¨POVÝ¿ŸìØqPbû%ؽ{W±'«®­Éââb®6…3«Sc}}M¶oß‘¹L-CAÓ«–i¼ÅuDÇ3MûºËÐEܾ}{å ƒÉôê ¹Ñh˜`Þ<¶ýêB>\GAùpc…|ô:GÑŽsýá*E*ôG X¡¤z¿g}•žë«3ÖWîó'ëúêò+wËãž÷�HEOÜ-å§ÝɽòM‰=Ýxî÷Ù„€û=÷û,3'ëý¾Ûg…¿) ýþy°²ñDdã†þ@d™9è7jøcñǺ͔ÞTìçe%ÇúŠýîø9À~÷`™ÂþÈvÏÁþÈÆ­ÛþÀŸœ�#¹f“«³9îôÚ�ÀÇμZžuú·ƒ”µZE¾÷ù‡Çæ\Ý¿_—–ò«îÛ+;:Ø¡uý“Œû⽈ \uŒÔêõTÁ Ã^¼ëÓ¢ ™ÆRÛº±¾.{÷푃¾A)¤Ý ÓqÑOžÛ~�E>ܧò‘Ì ùèedæ ú#yòˆwz1úà •s"ô‡3ªH¢�?è�äq@ ?²<øÃ«öÈ£OúzÞ ÇÞJÞrÊÑÉ“nÆS`O{€û}6AÀžîpÞvŸC¬‡’Y±b=”e=d©aO'ËXÚØÓi‰±¾ÊFÌËÅúŠõU–ùÃú*™ë+ÖW¬¯úË ò�|Ì¢|àONÖ�¤€€%@À*s}|ðÓ¿�çÿí%ÁÕ¥…š\ü™‡FRëëåWW÷ËÒÒrî`Õ½{v›`U}Å}Ö�ž²TŸ›+$èPû¶¾¶fN�ÕS7‹øèë´ŸÛw”¹LuŽjëõºS“´ú/W§ŠüDy¹íÝ»GæêsC VÝØØ0Œ²Øöãƒ|¤™9"ÈG2/ä#Þ¸E$ÏM�þpã”&ú# -/mÞuB\�è�äq@ ?²Ú?þÙ^ù‹gÿ¯Tª�ÑN|âaò¦—•<ñf<ö4ötÈ«'¹ßs¿Ïz¿Ç^È"±Éy°’u§È{Ä^ÈæÇF ?ÐýïWÈò�| iV4äÌ~…1ö+Ü8¥I…ý‘†ûéiur ²ÛÔŸü—'~-R<þä<´É;ÍX�æÑ¥o¹üóÿ»JN}óeAÛ·ÎÉ7?þàH™E½†³ˆÅ»+¨rt äL‚“ç‰Û¸²µm{öì–­[·eMû$ÿ°ƒUµß:'––—“ðÆ^ß·o¯8°jÆQOV-j,5FǹÝj™‚‹þ îD‘�dVÈGyÎQôG/[ôG²L¢?’Å¥`}•�ë«7ÖWîs¨ˆõÕ?þ½<æyçI¥ÒyXîyO¹µ¼þEwtoÈŒ¦ÄžÎþÆ ìiìië[Јó<|[Ôf1ööBU†½�…Z¾ÑèôG:¹+Â^`¿"s—ÔèJ½ið7eㆿ S–™ƒþH¦Æ~ûy³òÓ_î“GžðÕÈ$ÀŸœ|ß Ål `u6Ç�^;xÛ¿ÿD^û®Ëƒ”‡¼ _ýȃ‚¿ÕÔ×§çÝ<س{—9YµV«9´*>Iѯ»/Ú¸ÕV듸ËË+¹ú™�2ÑOžñISŸ¦ÕWõ-¯¬¤ÍfÒïß¿Ï0Òö3XµÕlf°ÔQä#Ý4@>óB>â�[ôG:9sM�þH&¥÷xôG2§î¬¯Ò3c}eÆú*Ý*b}õ³«÷Ëßù•HÅ/:þ¶òºçÝ!]cf05ötçTÞ"†¿ˆùœ¦¬‡’i±Jf—‚õP6nø›:ÜX¥›CèüMéfŒˆ>쀿)-5·ô¬¯’9±¾JfÄú*£¸\¬¯X_e�M¬¯X_¥�;¬¯ÒsO?Žë+üÉîãGJ°Ê€@oü—ÉßûÃàêMo´$ÿûÁcÌßz¤¼ž~™'R'»wí4ÁªyNÒœ„`U 6[XXÌÕÏ4UOÿÐOž àp}ú´\¥RØíãÒÒr¦9¡†ñž½»M¬ª�ÐeÖÖÖL°QÖÛAíC>Ò�ò1˜òÑËý‘NÆÒ¤F$ÓB$3ŠKQFpúý‘v6¢?ÒùÅoVå¡Oÿr$ãKŸq¸¼ú¤#Ò6c9°§‹pî÷ÜïÓÎ&î÷i‰¹§Ç^Hf…½�Ì{Á�þX7N6þØt¼X_±¾J7c¼`nöóÒRsKÏú*™ë«dF¬¯Ü±¾rãÄú*'›šõ•Gr¶ùC®Ù$@ÀêlŽ;½v ðš¸BÞþÁ+ƒ”‡Ý|‹|á½÷“F£a‚ó«îÚu½ìØqp®àÄ2‚Uçççƒ3ðIÔ�ÒÀÑaaj¥ÊDÿå ÷/i¼uq¯ 0==6ËœÐ×íÚ½sèÁªÍfCVV¶¤J§´I¼\ QçòáB*}ä#™™Þ³��dNÝ)4ý¥’t?D¤ãå2+Ñ.”²¥A$sC$3ŠK1îúãêß�?;þÜHÓO{öíä´nŸ­Ã3” {º˜ÁÆžÌ{º—ë¡bd/®ÖCÉlY%3šÄõ�K¯��dJÈG2#äÃ�þ&7N6U/—ÒX_¹PÊ–ý‘Ì ý‘ÌýáÆ(é~È~ûn3)>þ«üÉyfyg�«³6âô×™À©o¹Lþù£WéoØ6ùø;ïi‚/³&Ú‚¬q»}ûA&¸g\>E¼R«»/ÚW]àj?õ)É¢N<íÇLÛú)*XÕåÉÎ<¯~ÐÅ›fêɪtHéóA�ÿÕÕý†Ñ–-[ Ÿz:Þȇ;Väc0+䣗úÃ]¾Ò¦D &†þH;£:éY_õ²c}•n>±¾JÏ«Hûãšß¯É1Ç�iÄé'!§<óðt ›ÁÔØÓù{{!í,Â^HKÌ==öö‚ûlI—{{!ÝŒ‰÷á�u§ÈúŠõ•ûlñR²¾JKÌ==ë+ÖWî³%]JÖW¬¯ÒÍÖWEð*Ò›Ôžq×ø““F�ëè `•Ù�>^ðúKåŸúypõއo‘�½ãOs«îÜy�lÛ¶Cdž½†iPiž@ÜîÎh0‚þÓrË0ºëSÇ�~¬ê28{öì6'«f©S™è\f°êõ×]+KËË¥œ¬ZT0òá2óÒ§A>’�?ÈGúy¥9ÐÙ¸¡?:ÜÐéæë«Á¼X_Å;XY_¥“³pêß]¿.÷òÙ‘^û¼;È‹�¿möBg$'öt¾�æ~Ïý>í Ò5÷û´ÔÜÒcOcO»Í”ô©°§Ó3ÓØÓØÓÙfŽ˜½ ö+úÓÞƞF>��4÷Wì�j\©Òb`¤š0)c¤€JšÖþÀŸœ�3¹f“«³9îôÚ�À‰¯ý®|äs¿4)Û­M¹ËчÊGÞr‡œñI‚ÅûÖí²¸´”¹œ¢3êâdnn®ÐÓOõ$6}ºEƒUõ÷"aãú¿±±a¾扵»wï2�ŸY‚Uµ½º‘¤Oéɪ EkOy;¯¿N–––K™{Úå�gœ‘�ò¦ò‘ÌùHf—ý‘�ú£Ã ý‘n±¾Ì‹õU/ÖWéd,.õu;×åOŸ XýÛ)Ïêmò>å%`Og`î÷ÜïÓÎî÷i‰¹§ÇžNf…=�Ì{:£¸\ØÓØÓYgë+ÖWiçë«´ÄÜÓ³¾JfÅú*™ë«lŒX_%ëCö»Ýçë«xVø“Ýç)!@À*s}<í´‹å“gýÚ\ÕÀÂûÜå†ò¾7Ü#/kÜnݲ͜p9.Ÿµ¤>7—)èrPÔàVð訌[=YU}Ó~t.\ýµfNíØqpæ“v5¿žÎêòQg®«–1&°¦·®m‰k/òá2ŠÙÒ ÉÜ��dF±ÎôG&p:ßÐ:ôGú)Äúª?3ÖW½lX_¥—±¸»voȽŸð¿‘KozéQrâ+¦‚).{:ûàr¿ç~Ÿföp¿OC+]Zìéd^ØÓÉŒ°§³1ŠË…=Ý¡‚=�~^±¾b}•fÖ°¾JC+]ZÖWɼX_%3b}•�ë«ÁÜX_¥ŸW¬¯â™©?ù^Çž)•J=H€?9ýü"Çl `u6Æ™^f ðÄ—\(_øÊ5AÎûÿñ�äŸ^{·Ô%�ókjµZ¦ ËAôdÕ,§Ž¦+"£0nwíÚi‚?³œŠªlôdU}µJž`Õ4§Ö®îß/ó ¥Œ‰¾&Hƒv 9YuÛŽÌÁ»YæNR5L��$J½×‘�ä#ýüAôg†þèeÃú*½Œ¹æ`}•LŠõU2£ØÍƒ \_íÞ·)÷ú«³"ÝyË©GË �¿U63” {:Û`³b=”fæ°JC+]ZÖCɼX%3š–õPw?��ä±G>’!ÙÅå‹?6ÏlÂþÀþH3°?ÒÐJ—–õU2/ÖWÉŒX_ecTôúêº]ä>�û”TçvEãO.nl(iº°:]ãIo $ð˜“Ï—³¿ùû Ä?»ÏÈ;O¿Kªtñ¾k×õ²}ûA¥œn™ª1¡ÄERÅÕ­�”zÒfžÓ6]û¤lõ”Ñ2N �kƒÖ¥O6...e ¬Ô Õ}ûöÊÆÆºèI»‹KK®]�¤Kó´R¯Zî×È"ÊF>2M§LÈG2¦"æ0ò‘ÌÙ5ú£?)ôG/ô‡«d¥O‡þHf†þHf—bRí�½ûòÇ�ûR¤Ko=õhy«‰{:QOÖC¬‡ÒÌÖCih¥KËz(™ë¡dFÓ´ ÷ùH{ä#™ò‘�Qw.ö+¢DŠ�=ÖWÅÌ͸RÐÉl‹˜ÃìW$svM�}Ž}î:W4ú# ­ti'Q\ó»�òÀ§~)°Š?9ݸ“zv°:;cMOSxø çÉ7.¾.ÈõçÇÜTÞô²?r.Eèî];eûŽƒ ?ÅÔ¹1 Ó<橧̼Ã^œh_ôIåÅ…ÅL�¦l´ººßœDZ­Teiy9Ýèw=ÙµLcJùëé£yOVE>2MƒÄLÈG""A>’Å¥@dã†þèpCd›CÃÊ…þH&�þHf4múcßjCîñØNÀj¥"ò–SXu™ ØÓ.”F“†û}2wî÷ÉŒ¦í~oûƒ|$�=ò‘ÌùÈÆ(.ö4ötq³©Ü’ÐÉ|ÑÉŒÐÙ¡?sÃ[ܼ*£$ôG2UôG2#ôG6Feé�Õµ–Üÿ)çJ¥º`ªÀŸ\ÜøPÒô `uúÆ”Dà�ÇC.üÞΠ´Ç<øfò·/úC§Òu�¹g÷.ÙqÐÁ&°o>úÄ­¶kX'’–Õça/Þ͓ʻvÊÂÂb¦@S]Hïß¿O–—Wdsc#SÀ«¶Á«ãôÚAc§¯ˆ1�·Õjæ!F>2£K̈|T•™ù(“nþ²‘ä#ÿ,ê-�õU6ª¬¯¢ÜÐÙæÑ0ríÚ½!÷:öL©TêAu<ïF{Ú�Ó°S±b=TÆœc=”�*ë!ÖCÙfÎhr¡?ÐeÌ<ôG6ªèôG¶™3š\èôG3ý‘�*úý‘mæŒ&×$ë�ß_»OŽ9þpø“G3�¨uü °:þcD GDàOžôU¹ô‡{‚Ú�}Ä-ä5'�ØU ûöî1'«æ êK¬(E]„ê)Ÿõzg£5Eö±Iªl5Ôõ”Ñ"¾kçõ27?/++[R§mÕ“U·lÙjÚ�u>¬­­Éââbêú‹Î sHf³öCÛƒ|=*�ò��òغ”Œ|¸P]äctìµfäc´ü“jG>’•{ù(—oÞÒ¯þí>yÐqgK¥:õ¶—-Ïü«[å-zêócO�ßs¿í˜p¿-ÿ¤Ú‘�$Bå^G>Êå›·tä#/Á|ù‘�|üÊÎ�|”MxpùÈÇhù'ÕŽ|$*÷:òQ.ß¼¥#y æË�|äãWvîI—�kwmÊýŸ|vþä²g åO*V'uähwéîöØ/Ë�~¶/¨ç¸G&/ö‘ëUºß^Ù¶}G® ¾";§�’ú�`ÕôT5XµV¯ËÖ­ÛÒg1'«f t WfOVÍÔ€3ñÊä£Àé*jT‹wäÃ䣼¹]DÉÈG³—�|dg7ŒœÈÇ0(÷¯ù-ÿ¤ÚU>~ù›}òÈgŸ$mK[Þþò;°šOD°§ 1 ÷û!ÂŽ©Šûýhù'ÕŽ|$*÷:òQ.ß¼¥#y æË�|äãWvnä£lƒËG>FË?©vä#‰P¹×‘�rùæ-ùÈK0_~ä#¿²sOƒ|üêšUyðÓ¾Œ?¹ìÉBùSA€€Õ©F:Q�£ÿüùù¯Wƒ¢ŸñW·‘—<ýˆ¾U©ÕÓ4·oßQFs2—©O ÕjµÌù]2æ9=Ô¥|}MªÖ1??ï’¼�4¬Z©V3�çêþý²¼²’«-㬚«~fä£ZÆØ2��ÒЭ`äùO6ôGTô�äù诎��òåãêßmÊ#žõ•È ¼ý´;É3wË¡­&µ"ìi÷‘ÞîeÅzˆõ�%€| IwSÖC寇ðÇ&ÍÂñ½Ž| ØÓØÓqX_±¾JÒ\èôúý�þHºSz×ãüWWýj?þd7|¤‚€°Ê$€@‡?ä,ùíµëÁÕç<ñpyþq·‹M­‹÷õõ5óê÷qú´Ûmó ÷2?eÄj0žÖ±°°Pf7"ek°ªT*²cÇA™ê<°º*KËË™òÚLÓ¬Š|äš}3#åpf©è�ò¨@>†9“Ë© ù@>Â3‹õUTÎ��áÈÇ�®Ú+�:ékøo3'¬°štçÇžN"ä]ÇžîåÄýžû½%€| IwRÖCÃY%�CQ×ñÇEÒ+ù@>°§ûËò�| ÈGìì�¤Õúýá¢?ð''I×!Ð!@À*³}Üâþÿ#»önW5XUƒV»?º8ÙÜØÈ}šfÑ1Œ`U ª×ëE7=(O�e»¸´TZÝ«sTÙtð!™ê\;p w{§-XùÈ4•3!‰ˆÆ>úýž¤è�¨È"Èò1xó€õU9j¾{}uÙ�wËãŸÿ�Heo=õhyÖãoUN¦¨TìéäÁÄžîeÄzˆõ�%€| IwQìììì…8èôú£?äù@>��¤9ÀúŠõë+7)ä¿ÂŸìÆ�TP¬2 ЇÀ ïýY[oW_òŒ;È3wëHjuŽê¦æâââØpÔ`KýW­–÷Ê-_û]v°êÆúzî“J]Fû´{×NÓ¯ƒ¹A¦“i×ÖÖÌI°yNµÕ2Æi>¹ò‹K‡|”»y€|ä™�£Ï‹| çúƒõ•ˆY¿±¾ŠÙ<@>��ÊÇw®Ø)O~ñy‘1xË)GÉ Ç6úÅĘ·{ºÿq¿�gƒ=傽€½€½0x³l9 势©¶Ã*ý�þ@ ?º ``¸è ôúý�þ@¸Ü-E’üWø“Ý8’ J€€UæúØv×ÏE®¼ü„#å¸Gw6&õiÄV«%óóócÃpXÁªÚ÷¹¹¹Òú­\X•••-¥Õ.Ø«j¿4X5K°ïÆÆ†a’'XušNVE>��°Œ!Ñ[ò�| ýÕ;ò�| ÈGœstTöÇ—\'Ç¿üüH“ÞrÊÑr±œ°šd¨aOÇRÛsTó9i̲^ÇžÎJŽûý8Ýï‹E¯Dä£x²Ø Ø Ø èô‡Û½,þX»Áþè•äù@>úëäù@>òÉþd·µ*©  Xe@ †Àf£-‡üñç#W^õÜ£ä‰�¼¥ùN ¾qñïå„Ó/ˆ Ìß¿ì(yÎ8au�~ÀžŽ§ƒ=Ï{{A ȇ‹ÝÁzh4ë!—±I›lZbÉé‘ä{{º›ë+ÖWÉÚƒýnö»£³ûûû¼ÿ�ÓU>ð'»hÒ@À#@À*31öîoÈMï{fäÊ/¸“<ö¡77¯jÕO­V›)vÓhÜêîÚy½h°êÁß Ó˜ê|È;4XUOêÍr²ë¸MBäczœ£ÈGñÒ…| Ý›è�äù@>;ð?Š×ËÖ;èa¹¯|ë·rÒk/ŠTþ¦—ÞQN|â­ËiД”Š=Ý;�ØÓñ“{:Ê…õë!ÖC¬‡º  ?Ð.ËCôúý�þ@¸Ü-Åìïâ�ÅËúŠõ•˃õ뫬ë+üÉ.FxXe&@ †Àµ;7äÖúRäÊ_úGòÇÜÄœ¬: �…i^ez²êââbšl©Óîß¿O–—Wr�Tš¦R VÕ¾í8èàLFªÎ…<§ªj[5XUOêÍk$§éwYi‡qÊoYmÏS.òOùˆrA>Ðá�| Jý�þpY ?F«?Î9ïyÞG†êï^rG9éI¬š¿ØÓQ:Üï¹ßs¿ïOù@>�äÃe`O÷§„½0Z{!íüMJÏ~E¡tבäý�þè&€ý�ýá¢IÐè�<ú²‹”‘V™ ˆ!ð«kÈ‘�8;rå­/¿‹<ì~0s¼ôuBú/.XUƒX5زˆÏêþý²¼²RDQNe¨óGŸ¢Ó`ÕQ ¯¯¯K½^ŸØ`Õ"®œkŒ!å òQÛa•Œ|”Gù(�í°JF>Ê#�|”ÇvX%�“|üÏ×~-/~ãw"]ã‹�’ç>ù°aá˜Èz°§;Ã6Nó¹ÈÉ„=�Ÿ&ö´÷úQüMùçR\ ¬‡Êá:ÌR‘�òh#å±VÉÈGy¤‘�òØ«dä£<ÒÈGyl‡U2òQiä£<¶Ã*ù(Ž4þäâXRÒô `uúǘf på/öË]}n$ç?¼ê®òÀ{ß8Ci“›ER›¬º´ÔÓ‰�� óû">kÄÖQDÙqeèæš~4XuTå§§ªNêɪ쫟QûŽjÜÂõ"å�òQÛa•Œ|”Gù(�í°JF>Ê#�|”ÇvX%�›||îÜ«åÔ77Òý7¼èŽròS8auМÀžöèŒÛ|.Jޱ§ó“ÄžF>òÏ¢þ%°*“îpÊF”Çù(�í°JF>Ê#�|”ÇvX%#å‘F>Êc;¬’‘�òH#å±VÉÈG±¤ñ'˓Ҧ›«Ó=¾ô.#�˯Ü+÷<ö+‘Üÿüº»ËýîqÃŒ%öÏ6®º8ilnÊÒòrá}¸¶¶{zkY•êæZ¥Z•íÛw”UEb¹ÊV='5XU_™¡Ÿa´ù@>jÌ Þæ3ú£œ‰‰þpçŠþ@¸Ï–ñH‰þOýñ©³~%§¿ý’È$yý �”ç=õ6ã1qÆ´ØÓã9Ÿ‹˜.ØÓù)r¿G>òÏ¢þ%`/¸ÓÅ^À^pŸ-ã‘ý�þ(s&¢?Üé¢?Ðî³eÊ#�|”ÇvX%�«|ü×™¿�×¼ë{ ¯áåyOå„ÕAs{{º¬{÷û²È¯Üq½ßç% ÁÜø›òQÄß$‚|ä›Cƒr£?Êc;¬’‘�òH#å±VÉÈGy¤‘�òØ«dä£<ÒÈGyl‡U2òQiõ'¿ú�ß‘J¥K�?¹Ö”:ùX�ü1¤%øæw®—‡<óÿ"%èÍ÷’»5ºWÈê¦>•“çÕìû4功ì–Zµ*ÍÆ†T«"KKKR¯UDã+•Šù½¦ÿªáŸzJ¨÷ÝÂ|5ÕH¬8 ‹KK©òdMÜn·e÷®�2?¿ Ë++Y‹É�Oïz*iž±ÊÓˆµõ¦4mi4[æç†ÿ³ÙlÉæf[6›mÙl´¤ÙhK³Õý¾Ùó{«Õ–ÆfÃä­Vkþwb¾·×õ÷–¦ok^/�ù×nK«iÓ‰ù»Ì�Î×jE¤Zõ~ê§Z«ˆþOç¶~¯i*6�^7ßys]ÓxeT¤¢éCi›�Mi›S�µl“Ç/ÏÔ.×/Ó|'~º®òŒÔøujºjµmêÞ\_—…¥E¯�¶MZž¶ÕümËìê�_¿í‡¦M’Mä#ûl|ßýDT®ô£÷áç<áÖ2??Ÿ½ÀäÌ«?ÂM^__—V³YþÃ%è�°Ô{@½^5²V«ŠXÝ# ²eËr¡z0Íp�Z¤ik\ZÝ|Ö¹6jùH«7 i·«�žk‡tž§ûÜõàÆºêЦÔjs¥êA=Ýxn~>¢�ÎSÝV€ôtŸÕCm9°ºÏÔ§kº"õ ÕÉ.zPï;µzMj5OnÃúÜEæ�ßyó�‹|¤í‡Êô¿}òª@jþ“Ÿr»´Å˜ôã¬?þós?—¿ý§Ë"ý:ãùGÊ þšV 6ö4öt¦›AB¦Q¯‡Ò®#°§±§Ë�ƒ~eŽZ>²ô{:Jmœ×CIãëjO«o®ÞåWVÿ–úœ“|WImt}å#ÜŸq²V×Ô·Ü’F³üÜØlòfCŒßxS}Ïš¦Ñ”v»âù˜[mQwpÇ?ìù‹=ÿ±çKV{Ûø™Õ‡¬¾dko«¿z³!zB`µV7¾jõe–ñQ{º>7çû…;¾åX›Ú÷õÿs‚oÙøs5�ï«öüÒjO¯Êü\]——‚:#~íÀ_-RU‹Þäêî”Wi{>gãÏêñ|Öú�ñ…‡üÕ�½ìûœ›Í†Ô}{Úø¸}ßs¸ÌÅ…Z¸ )sœä#M‡Âþذ>ÌbWO²þèÇlR÷+âô¡ÙOU]W÷äÖî¯ÖÕ‡UÕ·V�nT¹¼X¬¬Mƒ|¤‘«¸´EËÇ�U÷Q­>T=¸ºÿ€Të žÜôö`íi �>ô|Év_5Ø[õudø{ë‡n¶EÚÁþªWöúÚšÙkVŸlÑŸîýÕ~~åv»)µjÍÌi»¿j~FtIgÓîkj{}h÷P#{Ÿ¾^³û¢ªË<åäïÉúºÍ׋žïØêÅÁú/Ї•Š´ZºNiËœ§GCû¸Vw–¹>Í:nÓ°Ÿ—Wï b7.úãß¾RÞð/WHE7eüþ䬳ž|ÓN€€Õiaú—‰À—¿õ{ùË“Î�äýèÛî-x‡ƒ2•Wf&5:òžvyÅOöÈcOöO”UO¥Òqüx~ç�1²Ìëî½ÀVcl©!Vý^mK]7õzÍ3ƬÃÒþ,p+U³XÔ ¡ xP¢fê¶D*�h”ð§ /ð¯Zi› 4ÈRO»ð\5zÕû�þlkZÿ»¶:½ì¿×æšå yÔ)VÑŸ+ïïÓò V‡œ-G/«¡é´&ã€SÇ›!6¨³åŒØ$TƒÈEÆiç—‡ „jªÅÝÔÑ8W¯ÈÜ\Mêµ¶,Ô«2¿P—¹¹Š,Ì鵪ÌÍUe~®jÒÍ›ï*27_3iõš½®²iŒR•e?¸]¯i°Ÿ~çoFÿž`e_¿o·š¦-Z� Ú:ê¦îªÌ׫R7m©ÊÊR±Ž›<³ãȇ}!’ýò3‘§¸¡ç-BØF¯­­I»Õ*?Xu­œ×† [š‡@|¹IÒƒ&ÜÞßÄ˪­Îów,†ªu^¨ƒ®R­úúOЃC—v*¤ç}]ãé¶áêÁ¶èú°%‹ ÞZÙ<,6þzÐê�"ôà¸ë�ÿÌUò¦¹<2…ÎxÁäÇÝÁ@{{Ú3¸½ö4·‹i#€=]̈±Ž(¦%ÙJÁžîp+Úž6¾¥ºï[¶¾¥p°«ÿ»±“ëþÁ ¾?JýÃÖÇlt�”gn þî<è®Þ[M<Øn‚«ž¯Øø‚=´ñýz€FÅUü¿õG ò4(Ó÷3«ïXË4ÅÊ0”Ö/Éó-w\Ë^ ¦—O7þãVË´I8Õ§l¾×€éuª9M g³åf°i30¿{�¦ú³éÿÔ¿×7R:­³‰¹&�€úhÕŸk}Çj[ÏÍWe®V‘yý©þfcg{iækæšIãÛ½ ‹5ï�qßOfeØú“Õ¿ìõ©Íøy>5•µ§¼ @sOð‚ÿ¬y~N:m ù—‹ L3|Ýú#�>w{: —pÚ]»vÊÂüBé~æAíËrrä~ºGóÜböYƒÃƒº÷VÍžª§ÓŒOÙ콈wà�}(Äß§Q?²î·xzÈÛcõö¼½o?µ£+5�Þ¤3û¡ö�p/Ag�Ø×›¾ò³;«�ïÙèEOy Ó£\սа}hÚä¥i©®õ•˜æóvyU¯E÷XM¹ú ƒf í±ªßÙêÆð˜&½~}c³ÙÑ} 1{¬aÝh÷Xí�%Yç3ù¦‹€±zû¦ÞOý§ºg~¾×§NgöSM:/¯þ­2©ò¬º¯VñöYkºî£ûTçÍÏÏùñ¾Þ3±žîµºoaÞ»Ox:¸ÓÖpî(õG½—4›ÆEüÇç~.oþ×Fš‹?9iô¸>«X�Õ‘§ß œùõßʱ/¼ ’æÿð'räm·ßy à–yŠiT}:LO+3°ŸË~ðyü‹¾Ý§ßá僚ÈMc°xIÅüí)Ö(±Î>cšøé�±c2úÎ9¿ÍÖñBóõ#²BH@�‹Æ¸3ÎPk€i ®güé5ݼXP£Ñ7ÌLzcV<£²^•ÅEïIPk¼™Ÿê@ å1†d­*ëM¹ü'»ÍFÀ?ÿç�jÚ–‹>ýP'ŠÓ¤?´Ãzb¶öiiyÙ©ÿYiùúäð¢ž<\¼®@fò@£&0 =¸oÿšüèçûÍ®CV=h¹M‚þxÿ'~*o}ÿ‘¡~ÝóŽ�ø¨‡¬ëÇžöôXOV�&0Šuötï„›„õP’˜ä³§ýÒÃ~eëC6q¢¾ý¯~c?˜Åx˜#Á ^ (~夑â: G xÛ ²íø�Õ?l‚‘ô!Sësû™õ;=)ÚÁ¿\©4eiq^66Z¹ýËÓ ?ºÇÜŒ·{—,..™7Ü�ê“õdîïÿð7òW/tÙgõ{¦{¥‘}Vï{ó]Û Û ?,¡�‡ üýX£íÞk¥sðΨàQ/ 0ö̘5ï�Ôª®èj(™×7™UB u:éÖƒ� Ýо¬êM ŠoëÛÌ!IEØ�ƒÀŽ›þøÀ§~†?yì%�Ž VÇe$hÇXøÌÙ¿‘ãN½(Ò¦ÿþçûÊá·Ú|§Á¢úŠàQ}Ô -*pç¢o~]Žû›=á³GGÕ-ê… 0Övl›—]{6zÚxƒƒäky�SÛ§I¬î× %‘å•§¾gM¤:O_9^ÖçÒo_ Oxåïуe¦\@`j¡Ƥè�÷ü¿+å]ÿ}"þ5Ï;R^rüm¦fLËèötT)€Àä(b�=�~`O§gF@eÈ«'ÅžNËPƒU—––Í!=£úèÛõ�¢,}ïÛß’c_y-þåQ õBcK ¯ÞKêØ¸éüÉI#Æut°Êl€@ ��}ñWò¬W}'rå‹ï»¿Üê¦^@Î�ÕÕRO’K­_ƒU«ú>”œŸýû÷Éϯü�¼é¿,×­n—Ÿ^Ó˜CïnÈY_yÙ'¡�ݽ7ïwÒwM•ˆ¥é—_ü‰„©ÝnH»Ý�JutOƦjoªÄ“0÷&¡�“-ªTO$}¦MT+ÕRõ¡>©›kežÞªcö“\*óÖ/¡“&pá×у…#I�“ c&¡�³¡µ—jLŠþøÇÿø‘üÓG:'ªkû_}òä¥O»íH¤mR*ÅžŽ‘ç±›÷ÉXùjcO—ß™„¹7 mœ�uöt:‰ÄžNà 9G¦™/E¦�„¹7 mœl=h[ïâ_ž${:�¤ìÙ³Û«ÎÍÍ¥ÉVhÚ<ÁªÚ�ŸþðRyÝ[ð/:(N…á_vÂ4ö‰&A×LB'Kºè½¤©;ŽúrÒ¨q¬2 CàCŸù…œ|Æ%‘+gÿû1rã,˜W—83hPÔ9;¿°�é ¿îr÷íÛ+µjM–ë{dÛy7•¯]õGòÄ�ÿMW² X€ qi¡¾!óµM™¯nÊ|­!sõ†,Ô6d®Ú�j¥%µj[j•–èë]ô÷j¥-µjKª•¦wÝüS¦M©UšR¯‹ù®*š·%uM[mÊœù½aÒè÷æŸý]Ë—¶y½‡~¼Þk?*U5ÎBßñ°þ‹±Ú-©×Z¢/ÑXYï§ÿ»¾~Ëü٪I«Um�´õw‘vµj¾3éüWsµZUSNëÿßÀoµ«ÒÖ<~Y­vE­¶4M©Õ¼`U-O˜´ö§æ7í©Šæ1m3ehy^;Í÷¦§ú»¶Cëõ_ÖöÚiÒØú[ZWÍ”¥D‚òµÏÚÓ^í«W¶h~ó}ۯ˲¨˜ï´í·Â÷ˆkj 8óôÆÅ{A‹fòFÇä5}òËV˜¥×N¯ÍÝá.ÃËã×á÷Í+[ëˆ ~¢|¦PtÐÍD®VdoAv Š æ>êðíòñwýIßö¶Z­©ÔeêCe¦ÁªeŸÞj$oãô £´¡уæî‰t”˜ŒÉ¦PZÖþ˜ýñŽþPÞû±+#ùšç!/yúáw6²aO‡Ç{:LƒuëÖCÐS¸ŽÀžN?o°§S0²ßlenUæë ã_ž«5d¡ª?7=ŸrÕó²ñ%«ß¸)Uãcö}Õ¶ñ;«¯¹VóüÊêkÖ¿ëµ¶Ô+ “¾^mJ]ýÏuõ/û>iý®Ú4>GãÉ5~dõyú¯™6’À‘iüÏ•Jž‘Ú÷sºù–õ~¿Ù¬­ñc¶<¿­ç3öü½­ŠïG6ßû>`ë/ö}¦�f[6›êC_0¾à|¾eßîû�ƒòŒS5­o9ì¯öûh|Ëž8êsö|¶�ØÚÔþk¿ ýÀïm}¾†¾ïòïøÄíwž>µ¾eßm}ýöšïŸç1~ßÇí9°­OÙ÷KvÈ¿ªÝWµ:ζU™ù:Ìäóô¿GÓß+õû§ßzûÔ�ýT»o,G¼Õˆ¿ÏêïËÚ}Q?¿WvøšÕ÷ÑýÙðÞjXïzc™p°ú°ÏÝ9ß>k’ÞKR ãª?ð''�×!Ð!@À*³1ÞûñŸÉKßô½È•s?ôYYlÈÖ­ÛFÆL_õ¡'«ºMI�Ô'Næês&ø¶ÒØ%Û¾qˆ\üëÛË_|øÍIYÇæúÊüªÌWÈâ\S–ê›2_ß”Åú†ù§aöwû÷’~7·.‹õMY¨¯‹þÝ�nqNóišpþuÙ¾è½ö:Ïg³U—F³*›Íšl6«R©Ö¤ÙªJCCÛÞÏà÷fUšíš4ýïÕxÐkæ»àw?�I—¿î¥m{éZM?�¦mÖ¤ÑÖ`N¿\S¦¦­IÛ/ß«¯Ó¾¦iŸW–ùiZ½<&]SÛæýnÛØh‰4 iWWÌ5Sf¨ŒV»Ì€Ä<£5%yÛ  ÚõÚ}›Ú¶µ�ÍÖ©é§R‡°çñ´&žoÐsÜÿN 8?HÚGÕö-HÏp÷JP£Ï†ö£ÑkûÁÓÆØ÷�|¿>¯ kžú�ÀÖœ•kKÈ>JÅ;ˆîq§ƒåƒoºWl“Ô‰µºº*õGö1œs˜›kff£;z=ˆ,K°GQ.z°õáêAÛˆ°ýQÖt(Z¼ù}WÈ>ùÓHs_uÒò²g°:h ±§ËšáÅ–‹=�=]쌚ÂÒXGŒÅ:{:½l½JjÁ¤ÚÓKõ5Y¨¯Êb½éûŠ­_y]ÔÇ\Û�…¹ ã?ž¯{?Íßú½þ=ò+ëï5M£y;׌/º¶.êo^š[OB9ðºõµªOY}Ëú�·õ'{?}®ï«5ß©ÿ×újÍa�tÖ?k|¹aÿ®þÝÐÀ•ºçSÊíø‰­Y}Í?±ï#¶~nõkÔoòs~íÀ‡.×k£õ-o6+²¹Ù©¯˜¾þóP_ð-çšVƒ3«4‡ „½»žØx~ƒC3üÀÙ.r'„ÅDÈvüÑ^t˜õ‡ÞCö7ûGEDì°×CþdãÇöÏ=0?5ˆLV—ŠñCûusÈ'­�Ø™ÑoOÛ¦ ò/O¢=í‚Xƒp5Xµˆ=O—úâÒ¤ VÕ½.}óeÜÛ/­>¼ðê;È£þãMY›3ô|[öËBmUkMYœÓ½SÝÝôuàºÑoÞ÷�=Õå°ÿ8¤/�T]èëOû·Ñƒš?‡.TàíCz{“þ~§î½aö-ýýG²³OiõKh�3¬›üýÒ`?Ô¿¶ÙªH³íí³j�©Ñi­ª9ìGua°—ÚµGjô•¶Çß»õtmHßùz¬£;:Ôèg[—öKõ~K¤ÙÜ”VekGš¶°¿ZªÀøÁ´bÞ§m mÛ<ïãĪ í£ÚæB µ;«žÓ<ÆÕQ¶dïzGï˜�Ó$o4½§ÅæJ´#ô)8}ÊpԟͦÈÚ†ÈÖÎ4ؤ½ë‹ÒVãÒdž�Ö Ôõ ΰs2dtÚt6x¶iœ¢6�Ö߈Œ1R�¡ V§¯¥Æø �~pn`øúư1’Ãi Í8gmÇ�®Ézs¾˜¡koš`U©L�€èSŠúIs²ªoØ€3NPßùœ…ëû(­Aç™q~uþ/öÔâ 0·§lÿð‚˜ºïÝ•÷œq�ž+zÏÕ“¹Ã÷Ûbؽ”²õ‡{KÜRêæÚ�«²¼¼<¹ì–3[*# (¾É…Ûу٦ʅì� =èéTôàtéA£oûØ©n‰ËÐo|Ï÷åÃÿý³Hí¬&ötFØÓÉógP Ö¬#°§Höt¾LŸÜØÓƒ±fµ§�XƒaÌé¢þï ~嚦ó}Ìúæ+=�TjŒ_YýÕõ YöƒdVæÖ|¿rȧ¬�£õ Ù²€_yШNª_yÿƼT*þÁ öp‡�oÙø™ý ÞÎÁŸqœo9päù¬íá �߸éáJ)¿�f=6ˆ)ð#Rxå…“‚À\?É f ù¶­¿:ìû•ðÊZk,ä¿Ί_Ù’²AIÞ´‘ ÜNà‘ïK¶�ºþþKO`n$ÈÖs@ë[×:¾ëtþåI¶§MD«?4X5.ø3ÿ$v+ammMæææœö]777MºAíuÝgÕ‡&T§©.T�¦JtëFýÛü«6Ìž«§½=Wý©ëIŸæÀžZ#ЇºŸjïÑ Qo_5ºÇjÒÌmHì³ÆÏ•IÓ‡«›‹fOs£¡û�ÑýÕ°ìÎz:Ã{H$ºj@ô�‹ ¨M>(Éìz{½�Ølào÷H}Ûcöqý™übl€²§— ÔÝÓaŠõa8k‚lCºÏ¾ÙÕKá \Uizö®9z¸s€‘~ãt”Gï%ݽ'AàONE®C C€€Ufb¼ùý?–3þéÁ•v»)}ú²²Tb”ထPçèÂÂb!¯Äصk§ Ví~ §RŸ½âOäÄÏž´ä�ov™|êɯH5Gü‡‡RåÉ’¸ÙòÖAã˜éÚ~ àT>ó%¿ÙdXc0¨ßÚW£Å97:ºñ¨�ÇöP·\î©´üjuôó%íØØ“pCMeýÛÈ Á“£ž¡¸ÙðqÍKQ›�Óz;NÛÀ᜶ë=1Ú9 8zʯ9Ø?ýÀžlOièuövŒà°Qjêl¶=¬ÌÎß°j�ÄZvçlX÷9ÐI™ï©¿~cø€{ÞPÞýš»÷4¨ß+‚²´ÿóHSOÎíå”gÝ®ÈæO]YØÓÞ�bO;µYG°ŽÀžÆž.ö®’\öt2#ìédFE¥@¢ÓêA%Ö÷ínÁßzOæÝØôß̦~å~AKæÔ?ÿ´ÁÐâ¼àÛÐɼ¡@({2opRaèЊà‰ðɼ~0oømná`¦ðçÔ¯Ü4¯Ûžï¼ÅN¶ ?™7Ÿ_ÙÎâ4þåI¶§Ýÿ¬þ(ꙥœ4Áª&X5é$XüËYF"]ô!úÐEš7‚Æœ¼>())�W÷Yõ„]Ýgµo@÷@^óÖS=ý·=òÚµ@[Š<Ü(�>L£÷’î“ ?ð''�"×!Ð!@À*³14XU7ÙŸK>÷p™«ÿØJ=Ò\ƒUõ)¿<}âd×ÎëÍë5âNúÛþµeù· $¯:ûÙA5¾í·ä�|âjž6ÍR^5¢Z-‘…|Ã8È´¯úq=EvCßìT+/˜TÛ£�Í“tïD t��Ì*6:NHß9êËF�­Ap¯ÿ* úQÃR_¡fO艜hà¿î,|r‚-ó²kn-Ÿøþ1=½Ø}o"o=íÎRÉ_Ô°ôGþ–z%”lÔ¯}æôÛõuYXX0'¹¢‹Éør²Êy¹­*§tô`9\§¹Ô¬ò1îz0Éþ(jLËÔ¯zÇ¥òÉ/ý2ÒÔÓOY\ †Wëˆá±ž–š²ÊǸ¯#F=>ØÓƒG{z¸34«œ·•ÅÔ†,†ã,•’G>ÖóÁ©}®o}³o†ÓŸm=8"dkdƒW�ÇŸÌëâ_ž{:nvë�QÍU V�ŸŸw:ÝUƒUõTÕz=ù$üËåŽhy/·eÅ—Ž>,žé´—è*6ç;§ë}ÜkÞbêï•v.ÒÓxíQýàãb1§Ý{±hÞïÿö0ù¯ËØ3iöU'IàOžvi£E `µHš”55^õÎËå�úI¤?—Ÿùˆ¡÷o˜ÎÑmÿwyë¹”·Ÿ÷„ Ÿ�»ã¹òÎG¾Ã©ßzš&�ñ¨4 Sù,ô¦w§Q¢´Á¡úº‘2ƒx•½žÚê<[6ä£?ÙI“�³~|yÚ§NïéУþìæò†ß©¬)”ºÜaê�Ô�‹ÉÐh4dsc£çôï"ÊîçÕ:àˢ-2irž‡z0žzpöôà°6×ÊÖ¯xëwå3g_ÀW>ç9õY¬ºWbO{t°§óhÔN^Öý9bO3Ç&¹”I“ìérf[Ùë¡îVë:{ºœ±Œ+uÒä<ìiìé´ógRå#IN‹=í¢?ÒŽyéõõ kjÒGÓj:×…ð/'Í~}Rå=K�чèôófÜå#Iï%õ7ÎþHÊSÆuWý¡þäOŸõ3©T;§˜áO.cD(s°: £H '𲿿LþåcWåêɪzÂê0?l4?¿`žòËóiµZ²óúëdeeKìɪ¶ì­çßZ^ùß“}·ÓϧÝùóò·~obõºxÖ`U=Å’O”€n éɪK ÓO&­u`à V-kÞ¬mzeÏ'?øê<8ÚÇ´Á¯ÈG¼“(g]yyÚ'{VŸøÈ[Ê«ž{”ó\*3á°õGÞ¾èFWcss ŽÊ[Gw~=�¯ûNèÁ¢){åM¢œg%�Œ'‡œ==èjd•5›oúãeoúŽ|á+¿Ž4õ´gß^N;ávy›?Õù±§½áÅžÎ?ÍYGôgˆ=�~Mz “(ØÓÅϺa¬‡°§‹7×'QÎ]ûÖ�{{:íÜ™dù¤_yâ‘Nûyiyu§ý‘·ióëi©êîö Ç•£§°ê[¹ôí\®üË®¤Ò¥›dyO×Sô!ú0휙ùÈkÆíç¥å”7}ýñâן/g~íšHÀ*þä¼#@þi%@Àê´Ž,ýÊEàù¯¿T¬ dN IDAT>ø©Ÿe,/Öä¢O?4W™®™777euu¿,..¥2„âÊO³Y¼õ‚#å9ÿù(ùÂïuò=ÿKN»ß‡6]Bsõò‚]¹�c:eÓhЬ,ŽcëŠm“>½¥AË®§ìX/7ˆW7ïôdÕÅÎÃK¹;Üj{E¤ °E>úcŸTùøß+ï.ÇòU=;þ±·–Sžy‡Üó,O£ÒyÚ¬†¦¶{qqô7Jô`ž‘ŒÏ;©rž…z°ÿ`�8]ò‘¤ÓØYdÍæ–þxáë¿-g}ã7‘¦žöìÛÉi'Ü>Oó§>/ö´7ÄØÓù¦:ëˆþü°§óÍ­iÈ=©ò‘´ŽåØ`Oç£�=��_\îI•ó,$°§±§ÓΛI—�¾úð1‡É3}hâá3iyu§–=�·�EçW]¯§¥º«jýi}ÖèâGÍ; �}Öx®Ø…ÅÏ·I+qRäcœí@—1O«?ô„sο² \ÒÌ<Vg~ ŽÀs^óùÏÏÿ*¸´}ëœ|óã.–nè†_;¡O5^ýµ²}ûA¹ƒUÕèÔ“U·lÙêtjÝ– ï"�ÿ×cåü_vN|ù}?$Ï»×'úö[ƒõôJ× ÅÂŽq�zºçfCdëÒ7² ¦©S1Í)¦ûˆl)‘‹ÎKi—ë‚ùèOi’åãì+ï&ýÉW÷tî¤'.'?ux§­�“þp‘‡¸4Ö9ª'‰»¼‚)k=®ùЃ®¤ÜÒM²œ»õ°“ =ØÇiÊ:±ïTšdù¤O|ÒmRÙieͦ¦þxîë.–/ŸM¤©§žp{y峇§ó³re>ìi�>ötöY8É÷É´½fÁ:"휙dùÀžN;ÚýÓs=äÒjìiJîi&YÎÝ{é¥D¢ÓΙi��~úðø¿¼‰<ÿ¯�pÚÏKËmötÖ6–‘O÷^õ´T×`Õv«%KËË©›‚>L�l`†i�wW"èCô¡ë\±é&I>ÆÅLËXÓgÑ/}óø“³À&ÏL `u&‡�N'xú+¾-ŸøÒÕA²¼ _ûȃ’²åº®ŽF Vݺu{ê§öº+Vå¹sçu²uË6gãvËÅ÷–¾ý©òãënwƃþEž~×/ôô«ÙÙ¹OdÇŠH½–«ÛS™YŸhÒÛÒÛ³ÇCŸlL3ö(7ˆWŸ(ÔùYf@lÒ !ƒ Mº|œó“»ÉqŸè X}ñÓŽ�g>þ6AçÛí¶q‚ ã3jý‘¥�ÚfÕUõzÝÉQ˜¥Ž´yЃi‰õO?érž†z°—zp6õà ÿúvòènKe¤‘5›vØúã9¯¾P¾váï"M=õ„ÛÉ+ŸÍ «ƒÆ{Ú£ƒ=�EÊ=[{:žöt¶95M¹&]>°§‹™�Ã^¹´{Ú…’[šI—s·^z©°§±§ÓÌM;-òÑO>ÿ)·‘ç<ùˆ´XœÓ�£þpn|Ž„iƒ�šÍ†9å6Ë}˜…Z|ži‘w"èCô¡Ë< §™4ùpµÓr(;}Vý�?¹ì‘¡üi"@Àê4�&})ŒÀ“_z¡|îË�“tnrÃ%9ûß�)¬üî‚Òž†:¨!z,ùî];eÛö¢§Ö¹~–/}¸ÜåµO‘ël²¼íaï”cïtN¤}-ú5;EÝ.27%ÁªXQÔ)±ã|ü¾Ž]š×Ù»Î×t»÷‹l_qM�>�«n6G(Œ| ·i��~†Õ©Ï>RþúQ‡‰ªêé§.Ok§Ÿå1†{ÊÓ´ËÐiû¡|ÔÐSFÃâäÒFô  ¥ä4Ó çɽ̖=˜�Û¨s±NŒŽ@?=xò“o.Ï|ü©ì�´c; ýñŒÓ¾%ßü¦žòÌÛÉé'°:hü°§=:ØÓi¥|¼_÷ˆ=�~<ÓæÀžÆžÆžN–šQ¬‡’[%‚=íB)9 ötFØÓÉógS`OÇ�J’¹Œ±WýQF_Ãe¦ 6ÚÜÜ�­[·enú03ºHFô!ú�8„þs`åcz/ïÝ(�þÀŸœ—>ùg‰«³4ÚôÕ™Àã_x�üÏפ¿åMVäÌ÷ßß9š„j(î¼þ:Y^^ÉôЉp]6XuûŽƒdnn.M3déÒÇÈa§>]D:'¾÷Q'�¸ýy‘rt‘xðÖt¯€ïnȨ7zÂíIûš…AP5XRŸ„[r�N5FyéÊÒŽ]û½yËú¬®{››e{ðµ°f!ýQN‹|œó“»ÊqŸxMOG_uÒQrì#nnV‡„9.ú#­mllHµZ5§«ŽÓ=˜4¦EÎó“è-=èN•u¢;«¢R¦Y'öÓƒ¯xöä)�ºuQMŠ-gúã¸SΗ‹¾w]¤=§<ãp9ý¤òN½)â� Çžö@cO§›p¬#úóbá>—XG¸³**eëìi÷ÑÅzÈ¥uØÓ.”§A¢ñ+O¿_Ùöp�ù‰~Ëü7”˜ÆU”ÒY¿P=(H?.¾úµµ5Y__“íÛwäjú0>“}ˆ>DNŸ>…ÞËs7Ê«?ð'ç¡OÞY#@Àê¬�8ýu"ð¨çž/çžÿû ímo¹U>ûžû:åM“H›öïß'õZ]—–ÒdíI«ç¾½{DƒU] °îÖ.<^îò꿊|ý‘¿z�ÜÿÖß ¾Ó À¹z¾“UÓ8²sqȼ¶)²˜.®·o©¨ª}[(¨<‡æ;'Iû:‰ÿ�½ëw¢ØÂÿí¹½péí¢ØEA±"‚(vylØATPìbElˆ½ bÃŽŠ…¢(RìEElô^no¹ý}'Kn²Ù$;³»I6ÉÙïã{Ï›™Ù™Îì?çì¿g„(H/‹*kBŸYµ¶^RGòâõýXZ W÷ÅïÞ©ì]ãöÇéÇv›ÓNü!³îêêê\e7±*��yPf&µeci�›CB]›yPMÞ'ÊáeEiÙ}b ¼çšð¿ã»ZÑ%¿mDŠ?Îÿ ~YYªêÓÄK÷Àí,X :×ìO+ð°?-þHà}„¬x!nCT’÷rxYQÚª}ûÓb³©ý�HïØŸA)>âfæ�`Ú̉ṽVZŸX[²<èn5Ü~µ�ùC iùR”è�.Jš w‘XÕé¬E^^¾^QÝß™u! Z€ýBö ù=klîÃÍ{fžDVðÇ“ÍÌ×�7X°o3ÎãB`ØåßàëežL:ûöÌŬ'Žª+SÈY[‹Ô´4!§)X»äpÖTW¹Äª"˜¿¶6/‡!÷§úéÃóo@¿Î¹þfVÜI/ZZZ€$}ÿPBÃeiÓ›‘f¸ºª"��BfJÖôDÝ õ‹üòä¤P´®ß&Ý¿Ú d›Ób½Í#ý+4~J‹þ@Jðú R¬­�@ŽÕ½×õÂð¡Ý¬Åš"vâÑQð�„ªv«Ò˜EgR[.ÖÖ¹q$´<Ì<(†&ïÅp²²”Ñ}b œ2¡NÜÙÊ.¶¶Iþ8sÜWXño¹j\,XÕŸfö§ŒØŸÖ·*Áûÿ8±?-f?nâx“8^V”´zÁþ´þ¬Dr?¤ß;ö§E0 T†y�y�ãÊñWv�4œ~µÝùÃÌó3àsµ¹ ®záS[S�ü‚6zE…~çø²L~ 122Æ.†“÷Œ?…HSa p<ÙÌ,pÝxC€«ñ6ã<^!†\ô~øÝ“I§÷ÞùxsÚaBuE ‘#äp8D‹,gÕ׿ͽ#žP�ñó‹ÇbŸvëLg©°ÛWqUµ@†HÔ÷W…æÇè—´B�,i玼u Ö‰‚ýÁ@BUµÍ5’EÕÌ~½Îëâ‰�hÆÌúørM_œÿŽ6ÃêÔ›úbØÀ޽0^Ônü!2Ø&§¤ØV¬Jc`™Iÿe˜µ¸0ŠÛó 8VV•Œ&Œ4œ~åRü½¦Bý„‹÷À¤«÷¶j:b²ö§•ieZ̼yÁû36ó>Bl�YY*šöþÆÍþ´•Öài‹ýiã¸222^?±º>Â_Ž´?müÉh¼¦¬ØˆååNäÛÓßæÞ‚O®ú3û…bó«ë]lôþKq|Y=ö ű²ª¤Œ_.Þ336+ùƒãÉff‚ëÆ,X�·çñ !päyK°ü/O&�ƒö/Àk*TW¤eDMMMúÂ/X{äp646 ;Û|zÉ/ß{W½°�êv_�…¢ü­"C X†6Ô´QLK1ÕŒiѬûî$Vu¤Z—uÔj'ʬø‘Æ)³I47+��(+æVóÇ“ÍÌ×�7X°o3ÎãBà�³aåªÊÖ²‡ö)Ä‹Sª«W¨±±Ñ’ s5ÕÕ®[edfêÝRè÷^{ ·¾Q¤*ûËU¢]–'Ó¬PC^…hÓÓÐ8LŠUÉY¡Ó;Ì|mLݪ¬Òm,V%¬R’dQV—'Ìé_j²¹vŒÖ¶*hìþ$V¥¹lŸg´—ö¨ÇëCnì²>¯éƒsß¹[Óùgïî�£ú·“”di»òG°aÐ Áääd$%™|¸Ibe¤8ó Ä-Àªõȱš1å èS(Þ!É’væ�@C©¯¯wý¬ üIB&]œyP2«žã☻K2ª1c·¡hâA;ñÇЋ¾ÄÆmj躋zâ.¬5>ö§xØŸöo&¼�ð� ûÓâœf• ñ>BóhÚGøûÓâsm´$ûÓâÈYõ cZsö§ýcÅ<(nCVñ ûŽ¡Œ/ÛÉŸGØ\É––áÓ,I¬ZQQ†‚‚BK QÏiŸA§aRr!æCñ¹d>d¿PÜZB[`>Ÿ £|JÞï½¶d¨øƒãÉff…ëÆ,X�·çñ !°ß‰ŸcÃÖÚÖ²ƒë€'n?H¨n¨ ‘X5%%©©©–ÞêÉ'_ÃÓs Tm®�0)I�Ò÷!Gƒ6-f…“õ»nm¶+ŪôµV]�‘& KÀ µu@jŠ9¡§ÑM¢u£}K$Ò)«:©Í4ô7¶ø¼>äµÛúttÅ«Š~ûÛÛ8CÅþf´¡¡Á%Tý²]Î*BSšyP WæA1œBQŠyP�*ïÅ­ÌÊ}b¨yÐnüqÌÈ/°u‡SöµÇí+>qX’ýieÒÙŸÖ?ï#"÷@à}ï#ŒZ_4í#ŒŽQ¤ûÓÁQbZÄŠ”S±8®,†•Õ¥˜™�Ú”•<èîC¨üj»ùÓF1—©gDl”Ÿß))&�…ÜÕIo±*ý‰ùPlö˜Åp E)æCæC£ve†CÅ{FÇBõBÉO633\7Þ`Áj¼Í8�W�=Žû ÛvÖµ–6°#¦ÞÔW¨n( Qp455Í2gÊ»¯<ü6^ù"«õO hÆÆO“‰ñêê�t“‚N Þµp˜ô­«Òf¬Ú äfJð9)Éæ2ÈÒ×_ÍÍæ³Ùzw’æÑL¶WëRZ"ÜK«�ÎÑŸY•ׇ¸uØq}|¹¦/Îçê¿3§†¾ûæ‹.Ì%CɾC‰tpÔhöæA}£dÔÇ(T%˜ÕÈò>QÜÒ¬Þ'†’íÈÏû;J<~!!?näî¸÷¬³Bö§i§Èþ´¯�ð>BüÙmuIÞGð>¨MEÓ>ÂèEê±?­�ûÓú1êcª̃̃FmËj¤~Ð{—Åk)¾|§¦[fâËvô§�âŠz”Yµ¼¼$Vµ*PSSêœNWfU÷Å|¨?{̇ú…ªó!ó¡QÛ2ˇJ<Ù?ïõÙ;×Ö‰oŒðÇ“�Z׋GX°�³ÎcÖE è˜ù()oh-wÊ1�qÿÄ>ºõBY ¦ºiGÈŽV¾íÞÙxÿk�:4;µ]7BzH5@N†t5U!�Ó¬èÕJ±*mÆ*k€‚lscó®MΉUÍd�¥ìbä0+ìõîµGR¼µϺ�K¶är¢ª€ÎmìÓ'É!´çõ!Žœ]×ÇÂÕ}qÁ»ZÁê›�†ÞûØS°jþðžÕHGëêê�–fì‹ æÁàë“yPüùeuIæAm0‘÷‰bVŠ}b¨xЮüqøˆ(-¯W>ndOÜ{Í>b“§¥ØŸØŸV?ï#"÷0à}ï#ŒZ_4í#ŒŽQ¤ûÓ"(ìO³?íF€ãÊbkÆH)Ž+‹£f׸²{}, X5_¶«?->c¡-Iñâ²²äææÃápXr3gm-šš›�™éID 322Z²Ä‚6Â|(ޱ]ø0�`õ•ú£ÿíÄæ’FùƒãÉaž(¾]T#À‚Õ¨ž>î|¨èxÄ\T×6µ6?ü¸®¸÷ÚBu;Ývkkj\bÕP­<î¶�ñùω­})Ì(Ãò±#uûæ]€ŽkÏ3™}ÔÙ45™&ýF«¦¥šË\êéiÜ&Û:Á$õ/9ٜД„½t¥™ÌBë;É-$Xµ‘Xµ¤è\h¯Œ¯R cWa^â¨Ùy}|±ª/FÎÒ~ øöc‡£×žy⃠SÉpð‡{(���.ž %Wƒ�ÆêHOG‚Áó``t™ô`ý܆‚J̃`xŸ(n‹¡Ú'†‚íÌÎü UžiÆ]°;î½–3¬³Fö§ö§=Âûñg·Õ%y¡F”÷âMûñQÉ—dZ3ö§ÙŸv#Àqeñu#S’ãÊâhÙ9®ì^ʇ ÖÄ—íìO‹ÏZèJ¶Š�rò\qc+.ú˜¥¾¡yyÚä̇̇̇V¬²Àm0Šãk'> È{�†^{Ù3�þàx²¸�rIF€«lŒ€Úò é@zåqRwLºjÿˆ`E©Æ­úê/Ø.¾~¾ÿÓS¢[î6|{ÅåÂc¦Mbv:�äѼ ×u¤—õ æ3´Z)V¥>QfÕ¶¹Òà X�įÉI@†±$€®v©_¤)µZ¬jÝ(Í·DóXRt‰±*¯1›°ûúøbÕA9‹2¬ª¯÷ž<ûìž#6È0• Ðp"¥#ÓÓ3L‰e™ý&ó`˜¬ŸÛ0ªAá}¢¸-†rŸh5Ú�?úŸ¯ú�‘faìù»còu,X f‘ìOìO+Âûñg·Õ%yÁû£6Mû£c©Çþ´Jž2ìO³?-g1¡/Í<ÈYåWÛÝŸ6:VÕ#.§Ìª9Ù¹ÈÈ4™igW§‚‰U©ó!ó¡UökU;̇̇FmÉJ>´Š÷ŒŽE¶žYþàx²,â\>ž`Áj<Ï>�= 9}¬úmäi=pÓhù—’ÍÍÍ®LoF²½µ´´ ¾¾ÞðÑÆ²Ó{æ•s±b�G¤»gáz|yéÕBÍІ7=ͼXµ¶ÈWŸ !tw!:R…Ä¥Ô—Ôd©ª~ 76å»2«šoMi�Äx”ü�Ä‹F¯Úz¥ ‡Å™U�ö'õÜNTç6æì*}“m“ׇ8bѰ>¾XÕ#gMÒ jöÓGbÏÖ V£‰?ššš\<‰ÌªÄ•n±jRR’¸±ù)yæ•ó°bMsë/̃ó )“2U™yP ÈxŸ(fR¡Þ'ZɃÑÀž6uun Y¸ú¼ÝpßøýÄ&$NK±? ð>‚÷‘\þ¼�à}„Qû‹¦}D°1²?-fìO«q⸲˜ÝDC)æAæA£vjt÷Ë ¿:üi£ó¬q—ÈûVÊŒWZZŒ¬¬l×?+.ʼ^WçDn^~À>p|Y‹4Ç—­°>cm02³Àj>´‚÷ŒŽÅ]/œüÁñd³³Åõã ¬ÆÓlóX…¨ohFá€9ª²—ž±®¿t¡úîBfF"MªŸLgƇá¢{�xégX¿Íó2¶wû1÷¢ëuïn•�Ú)4¡õ¢ â¶2 M¶5bUxe­9a©/x$Æ£~æ™ø˜“Ä ‰ö«Ò)ý«Á‹l¡¸Rɬj&c¯ÁÛ[Z�ׇ8œÑ²>ü×½w»f`={zv·&ømüI±jUU%222aV¬J:ì¢yXÇ<¨²mæAñg˜wIæÃâ6o«xÁû#¶oûˆ`™ÙcD"Ëþ´5I8®,öäาNv)Åþ´øLD ºGd6¾l†ëÄQ5ïO›½—w}Q¡Õq‹Ué4®ÜÜÁqV’ýieÂÙŸ¶öãÏhzNšYò¼�à}„û‰¦õaÅ>"FìO‹Y�ì~H¤Uö§Õ(±?-b5ìOC‰ýiqŠ&t�Ê F“?->‹Ö•t‹UŽtäåå[Ò°³¶Ng-òò tÛc>d>Ô5�ì²_(`&š"væC3¼g #u¬äŽ'™®¯°`5^gžÇ�’²z þTõû¸‘{âŠsöB�‚£ôµFJŠýÏk÷vn÷;aZZæÿ3—~p‹f€óf B÷Žâ÷S2ZùÃÔ  T¦—kee%(((´L¬JÝ`ôLó ÃÀ<èÁ�yP܆â�#ýrM†?ššZÐë$õ‡Œ4³W�»¦\¿Ÿø$ÇYIö§• gÚ:Ã�¶ç¤Ñ‘ó>‚÷Fl'ÚÖûÓÊ,GÓ~HÔ.ÙŸfZÔV•cd4bCÑÆƒî1åÃXä#ó¨Ž[l”–š†ü‚6–4-#Våø²rŽ/3AæCæC#–cw>4Ê{F°0RÇJþpÇ“[šë��˜ÖÚŽ'™®°`5f™Ç(…ÀÖ�uØó¸ÏTuÆ_¼7.;kwÝv\bÕÔÔTݲ‘.@Y\) ,ý««oÆ�§ÎSuiðî?âÕ3îñÛMʈJ‚N³™U‹+€Î&ýÆme@^¦ubÕj§"ĵê"碤è¤ÿñeÀ[FƒX•²¿R¶]#e9¥#©H¬Ú¥Ð\†VÑûÓ¼ÐeF`è^¼>DgAwEÛú˜û÷¡¸|¶6ûô§3¡« Áj´ò‡øl[S’D½¥¥ÅÈË+°ôÃæAÏü0³UæAñâ6o<è툣dMI#üá�¨7cÎé�&p†Õ@3Ãþ´‚ ûÓÖ¬Ýh|N9ï#xaÄn¢q}°? DÛ~HÄ6ÙŸfZÄN‚•ad4bCÑȃîqáÃXä#ó¨Ž[l”š’Š‚6…–4MmÖÖT eV¥22š5<æCæC#6 |h„÷Œ`a¤ŽÕüA\Ðçä�€f'’³[»Äñd#³Ãuâ¬ÆÃ,ó¥X·¹½NþBUç†Qûâ¢Ó{m‡ÄFô…£Ãa¡ÚQªçâ…}�ÛâÒ:yîçªNØó<úýª¿QÖ²j 7SÉLiô¢ÍÓŽ2 Ss¢WD8R­«ÒØÜ"�cóÆ„ŽmØNã,Œ¶I)üS“ÅÇHYUé23?2óJ¸QöØ,‡±1î(Wæ�þ·kÛðˆUkë´é¶�ðáõ!c9@´®�9†Q³oÒ vÁËÇ s{c©™£™?äfÝ\iâX:~)55ÍR±*õŠy®,ë̃ò6Ê<èÁŒyPÎ~â�#ùrÍ(ÔÔ6¡ßðùš‰õ}º IDAT3b7<0‘3¬²xö§dØŸ–{&ú+­ÏI™‘ó>‚÷2ö ñ&ö§=ɌνÑzF÷C"÷cšýi;ñW†y�yШíDû>Q–£ÑŸ�[+²Æ’؈NSINJveVMLL½}ÀrtÂW}}²²”å=ìÊeåµ8ôÌO��¤>‘“ãÉ"³Êeâ¬Æã¬ó˜ƒ"ðïºj4|¡ªÌ­cöÃy§¬G{àH7&V ç”øsn×nªÆ —-Ruãô}ãÉ“§ªþFÇ»RfU3bH«’ˆ“2«šÉÐÚØäÒ"Å¢£ãÍ|¹æoþH8Jãl—g/#bUÚÌ›ÁUÖÉ&r ž‚¾³ 167+bUæ†ú¢L®�Í@v–*¯ñÙ‹æõññÊÃqÅG7jûÅ+Ç c;yÊvþŸus%‰»«Pe0ÿo]N¹b)ó …Bþh^ç2ÖÊ<èA‹yPÜr¢y}áÁH¾\3ÃÕ�pƧš‰½bD<8‘3¬²xö§dØŸ&²?m +ö§µ¸q¼IÜ–"o2²�6*ö§ÅæÜÌ~HäìOW±mö§ÙŸ6b9ÑìO»Ç+ÇÑêO‹Ì-ñ8]ÉÉÆ_ ¹3ã%%%¡M›¶–ˆU©_„{JJŠë„Jы߳2ŠÚŠo9æCæC#¶M|(Ã{"XØ™?Ê+ëqÄ9 5üÁñd‘™å2ñˆ VãqÖyÌAøó¿J 8[-Þ¼cl/œ}B7¿õ(3‰UÓ3 ªöÂ8---~¬?þ-ÇYã¾Rõäì^Ÿã‘oýÞ(¦Y±ê¶R%³ª¡)mÂÌôÃr«ƒŠÔ>e ÍÏ’-Ôê™IS³òåY¸îGý¡l»y™z=óÿ{i°½\×v-Ï kìnJ-šç†F%C°Õ¯9D£y}ÌþóH\õñDÍ€¿|m0ÚÊeØŽþ�›yã¥ékI <†â¢/æWü[Žó&üÀ�~M&š÷½zkÀý;û…ìŠÚJ4û…¢¼'‚…Ýù£²ª‰ãÉ"Ée�]°`•M�ðAà—•åxþÕ_ï¹®7þ7´‹«h:Æ9ØDÿø[1.¼ñ;U‘‘}æbÊqϺþFG¨SöK3™;)h²¥Dɬj&“f4ˆU)h–é07N™…iu¶YŒK*�¼,cÂarÀ¶•)u)³ª#Ef´ÆÊÒ1×t4‚Q�m°»òú�›“h_ïý1ãæ\¯ô¢×‡ ]�xD&VøCnöíWšœÛ¦ÆFüñ_-ó …ÓíëœyPΘåðŠöõaÊ¡™Ò;KëpÔ¹Ÿkn>úìxèΰhVØŸV�aÚøº�öç$ï#äæž÷rxEûú°jÁþ´œÝ„ª4ûÓ¡«Fû:g”[q̃rxÅÊúxÅ@ŒýÄ||Y=û”vó‡™$@n±*�Š2«šÉÒêF†2öQFU#bUjƒß³Zkc±²Þƒ¡ÂïY=è0Ê­Ÿh[Vñ^4ðÇ“ål™K3,Xe`|øþ·R{±:Ûèýûà”c:«J’óB_Ò±v¿¨Ÿt:¾bÉ�ÛqŤUø¬ßG¸kð ¨kP²vš«n.VĪi&ࢯYÍôÃwž(Xz*ábÝ ’0’’†C„I½&L蟰÷èë•ù”Á–L©¸RÉkd.ªj�M%á«Ò=I¬J}¶úâõ!‡h,¬��þˆküV—¾1mòÅ«±Är`¯ÒäÜÖ××!++̃ÖÍM,¬sæAq{`ÇŠJÆÂúåA=ÿC¹È”Þ¶Ó‰A|¡¹ùågaê�½"Ó©(¸+ûÓÊ$±?mÌXcá9Éûñ¹ç}„8Vñ¶�† ûÓrvªÒìO+bUŽ+«-ŒãÊr+ŽyP¯XÚ'¾·âhŒûd¼w|9üé@³ëÍrà)MbÕÒÒb×ûNʬjÅ;ZÊFN—Q±*Õåø²ÑÕÖ‹¥õî~ϪF…ùPníDãúÐã=¢…?8ž,2›\†ð À‚U¶FÀ�¥?ãÄÑߨþúðM}qÂÀŽ­#ç…œF+¾Ú³Ã,øz ®¹w™ª+W2 ×þª%bÕM;�Nm” ž]. *’xÖˆè2Ð(‹,94NÊzJ/ªBy‘“®‹î#Òž™#8¼Åª] Co$䥯Ìè*̱~&¬r¢x}X?7Ô¢ˆ=ËÜÙÝÞì?�Áµs¯ÕTýú­c‘Ÿ«ÿ�‹5þ�ÁÐNe)°Y[[ƒ¼¼|W·˜­™æÁà82jñ!›a´fýù¶bW ÍhCÓê¦mµ8ö¢…šÆ/?»¦r†Õ€ ³?­@Ãþ´üºä}ï#d­†÷²ˆ‰—·ë>‚ýiñ9 eIö§±*Ç•ÕV&òÜา3Ž+Ë=¥bmŸøîïæâËrèÙ§´/é™;³*½ŸÍÏoƒ´4±ÁîEÃ$&&ºþ™¹8¾l=OÝX[ïþPa>d>4ºZ¢u}˜å½hâŽ'µn®¯°`5^gžÇ�/¾Ý�Ó¯þNõûc·õű‡+‚Õææf×ÿšu^ì4/Ü„úUÕ¥qfb‘ï˜tÒÆiãN c>�é°Ïˆéë# *Z)(¥ \c#�ž¦-©�³”Z�aKYP­Ê¬*Ò§me@A¶1�lm°a§r—®mÃ#VݰÈÍ MfUŸ„Âfϼ>D¬ÎX™P®�·Œñó®Ñtì›·‡"/'x éXäc3ÙZþœ[æAósÂ<CæA->̃æ×] ìʃ¡qhZ^·¥Ã.ùRÓøågaêMœa5êìO+Ȱ?-·.yÁû9‹x!‹˜xy»î#ØŸŸÃP–dZ95�ãÊòVÆqefW–³ŸXÜ'š‰/Ë¡gŸÒV‹�òò àp˜éHû úgEr"Ž/›··X\ᄄ02])Ѽ>Ìð^´ñÇ“�Z8׋WX°¯3ÏãˆÀ¼¥Ûpöµ?¨~êÎ~tHû˜EmÖ¼ ˜ôøožñ5×câÀ·pía³ �Ùýò }��n¸Ë+RP15Řè2Pgš[ú*š2«RVO3"F‘×Ö+¥Â™±vk©"ü¤€¬ìEý%ñh ‰U � ó½êv�„Òy™@Vl�ÆCBa3óÌëCw õúxë·!¸~Þ8Mÿ¾}w(r³ ,Ã#åŠFp:�p:k[3«ºÛ`4‚¦×¶�y0(€ÌƒZx˜Í­¹`µ™­Ãv͆*œ8j±¦ÁËÏ(ÂÔ›Y°iö§é+Wö§eV"ûÓÁÑâ}ï#b)ÞÄþ´ÌÓÑ~eÙŸVĪW–·MŽ+{0㸲œýÄê>1Þø0ÈXƒwfÕÜœ<¤gdÈT÷[Öê�a8¾lnJbu½{£Â|È|ht•Dûú0Ê{ÑÈO6jå\/^`Áj¼Î<�; ~±Üð“ê÷é÷Œ#úµ�YÔf~¸÷=»Âk|-¸õèWpå!ï³[„Ð.È1ï7ꃿJt/­ÎJJ�¦p‰GC-Bð‡Û–]bU‡-Ù‰Ui3Ý¥�ñL»TŸ2ÊŠ\äôQfÕPÌ ÙP†C¼/þúËëCd�• Çúxãס˜øéÕš~?ë8dg&ë8× Áœ[æAsSÀ<?æA-6̃æÖ[°Ú̃ÖbûïÚJœ:f Zšë‘�˜ÚÚø¥gtÇ´›°öf1ÔûÓ4™ìO˘4ï#x!c/¼��AK®,ï#äðŠ·ÒìOW6fõWöàÆqeyŠÕ}b<Å—­ådç"#3SÞ˜üÔ Áª•'ir|ÙÜ´Äêzw£Â|È|hf…Dûú0Â{ÑÊîx²ï|s<ÙÌ àº±Œ Vcyvyl†xwþ&\zë2UÝSÁ€>…†Ú³º’Õ_ýQÿ^xgyé/UWï8æEŒêÿ¡t÷éåÁ¦�@‡|ãâDé› T €PJ²± ¡Áš¯o´^è~®—-@z2”z;QyÆîIØP¦S:¦ s�ñl§2Yk˪• ®V‹’ �š:¥Ýä$ƒ P„ׇqìôj†k}Ìüõ8ÜøéUšîüðÞqÈʰ·`5ü¡7/vù]Ϲe4>S̃�±cÔbÃ^ìOkO*q£Æþ´¾ý*Á<È<(c=̃2hÉ• º{Eñå>9 )ªŽFC|YY½x¬H[Þ™U³²²Aÿ¬¸ZZZ�� ˜!Eð†Ì‡‚@ù)Æ|È|(c=̇2hÉ• ʾW�fþ xòÿ®^ªžãÉr¶È¥ã¬ÆÏ\óHxýã s篪ү=t(Ú_í< 6gi±¦¦&�#•œl\EmÐWƒÞÎØ“3ÿÁÓ¯ÿ«êë=CžÃ%Í‘ê?m7 B“ÝRª3^…IhHGÙ›9ÂÝß½IHIY?-öký“°m!±ª'¹“Q8„êÑ½è‹¿Ü cÂc©W("OÊ´›•.t[M!™¯Æ¬8R)P/kI¬jÒ†x}³‘Zá\¯,†[\@в{@1Tü!2?‘.㬭E]}rsóv…yÐØ,1Æ�yP‹ ó ±u&RËî<èÏÿW¤Ëüôû\0~‰J¬J}ºdxw𨪪e &V¥;1šÇ;”-„{�ÓX˜ÕÏYæÁPZ¸¹¶Ã½>dy0�ÿanÔ¡­íæ�å•`Ô¤š›]<¼;cÁjÀI`Z�†ýéЮS™ÖÃýœä}„zvØŸ–±Öð— ÷ú�ÝG„íÙŸf:\ÉBeïá^ç̃̃¡²åP´©õ1û¯ã0y©þ ^ÑìO‹ÄcƒÍ©·X5/7ŽtƒQBa8ÚäørÁ6p«H­w~ϪLû…Œ6ŒUB½>ȼýóÑšy¿W•yŸggþøõ¯Rœ{Ý7O£ýò­¢¬F÷üqïC€Àso¯ÁÄÿPµüîãG`¿=rCp7±&)8Zçt"#3S¬‚ŸRäàQfÕ”­štò3+ðúGkUµ>þ œÓ{�Ðýh#³­èÔFöÙá¢/¹©_T”› ÂÍ-ÒÉ5`nôµWI%�Ÿ8ë�eV¥>T;•Ì®áÈ^ !:Š„„·f²óòú�³A™Ò¡v¢|ûB¶ùÈ¢c1õÛK��¤^ ÞŽäèyk‡+Ôüa‡1úëÍAIñN¤9ÈÎÎÑí&ó .D+‰uÎ<è™næÁˆ™¾Ð�#±>DxÐÝù`þ‡Ð#PÈ›?þY׈ &~«éÅEûáñ[{G wÑqKö§•ybÚö‰ç$ï#xaë×ïE$Ö‡È>‚ýiý¹ u ö§•S®8®,oiWVcÆþ´¼ …³F$xнOœµòdLúârÍp½ãËÑîO‹ÄcÍ·[¬J¿çå -M0«I8 ÈϽ8¾á rûH®w~Ï 0ÚwmPϱ>^ü)8ïÉúvæ�Ÿÿ(áx²½Mž{g3X°j³ áîD�'f®Â­ÓþTudöÓGaÏÙé‰�ª««�“c\0[S]�䔤¦ú?OþöGÃ{ŸnP�oÚ �â¬^ uÇL™�å@‡|%›¦.ʶÙÐh¯L¯Fp©kšÃœYuS±"ò-0`î„;eVm“­ÛcTäé«ÁÌÊ:”)–³FÇáÞèóú°rV\ë#ïe¦'I¿Ïó7B»ðÇ“Åí�K2„ VÙ¦½üîxb¥ê¯s¦D�®b¢+¥@meE9rró ‹Ÿ*++àp¤uì&>ð æ,Ú¬êú'MÅðým)›&‰UCq»,i3O¡Ôd#µíS'\›DïSP‘pkkPM¶`Dèê݇š: ÃÌ’à–Īfìš×GèÖS$×Ǭ¿Nǽ‹.öPLKiq=«“’"¯Þ„n–�·\VZ‚´4Ò32„a†*l#¹Î™•O˜ÃfîÒ7ŠäúƃYÊ\Äÿ�t*øòÇ7¿ìÀe·ü ¹óÈÓºáÉÛ9Ãj )aZA†ýé0,Ú ·ˆäs’÷¼�ˆ¬õëß=’ëƒýiýù‰t ö§9®lÔ9®ìAŽýi£Vžz‘äA÷>ñ™ïÇ—[šjtßç…)¹»áß;¸ÅF_'±jrrt½äãø²œÍ„£´Ö»ì8ù=«1~Ï*kAâåù>‚ñ^c]…ôû<;óÇ“Åm�K2„ VÙ|áÜûÌߪ¿Îqºu¾X*‰�ÊËJ‘›—oXüD9uz⩱÷üŒ/¾Ùªêö3§<ˆSöù*àPh“X^ ´Ï³b´ÖµAbÕPgz5“=Td¤áÜ$ºûCAEÊ$Jâc#WY5�§>!]º»ˆU¥;+PôßF¤×ÇÓßÇäEi:÷Õ›ƒ�›�¦û¼ 2ž–ÃÉî»666ºÆN_¿Gò*//s9·‡Cª̃Rp™Ê¢-r§H¯s‘>ú–aT#ÂãägI¿Ï³3p<ÙÈÓ�ëÄ3,X�çÙç±ûE€Äªô’ÍûZøê`th+'~1¯[lD™UÍ|EHÇ8‰ˆ‡Fßö–þ¼CÕå†OÁ°=¾õ; šTÕ…9fFi}]Ê®j&#¦H�B¸¬oT¾äg–Q *’ƬS�Ú25@ŽI=wm�nƒÌªÆÐ:Q¼>¬@RÛ†ÖÇÓßý“_¨éÜ·oFnNøx"Âáæê‰“ÒÒ¬[ÀÍÍÍ.îá/oª««�œœb¨/̃âk–y�yPÏZxŸ¨‡�ñßí̃?¾<è'Qÿ#øãËï·áª;ÒLØù§vÅÓ“úŸÈ¯Éþ´2ÁìOû7tÞGð>BïÈû=„Œÿnç}ûÓìO·lëjr\Ù–W6†[ Z̃ÖâéÝšxÐÝŸ@ñe÷‡ "(ÄB<Ö=NwfÕ”ääå>mR·P–¹üÖïðõ²bÕ-Ø/d¿PÔæø=«)æCQË‘/ >œòù xâ»3‘�ÒFÕá¯ß„ü<ã;òÇ“åm’kÄ7,X�ïùçÑûAàŽ'V‚Ž1ô¾–¼1…ùÖƒo•ØHtré¥ò¿Å²¥ª*/ÿïÛS›Qˆ6‰ÎzóÙ4Eû'Z.AEÚÄ¥†ð’†& ®ÈJµùrTliº¨?jn¸²È6ÙßX«òú6©‚vYO~{¦,©é»L@Qjà…#ÁuN'Òiqi aÑH°š’’"1rE4KÇEÉÖsßdä ßá§ßÕEæAí0j1aÔ™¥_Â…c‰ÉÿˆþøâÛ­{÷Ïš9:ï”®xæ¬2^ö§dxÁû‘<ï#xáF ^öÙìO{l>ZöC"Ï2ö§EPâe�‹¡¡”bdŒ7t�× Æn±QZjšë´IÙ2ÏœP–mhhÀȉßbùß•ªÛ°_È~¡ˆÝ12Æ:¾ôó xæ—+4ËÁÌ{U»òÇ“Ežz\†ð À‚U¶FÀ�[§ý‰'f®Rýõ›·‡"/GNB„!y!‚’±2±´�0†€~-ö§ÙŸ6Õ·,¥ó ó ˆ­0Š d¬Œ�xÐ=£ñåhò§EfË-6r8Ò‘““ÕbÕ’’�¸úÞ±â?µ`•ýBö õÖÇ—9¾ûÅ÷ÿ9}u�f9¬Ú™?8ž¬÷Ôãß5,Xe‹`|¸á¡?ðì[kT5J˜2àº3ãeçäÎ's?*[UU‰ŒŒLüïê¯ñ÷µPçõ3ïÀÑ»ýÒÚ$Mš›íul{8Ī”¹•¾€w„P¯L¢Ñòj  [v�•w‹UI|ܵ-�”(ßNm½‚‰±jM�žÄÅò”¬ÁëC0‰âv[Ó¾>užeŽ•‹F’?(«©�Áé¬Eff–ts”‘ÕL?ȹ=cì×Xµ¡VuoæAæAÿ&É<¨Æ…yPúÑ%\!ÖxÐí˜yn{ƒJþ˜¿d3ÆOñøCîûž{RW<{gX dÄìO+Èð>‚÷Áô¼�à}D¼î³ÙŸVl?šöCz›Vö§ƒ#Äþ4ûÓzkˆ~gZ%ceìæO»Ga”c�?ÊÊJ\±à¬,k_Œ™�ËX[}}=JK‹‘“�‹s'üÌïY€Ç|È|(²®˜EP2V&Ò|øø·Ö½Wu‹UíÊO6f£\+~`ÁjüÎ=�<×Mù /ÎZ§úõ—‡!-ÕQŽ¿ÛFBlTQQîr“’’pÊKðß:õ—o�};Ž,Zîê. 6Iä˜BѦ¬A†C¬J¸ú†ÐŠtÉQ+­ÚXë“„Ó-V¥9íZ$'É"¯d›MN4'V�¥Ìª¼>ämH´†×ÇÔ¯ÎÁ#_Ÿ£Â÷³ŽCvf²èÐ,+iþ°b 4Êö���cEsRm¸�ÛË&ý�Uë«Uu™•,Ü̃Z“bTcÂ<(õØ‘*k<èíH p¨ùc΢͘ø VeçŠýi1ÞGð>"ÐÚá}ï#�xÝg³? DÛ~(Ø>€ýé໤x]çz{GæAæÁxæA÷ìáÃXä�ì¬ddZ{ä Å è�g8.«’è6''‡ƒß³ŠÝp|Ù/2̇̇ñćFxÏßÂqûvæŽ'‡ƒ�ù±„ Vci6y,– pÕÝËñÚ‡ëUm­˜{¢©L’Á:*±Q ¯éïåeHKs´»|Ò¨ÅX½¡JÕÍwG܊úÿ:2¥@Jx|sñ¾Î¡Ã<È<È<è±Q>ŒfZ„?Ìð o]â&«Í®J¼JñéÄDý“6I¬JI�òò \÷t__æø²ˆM32Æ#Šò^ 5ä눬5Ñ2VóÇ“E‘çrŒ€‚ VÙ.¹ef}º©õ¯©©‰øõÃa–âäú*²¢ õª/ðŒÜ¤±±Ñ儹Å>�޼p‰™�˜ˆÜÜ<Õ­Ž»øKlØZ£úÛìónDÿ.+�t)ªëPP±®Èòóq§³pX¤G+«ò¬=í$(î$Vmn:µ‰œ¹¦HMŽ^±ªŽdT/Ž]/×â}}Ü·h$žúþ ÍT~óöPäåXô€b(vã£6M�½ššj—XU$hô>þêùûžyЃó •Ö¦n‹y0t؆«e^€ ó?ŒÎY8ùã½Ï6âöiË5]qbL¿›3¬šCö§dØŸÖZûÓFŸ|J=ÞG˜Ãϵy!·�Åœ±?mUö§ƒcÈëܼ�j�y0t؆«e^¤Eüêh÷§}íÊXe{N§Ó%õ�Ê´MïXé©O㨪¬@n^¾FËñeŽ/ËØ�Ѳ̇F‘³O½xäCÞ 4CÑÆO¶ÏZãžD,X�Žyâ^†� nø ~±¥õŽ™éIøñýã-ë+QR¼ô¿ùm ñçî9®zb*S[[ãºgVV¶f,ƒ/\ˆ-ÛkUÿøü èÛùËÆ Õ5 �þŪµõ@zª5£¨¬²­=í$hÇH¬JeV5r}ÿ¯“Þi‹·¤âÐ=kñøÅÛÐ&»Iª)Â/%)zŪ”™–²-Ç[¶aïIæõ¡ qï—ᙆkìÿ›·ŽE^®E‰«ËŽü!õ ØU¸²²õuu.Ôã/#í«CÎ-e6§ ¢w’yPA�×¹ëaT2´3ò>Q†õü#Ï÷póǬy0éñß4]qBL¿‡«�æ�ýiö§ÕÂþ4ûÓ¼�à}„Ì>ÂÈ>A¯ûÓzéÿÎþtpŒØŸf:�…°?Íñ&_ÛЋ/Ç‚?í=æ@ü¡Ï<ú%œµµHNI›úk�N1£+%E?…ëÚê*ääæù�is|™ãËÁ,–ãË_Žç÷/z¼híD#pÿ³Ü>šš•&í&ü£l/õ @N†åCV5Xí ýшÞ7$±*aÝ!ßø¸z]ß;*=G›\rtî;w‡pƒ„mrbt‹U[(h‘$Bì‰ WŠýi9¼|K³??^çìOB€ÄªìOó{_ûÐãÃXð§ÝcÆæ˜ ±jRr²�ØÔß½èhŠ‹ˆU©¬ÓY«9½Ò»]Ž/s|9˜M³_È|ÏûE=Þó·v¢•?Üñdß1q<Ù,ësýXE€«±:³<.Ãüoì÷XðÍöÖú…ùiXòúK«ååehnjrev WV9Ç’#H¬J=êÜϱ³´N…Ùü ¯E¯« ãMkëJÁ‹bÕ´ 0ÇølT9Ðs\OUýw¯ÅÇ7nj”² �`69 bO¡I"»hnÇÅ+Ó1þ•öhhLÀÕÇ—bÔ�2ÉÖ¢³¸ìú0ŠS$^>Yw|q^øéÍd.}cÚä§…l’íÊ2¦ bEe¹K¬*rÄ’LÛzeõ¾€gd dC̃̃¾{ìO+ø°?-³ÊÅÊFËsÒ{4¼�à}„ˆ?]Y›ˆÙ?faö�Ùøok*h¯Q˜Ý„Cz:qÖa´_�î"‰–õÁþ´îT,©ýuˆýéàó&²Î�ϼ§f´¬sæAW|×ÇúÉøì÷Lüðo:þØ�†M%ɨkLl-#µÙMèѶ‡ìQ‹Á½ªq`‘ú½•¿õmë#æå$ë¾Ï“y¦Ø™?dÆá[Ö¬Xµ±±ÑÕ¤HŒšx°®Î‰ììà/Ú8¾ÌñeŽ/ûG€ùPˇ;*’°|]ÖnOÅêm)X³=Û+’QéLù‡ô¯±9Ä‹{uªÇÄS‹qLû…²~ žÿagþ xò=Oÿ¡é"Ç“ÍÌ×�eX°˳Ëc3„À)c¾Å¢v¶ÖíÐÖ�…¯ 6-X­ªª9Ayy&R]JŽHôeña# ¬\�ýiÁÅã°o»µ’w Oqú2Ù*d¸‚ŠUµ@Vzxðii6—i@¾ÿ¤ºRpkw¬Ýádœ9 O\²M· «Ò<Ù-›®nÇw 'Šl-=ø{s*N¼¿+ªœžÚôQ[pJ¿*ÑæÂV.’ëÃ(NÑ´>nÿürÌøùdÍ|.~}Ú„F°jgþ5lr0�’š*ôÕºh»"åèÞµµ5A¿€g ýGÑ´Î}íŠy�yÐýQÓÜe™ÿj{”ÕÈ}‰óðùÛpþQYÑ´>ôxPÔÿy~S™HòÇËïýƒžý Éê õ™ÃºàÅ{BÜ•cZ™rö§­5ýhzNò>BA€ýiíKI«‚ö7¿ÙÛÊ=§Úø–;¾Ož¹l+ÒS)GŸöЦõ¡·�°öÉ¡´Æþ´9TÙŸŽÇ•õí‹ýiö§Ýþôä÷ÚàÉOóÑ"y”aïîN×G 'ä?M<è^1�øðËW!+£9hòýUç)IZ„?dÆâ]¶¶¦Æ•Y55ÕØig--- "I…(³jccƒÐœp|™ãËÁlšù�ùÐ͇Ï|–‡{Þ+Ds‹øÑ¾”á·©«Q�¹ëÛ(ó eüÀhç�™®Å}ϮМØÅñd£¬Ïõb¬Æú óø¤vù7øzYqk½®2ðéŒA¦«ä@546 ''Wº?F+444¸¾úËÊòd ÔÖ€3?CEUƒêç…—\�½Ú®7zû�Õ#$eE´â¢`Áž›iEk�ÛgЄzAbÕ,‡uÎá²5i¸þÕöX·#‡ï]ƒGFnGÛœ¦  ÑÑÉQœYµ¾hhTާ'9nr7×WßÞWQa=¾¾w�­¹‘\Fqжõqë‚ÑxyÙ‰û_ôú´ �`Õîü!òô¤�5((r¼’H{2eD¿€g”AU¾l´­sß22’Müµ)ƒï醦fm0qÏŽu¸o º·m@SS~X•Žy¿d¶Ûf7âÇ)káð#4‰¶õŒó³…ý‘'I¤ùã¥÷þÂc¯nÐtõÌã»àÅÉ,X 4‡ìO+Ȱ?-²ÊÅÊDÛs’÷ûÓ€H¼é‘9xðÃ6B á¸ÞUxåª-š²Ñ¶>ØŸšnU¡Hï‡D2ʱ?-?¯25¢m�32’ øòà7§cøÔ.2¦¯);¤W5¹ ír=ï%¢u}âùÓ ¨«ØÞ@Ìhà½1øû�bå‰IIHK Mâï{R\™NÌt¤‹e¢a>42£âu¢u½»GÈñeŽ/»m¡ÿÍEØP,'tÈv4aÙk‘�î_°j÷õ!êоÏrxJ†‹?^™½÷?³@3=\Åñd#³Æuâ¬ÆÃ,ó¥8öâ¯ðýožc;{tÉÄœéG¬:�N×x"ÂQ©Ž)LÇaÔ7Ô dûŸ�êZµqÑ¥Wa�BÏ ÚæE¸—"—Pʪ!¹Ú©©S²]&ˆtðþ•µe"uÑdiGw5FíÓ}²Ó­é³^é~[Ë€œtEh©+Ī”!Á-d~eq.n|½�_8ÝYVy}"8yƒ­ëãæO¯À«¿ž ±‡/gFû6Ö.¼hào («^R’š$š››AÿDŽW}f.ô½ÞWðäÜ64Ô }Ï<(о\¹h]çr£Ô–f4‹ ±ú¡Þ'Îú.WÏè éÜÄSŠqýI%š¿¿¸0·¾åÙ?,¸m=zuóe­ë#Îápäe'ûÑÀïÌߎ‡^X©™Û3ŽëŒ÷õ5f¨qP‹ýie’ÙŸ6oìÑúœ4;rÞG˜EÐXýPï#|{õؼ|Lù Põçíê1ô€jtmÓˆíåI˜±(OuÊˇ7à�=œ®:Ѻ>ØŸlŸìO[»2µÂ½Îeúæ¯l´®s³ãf4‹ ±ú¡^Ÿþš‰ Ÿîä·s}º;qî‘.n+«IÄ[R±l�«¶i³gR‰·®ÛŒî… QýÞÅJ>Œfþ�µV%$&Âá°6ï¯W¦K&‹+Ç—egT¬<ó¡Nv+E1ò{Vÿ:„1ÏwÀ?j“�µÏmÄŃÊP˜¥Ök�&â ÝœØ»³ú¤Ühò ExOæ}ž¬½‡“?žû/<2ã/$$ªEÉO–�5./°`5^fšÇ)ŒÀÑ,Ų?ËZËïQ”�ÙOeH$IYNéäôŒ áû›-XYYrRóòò…›ê{ú|8�ê ÐâË®DÏ6[Û  1©‹¾Êp‰ˆU˪ý±lfÕâÊ$ü🕵‰Èr4£0§ {v¬G^€ün±j¸0ÛZ äféAæiKi2þÝ’‚íÉÈIoFï"'Ú{}•l¤¯“Þ)ÄÌ%¹¸ì˜2\wR±KÔLG,Y™Ž­¥ÉHKiqaµWÇzt*h4r‹°Õ!'ªÚ äï:ùµ®!ßRðx¾ƒ{Öâ£6ºÄÔ�Ö‡7>· W²7×7ÇÇ_{%• øiM:¶—™ÇÛÈúÅÉ{"í¸>D íÆùWbæòã5E¾:ÚZ,‹þÐÃŒ2«&è|e RÆ}¿Ry_a¬o?d¿€gÔ›IåwæAÿ81Æ–V'⢧:áûÿÔ™5æß²}Šú)Ïa o_œJ«Q¸¬˜[§Åw®Ã^�ꃮ#ó&RGo}ˆ´á.sÃü«ðúòã4U>åtj'v<�Þý¢‰?ôÆ¢÷»¨U¯ïß)¨HíÊ Å<È<È<¨[È<¨Ïƒ/,ÌÅm^™SçÞ´}wS²�¹/ú¸éìG;aÙ/,ºc�ëKø`ûD™g�LÙpðà‚—¡sûð}¤þ˜þÖxô•¿5Pÿï¸Îx‰3¬4Aö§hØŸV›ûÓ�ŸÚìOÇ—?]åLÀ‘wtÇ–R%xCbÕ÷'lDßÚ�_è÷KŸíˆ9Ë”/j/\Š»ÎÚ0Þ$³7�)Ž}ûÓ23â)Žý�HÏØŸfšýiö§éY!Wîws6î:yŸÎuøòŽõ7ëw$cìKT�žsx9¦]¸]äeºŒ•<èîL8âËÁnþ™œºº:8�µHKMƒ#ÝšØ{°û666ºÞ­ê%Kð×ó!ó!ó!ó¡ ö¿¹vqá{×`ÖxE“!rE[|9ïµÍO–~Ÿ'‚Q¤øãÅw×pô?ãKü½Æ#$<`¯<¼õèáÒ8ù;ŠCº‰ 5ÕÕhhlp‰Ue¯ýOœƒfŸRé[Qþ&W¶IÂKÙ{-_^­ˆU“µÚG¡&ŸœŸ�ûg·AcsàÔ¬W_‚Ûve¾ô×èÃàáOÚèÞ/5¹—.Øc‹U¢GwEz1±Ç¸Ý]Y4:æ7àûÉë�š¬ ëÞi–¯s =­Ù%¶¥`P^\™M}/š×ÛÞjë:J.ØEG |rã—àVöê4º§+£ªÌuèž5xíêÍÈrxÆOã:øÖ"— 63­+§­Še)=åÁ.øu­’ÕÒ-‘釻,‰tÇö^054n+¦� ø½ñ±vG ®Í“Aì’Ae¸ïœok>îXÝž»Ý�Š ÉŠUepºçì®L0$®×µ£<ðú0Ò‡ 󮯛¿ ÕTýì¥AèÒÁ¡N4ñ‡ Ýuhœ •ýZ�êS½DïôC»5ú<ó ó ó ó (ÒG@gOëÒúø›=aìé¬~÷�×½Úk¶{Ž/¿ µ³O^²g ¨ h$ÛÊ’pþ“�°£"÷Ÿ³ö¬æ}„‡²?­¿É`Z#w Ž+s\YÄZ8® ˆúÓn<Ï{¼¾øC g¤6cõ“ÚLdÞØ×Ö'à¬i�ñã*E°HI8¾º{vï d Õeu\ÙÝÏpÄ—a.ÚŠ9¡Œ{¥¥ÅÈÉÎ Ë)–Ä�tù‹9‹Œ‡ãË_æø2Ç—Eù�NòÚçºÝZLM8¹N.yÔDe|9ïÍ}þHtnŸnèa0°"ÉO2c.Ä´"À‚U6FÀ�O[ˆU<™ûî_€™jkœH S[[ƒœœ\CýÜwØM½//ƒüÔMhk¬ICýð­DG““XÕŸSä/-ÊÅÍox²c®Ó‚¿¦­F^¦ö™—åâ&¡6<­Ú·/]¹ŽTµUÙ€îÞZð£6ààž�ÃÜe™˜6·ÿlNÅž�êñܨ­Ø­�'èBÍIoâÕ%¹­ѽ:Õá�ë6¡}n“fxt¬e,}ç[¯”¡A€;s@ž¸d›¦ ‡Oí‚·¤ºŽçñÍHkäÝäð½jðîu›Z3­Îû%?Ó©õþ?L^ƒnA²¾R–ž‡>ò‰ß¿~#Û«VÄ4Te(¨X\ tÌWW}ó«—àÄ}õÛ­ŸÜ´$<î=q7T×))s3š°üÁ5šùv׳ ŸPµGín/Ò’åŪTW§œŒ&,¾c :æË‹´¥'uWš×Ü ã‚w÷½~îX¼õû±šŸæÏ„n­¬¯‘zfùÃÈ=©GéÞ‡"8—¹èKw úéït%''Ë4ç*Ë<È\°<<åyþøE[qÖa�?dôæÃhô ñÞœéG¢GW1 ƒèã9ÒüÁñdÑ™ârŒ€‚ VÙö?és¬ßâ½Ò»/݈mq"�NMM5²³s\GUÈ^MM-èuÒ\Ÿj-˜ÁèÕi‹ls–•/©²3Œ‹UI¬ÙkBì¬T„KYŽ&œp`5è®DIlðɲ,Ô7&‚2£þñðäøEý™�síäʈê¾Î:´7�JT›°³" ?¯vàß³ðÉϤ>ð”»ô˜2L¡ÍºÙ÷Æ"lÞuôÛ]gîÀèc•cïŸþ4w¿×V…_Ÿ"'æÝ¼4­ô’ë§:aá ­s~zÿJ¦¥cúVmódG{íªÍ8¶wµë(ß±3Úá½ï=jîFoÁIy23»Ûñu:‚áóÙ¯™xú³ÀøP]«Û£uBÇe¤ˤ 'êïµ/·Ã[ßxpz~ÔœÜO‹“eŽ] ѸHðN£DùÇbÐ;oÿ>DSfî G£¨stÏÜ�7ËFç�‚£t”Sf¦¼j‹œMªúËdæ xæAæAæAæA\¾6 ÇÝ×­õ8s¬òáÐÿ¦vFE­ÿ#(ÓÛ˜!Å8¶·Óµ¯ õ«<nþ ìªôU¼ï5|HG¼ü@¿POcÔ¶Ïþ4MûÓ„ûÓÊ2fZÁ�ýi`Æ—¹¸åMOŒfÖø�8boý�n›Ô¿›¼EmýgKõæÁ“肟W+YVéýÃkc7[N ¡ô§Ý��D|9Üþ´™‰¡¾ï@VfvÔˆU™™™™Eù�xæ’g;bÞ/ž÷cï^·GîÜ7Œf¿0\¼gþàx²™×�GX°�³ÎcŠÀ^Ç/À–ž¬—‡ÔÏß{°-Q#â­®®2œY•ÕØØ‚Nö¬¶4a騫°[�õ¿�t4;eVM•O’×ÚüŽŠ$ôš@éô•kú¨-8ÅG(·µ4 Ÿ,ËÆ�=œ8h7ÏœSyʆzä¤î­‚WúÛÇ–âÎ3wj†@›Ä%:0ö¥Ž(®rwº‹îX�½;׫Ê�z®>ú9Ûõ·s/Ç´ ·cÉŸé8ûÑÎ*a¬»eä:¡o5&¼Ö3—úOw›˜Ð‚_\ƒv^YVwV&aÀ­E¨r**Ì‚Ì&ÊÑ»î8cÆ Uï‘ôêù=y0üñèËcúÛÿi¦`8gX j–ìO“^•ýiö§=Ë„ýiö§ÝÖpêƒ]ðýŠÈ¦[a¾Ÿ¼V÷CŠ?”×m”0RX®XÜGX œ™}‰™¾˜¹/ûÓrÈs\™ãÊzÃqesqåÇçåã>/Áê¢;ÖiÞ£Ðøòà•/´Çû?(™Øútwbþ­rïôæ•~%ºïîø²QÓòã IDATù#Ð\P_ËJK�æp ++Œ ãR†ãË_æø2Ç—EâËt’êõ¯¶Ã»ßég=bïÂjìØŸV#Êþ4ûÓWÖÚ€^¼”ãÊ€¯`uþ-ëѧ¨N¦?<èîl8ãË‘ò§�L ql�Ó‰æ–fC's¹§Uu˜™™™Ež'³ÌÂÏ{’%éÕ3´·œ¾Óõ1E¸>b †š÷ìÄOÖ³jþ�P#À‚U¶FÀ�®硼Ês¬ø�Ã:à±Ûò:ì=ò�µ´´ ¼¬YÙ9¦Å;´ñØï­`õ«Q£Ñ#Ì‚U«’ÐÌaR¬JG¶o.n§æýê�‘XnXŸj ?¤GïWƒÔdÿÙ;ëÐkB�Öc]»¶iÀ‚ÛÖ#/³Y5ù$z¬­SŽw_?ãIãߧȉù·¨¿òõÎ"JBÒ³­ÀË‹ó\ÕÛf7âë{ÖaÆ¢\Ü?[9'ËÑ ºO}£’)õ°=k0kü&$&CïíŠßÖ;\¿ð¨2N†:àS‰žeu�æŸz}ûÉx¼¿âhM±ÙO…={Ø_°j%xƒ@ÁϤ$ÿGaS9Wp”>²ÈÍÓýÈ‚ÊÒån�2ÁP¿SS•g•Õó QæA5&̃̃Þ±pEÎ}¬s럈ÿ�ܧßþ“zž¸¯Æf ´2_ÿ“‰O—{2pwÊoÀw“×܇}ÆE+Ú™?|~%^~_+X=mpG¼ú ý>h4j;V×cZA”ýiö§Ýk‹÷¼� [øñ?N~Ðǘrîv\|´ç£cßg±¿x“ÕÏkïö¢uJLüµÍþ´ö§ÙŸæ¸²Úôâ¥îÒñWö¬Îž°öôœ€ç�•÷îîNíW‰çF)'·™½ÂŃî~Z_¶³?-;'$6ª¯¯wÅÍ$葽¯Uå™™™™Ež's~ÎÄ¥ÏyÞƒ«Cš†'.ÞŠ�ûV«t"÷1Z&T|hïù—ÝøƒãÉF­�ëÅ+,X�×™çqD ÃásQãôdá6°#¦ÞÔ×VˆÑ‘é™HKód˜4ÓÁ}‡i«_�…¢|k~‘¾‘/# H7©Gjj6ùY@cs"(øóÓj­*�Ä¡£�-Ã…Ë‘�®¢~ýW:þ÷ˆç¸÷i#·áœ#*Tà ‰³^›�Ò;ƒj‡¼FüúàU=ï,¢¾¸ÜwÎv\2¨KW¦ãÌižû{—ûôÖõèÝ]ùÚø‚';bÁoŠ‚2±¾z•’—Ž•ïK�Öj$"=µ%º6¸2ÌW&aáŠL<6¯ëv(¢ÖÌ´f|}÷ZtÈWg ¥@P·+{¶f�}æÒÍ8©_5R¼tiï솿7+¶8þÄbÜpj‰ëÿS¦ËÄ ÝÇL/|ªc«pƒ²Ç¾6v³«ü/kÓ0ì>OÆ2ﱺC_V�žÞsñ_½'T-bf.ñïör Cžçx :JaÁo™øks*VoKÅÜ_²P]§„e®ÓûWâ™Ëµk&>�Úö‡�÷ú0Óe ¾oÄf×úÈ–«†'¬ý•%Ûð¶K³íªõÇ×ãƒ?j~~ÿ©#±÷núÇx„ª_¢íZÍ"÷u‹U³srƒŠZýµå›iUä~FÊ0222Š>;>ø! c^ð| ïïƒß}¢wæ{ºÏkWo²<Ëj,ò`¤ùãþçþÄ«³Õ{yš¿S�éˆ×bÁj 5Ãþ´‚ ûÓìO“°?-Ê®@¬ûÓþ”…ÑÓ=û‡çFmÁ©ýªü(Þ$ަ|ÉXÜGÈ£ _ƒýiÿ±?Íþ4ûÓìOë?AÕ%|«o]» G﫜Dˆ?þ) —{qé]gîp½ß±â ºûŽør¤ýiÙyq‹UeëÙ©<ó!ó!ó!ó¡Þ3‰Þ³^ü´:Éù‡ï¥p`Jr 2R[\ïò÷îT‡ä¤fäxÕkÞôï¡âÃPòžÝøƒãɦÍ�ˆ3X°gÎÃÕG Í!Ÿ ¡Ñ“é”c:ãþ‰}t+’¨†®PýW^^†Ô”T¤gX·C‰¤#ålʪ€Ü ­°QtŸ´Ñ#±jA¶GŒGÖ�ÎÂË‹òZ�µ÷®Ö1¿/�Ù¢:ræÝo³1ö%åhzº~{h5Úåz„œ´a«oP²Áú^OÌÏÇä÷•ì¨yMøëQuV&ßÀŠ»> hœ²ŽÔTÑQòãvo‰ºËôíQ‹¹7{޹™øZ»ÖãgIˆ8s—ðsÁo¸àIOæ/ý‰-¨ÞÚ)pkQkßݳEí=ˆéoåÕÇ—à¶áÅ.±*}‰å›Á³¾1û�ï�J§¢x½þÄbLÜ%p­¬MÄ×ìÞz¯g.Û‚Óö¼À!Ü×mOÆÀ»ŠZ�Ñ;°È Ê*rQ°«¤h—§iÝרíñîwæ…†4ß+YíÊ<ë}ùÃ'P}ñ¹fX1.>ºDµ>Ì´wéÑŸéôi±*õ7Ô8‰Ì¡Ê\õÑÌ^y”¦+³ž8ûöÌ5ÔÅhæ½Sp´¢¼Ì•Y5XV½vBý;ó ó ó ó èsæÅ…¹¸õ­v­ÅŸ½| Në¯Þ¯øîio·ç5»£¹EÙ€L8©NQ>ð‰¶+<è;ðÇägVàõ�ÖjºwêàŽx�3¬4]ö§hÂ%XeZÁ›ýi€ýi¸¨ã vò§½OÛ!›}ü¢­8ë0õ -ô÷`ñ¦hÛ3øëo(öìOGÞ2ØŸfšýiö§eŸD¾‚Õ÷ÆoÄá{×äAg}޹»Vï:).-ø~òZtk«~O!Û�H•z�Åþ´ ¶vÉôÝ»,ó!ó!ó!ó¡ÈóC9™Ó[þnòZµmPU�5¿0T¼gGþàx²È*à2Œ€¬²50>äô±ê/ÇvÁ½×õŠ“ïñÅ¡µ²²Â%ˆÍÌô+jŽö;aŽêÓP½`#ñ¨·˜�„v ”ìªf.Ú¼mÚ ´É œ9rýŽdÌû5 ü˜�_×zÔ¦™Møêžµ(ÈRDÇo“�k^öV7?û/w‰Ý›DGªz,î¾_1½fÿ¤dÿ¤¯Ÿݹ^5,ßcïÝ?Þpj1ÆŸè.PæÏ�jPn>}'®VÚÚÞmoâ……ù®ÿö¬úö?®É‰-¸ïÜy”ÿ£è|³Í®ú?ͶÞÊQCJqÃÉ;ÑÜ¢Í>Kýð}I3÷æõèÛCÉK×�7aK©’õõºJpãiÅ®ÿïÆýž÷ÚâåÅy­åß¾n#îS«k:dkeÕ@;?zÂ#&uÇ[M¦öÝÕƒ�nØ€ƒ{zŽ/¢?ûâs÷Y;ýö—ÖÇ›_å`ÂÌö­¿?ùz > Nµ>DÛó‡÷¬ñëqÄÞ¼u�ó*jœdúɲc>šˆ�V©éÂ;��ý÷�¬F;› wp”2«&''GrÚtïÍ<È<È<È<¨û ØUàŽw ñÜçÊþËŵc7aH/å+ø@ûÄòšDìuínÁêÈ£Êðàù;Doi«rVó ¿ÁÙ…?î~ê¼õÉ:MO9¦f>ÔßVób§Î°?­ÌF(«ìOìO«ýEö§=O?»ûÓ¾ÚÝûz?¿õâMvzÖí‹Õûö§�΄µõØŸfšýiö§eŸ*¾‚ÕOnÜ€ÞENW’ï]ny³-f|éy'pÒA•xatøN”Ÿ^y«ùÐû~vñ§õ0pÿÞØØhû¸±èX˜™™™Ež¾ïðÿytr2<ŠcÑ/ ïÙ•?8ž,² ¸ #àA€«l Œ€��-(8ä&g ë†;Çõ ˆS¸‚£ÕÕU {åäÈ ¢ô&¹×IsÑÔäÉ*Kå¿5=ò•#æCqц‹Äªíóüg*•¹'‰7îTĈ”Ɋıé©êq¹Ûýly&.}¶#šá€÷2ßþ“ŽÓöa¸ìþ5èTÐÊàJGú¥${Ž“÷îç¦âd>©;œ ŠºõÜ#ÊñÈÈíª¡ø{ÁF¢Ñ_\ƒ¶9ž,®7¿Ñ/-òa°ë«áî^_ ‹ V‹ ë±±$�Í^iEÑâzÞrúNô. ,`œõ]6®žáïú¬uG7ü³E×^8°7�ºÓuä¼ïUR•ˆAwuǶrE¸v@7'>»M�uÜKíñηÊWx½»9ñém\¸×5mvà”»´fWÝ¿k>¿]-ög7d”ñÕ_Ÿ¨ü 3ÛâÕ%ÞX{Z¡¬©Çõ©v‰�é8ï̬Tê÷õixÅ«îÄSŠqýIêŒiÞø\vL)îá_°ê‹Ï^�˜{óM&_£íí×ʼn/&‰e£õ‡£NC¨FÏuÈÍhÖd™ÁIfÍG²ìÞ€�ÿ:BÓ…·¦ŽööoG�ú üllåe¥®Ìªv«Ò˜™Ù2ó ó ¯m\üLGÌûųѡkývwÝ'>:7÷ÏV2ðÓuÞå˜ê³GŒ$·ÉÜÛJôw_âF»ðÇ��ÿŽwæi÷š§Ó3ê'[Ü”eÚ3ÕìO³?MÖÀûÞG¸Ÿ Ë×¥á¸ÉÝZûv©ÃÂIŽÑ‹7Å ‘X¹�`Ú>VÁþ4ûÓìOs\Yö‰ä+X�wózWüÝß{—isòñÀ‡:#µKîZ‡.m¢3»*ae%zco'ZÄ&(Kz¨O¬ g?˜™™™Ež9ý”…QÓ;¶ýýáÕ­ú€Xõ ­æ=;óÇ“EV—a<°`•­�ðB ÖÙ„ö‡ÏUarîÉÝqÛ•ûûÅ)\ÁQʬš��€¬,%s§Õ×'Ͻ\ô¾–Ž�ÝB$X¥ ׆�@a�l¨¢c$!ãæ C�¾+!é‡?eaÌó�—ÑŒOnÚ€ÝÚ«Sé»Û>~rWüºNÉ´záQex`W¦«Úúôš°ªœŠðôÎ3vàò!e ácr�¢œf¯ºJªqΣ�±|W{ôã‡7à�=ÔÙ6?ù9 —=÷ö¾^Žªúÿ»í½·¯ç½t$€HBh!4iR¥Š‚ „" ½) ¢ JÑ¢?+?@Qé`ª¡‰€ ½&„Ô×ÛîÛòÿœ™�Ý�ÝÙ�;3wfgÞ;óù@’�sïÜû½çÎ÷žsÏœ[Xˆ’Üa;ôãOÑL}XT´`ÝiÓaûvG^WØ ¤ÀÏ?ž½ÿ]^‡U=QLhÊ`›Ï�`J{!@¶Þ¿ÿ{.-:ööƒÿy�õz]™{ÙFøx­šõØÝºñÓãÊ2éØžã~1O½Ù˜Ô-§­Äsu�~ú­8Žº¾Ðö+¿¶‡m߇זÇqî­“±®¿�¥ñ§Ç®Æ±{ôUU3Ò‘–xu�zge†’!%Py8©Ž{KCÿ¸âLëH!“1R¦æ/ž¿1z‡T¥Ø{«Aüé앺‡ãS)`ÕŸ_.\‰#æêñ¡ŠíÖg„·è<Óä*áôøåŸ`RkªâüÁÉj[j%¿è¾ ñ··ËVÿtÃ.ØvóBÆ=³ö�þ0ê§æ¥Ìª±˜únðûÅ<È<È<È<(úž:àG3u™úéæ)í©ŠëDÊž~Þm“‘É>YȶÇk9Y<þøî�ÿÁÝ—ìó•=§âO×q†U£1d{º€ ÛÓlO“6°=Íö´öV(µ‰é÷{Ï_�y› ƒ²ÃVó7}ÖÅ…·OÆë+êpâ^½8ó€ÂÉ;^¯œ>OÖ:‚íi§#!·<ÛÓlO³=Íö´Õ·JiÀê#—}Œ-f$uû.ä/¿øO“ðçgõ \~xÌ,ÜÛø´8«í¨•¼Â‡oí „ô'RYõ/·?ˆþØZá_ü\™ú˜™™™EÞkO¾ÇÑ7öÁŸùþGØdꨩ](R·_edÙ�~ê_%þ`²ŸF‰Û8`5£Ämô �¾�f|i©îy Ÿ…‹mYÖ2³Ù¬«™ãè##ÈÇ]ýÒpö!K0Z°zò©Ø¸Cx'c ÈOÙP)Ûek!vÑVÕ#£Àª.`ZP_uÈ�gà_響[o8‚»ÎýTÉúX|ýçãz%[§– õ܃×ãÂà ™1¿û—‰øÍãjðY¼. ,8d‡ÔœjMÙZ¯¸s">\S8îàÀ9øÃiåjï|®gþ¡�±”ê¿ëÜØmsý±ö”!v—ïl„5}êuòg8|Ç]*¬RÀí6çÏBÿH!²öÈ�úð“c× ©Á8ã¬ÑP`ñmOµá’;&ço—M@7f_0+Ÿ5õˆûñË“õÁ·+ÖGqúï¦â…÷ Q£ÕŽíùêuà™·«+e>}ùÇ–Ï÷ƒ²ø¦R…@f3%£M 9ÍÊ‹}unþçÄÕŠ‘`¤¬ ~ý† ò�¸m�i¼uÃ%³µƒÏþ³ûñgkd§>™Ç$áôÓù«•¬ªFóC'³ññËýSßÞµ¬9·ÿt¶ÛªC¨™c‰?J;L}ëéîR2«%XUy�1‚y°|ú22½Ô¿výXö–ºN!ÞûÆ0œD®é�àÚ:qû2ýæÚô £Xö½�-­É„ÈÅ#!+ó!óaéûpuo³/Ø8ÿóuóWã›»÷•ù—³YJþE×`D±ÿfM6NÎåæûVVÝ2ì@mñ‚?ØŸ,c¤¸Žñ„¬Ž§Ñ澚"ÐÕ“ÄFû<¬“[xÔÆ8wá(>LÝ çh"‘@6“ACÜ$5¤i¯Ì涉¤> sÙ)§bã rV3Y {@ j3ËxiÖêá°¶O V- &üÊ53ðâÜfvŽâè]ú0±%�uý¼¾¼�þ§)´<=ë¶3Vâ˳ Ù,{‡ÂøÊ53ñÁJ› »m>ªo(Æ'kcøÇË'Ÿ›4Š/\ŽÉmåLo{ªÜ>%ß½�''ñìUv÷…÷ðO¶)ÇÌž°gùWÕV©²ß׉–èƒç:šÒ8dû~|aƒ$ê"jàjC]{l1TÖVr ÑEAý±°úŸŸ|P&»ÙÙ£oXs®dñå­‡œh¼ÿóqÿ» É”šµ”.êóâK–+™^�®•]QtÍL%l¥kÑ¾Ýø^ç�Ô‡â@f3�ºûŸ-8ãw…`⟟° ‡ïØ_5“ê¼êžNÜôPë'¯ü_˜žÌ?î ß.d`ÌñÙhRK/­Œ�ÕúÌð6Ã¥ô~)N×Ï_…£æ9ÇÉj;j%¿èþ ñ·7É¡XÐijËÿ];;nm°:Öø£x4ç(eV•éìób¬™™K9›y`4~ûбM§þfª’1•Ö|‹öéB8 å4„¡Dkû¢xí“z<÷N©L±´ÆÓ¸û¼O±õ† /^m®<Ã)5ʯüqÉO_Áý�ZÖdX­¬ZlO°a{šíi¶§Ùž.}[~²6нð¹üi>tß­pÓ‰«ÐÞ¤ÿ¸¸8Œßü½7.ž ó§L›0НþH p âåtÁö´?G�íi¶§ÙžدlíýtÞ­“ñǧ wž}`šã|¸&†‡_iÂú�ò}�…{÷ણ×êEX{ª?¤ÉßtÚ`ñÛ»—5HÔ¿iÀ+×çO÷$¹[ÏX‰ýŠâ$¼º<«B±ß*?¹ÒïÙm´WüÁþd»#ÄåÆ+°:^GžûmˆÀêu |~ÿGt÷N9zS|ûø/ä£ßtE£•ƒéœÂ;2<Œp$âYÀϜ×"‘Ð>uÒiؤ³|ƒÖIßú‡�Æz5•“k(t Ó&×õ³¥põ½…±ýÆÃX|qyö$ÚL8äÚ™ùì¡"~~j:ëSÌœ¨êIéõëÇÚqù_'å¾ò¨µ8u¿‘ªËd.ÿëDüú15 ìQ;÷á¦Wçe踹E¿™†%ÿn6­»tÃŒ(ÊA ˜-X}÷gï£%^Еî�¶8w@Ò]ù‘›LIâžóV`J{y0¯VŠ‚M?XÅ—×�ÅsW}\ñk2 ”¥�l£ú”Mqøéƒøéƒ�y¹\ù6ŸnþÅÚ£ÿiÄü›6È—[rñrl·ñˆòïd*„ O—‡�ìúLA1p';í¨U™“î¹KßÝ¥L/wõ\ÌÛ¶ú{g,ò‡6Z°QsK«TgŸWãÌ<ÈîdØž. 9ÛÓÛÓlO³=]N÷¼Ð‚Ó«?ugJ[ _�Û�™GÑ=Q>|Yöf£.°•j¢_î8{%¶Ïù‚H2NÖlOûwÄÙžf{šíiÀ ©l?°ìúœ¼•ξe þòl«P�u\{ìµs¿�¼Ÿ…4Ó¢û.Æ’wÈ¿¬¿DüËÅ%ülO»1Ô_úÏi¢„‘‘444Hi"eëëëíAcS3æ~ýqÞgå}Öüþ7û—Ù¿\í%s×ó-øÖïõv¡ÙKéGßXƒ÷*OneVÎ÷O¾WïÙí‹—üÁþd»£ÄåÆ+°:^GžûmˆÀòUÃØêàÇt÷Nÿæçñ­c7S~£#"({’›ÇÓ—} ‰XŒ¶s0¦Ûþ†úÂ'O:›v–qÚ}ÌàÐ$Áú†�éU’óåÜ['ã®çÍ�s7ÆÎX‰ƒlŸô¬�DWþu2î{±¥j×b¿g/.:l=âuúÌÅ÷÷6\ög5c)#ûÜ?2|¶Î�¼Ú„ã~1]½å´•8`N!C,ýF�Ÿ×Þ߉_?ÞnP‘Å;7~€ÖÆŒ’•T V¥:–½Ç×n˜¡æCæCÞg…²—Ìû¬b¯*âÃ'ßlÂ_žkUNÙX×ÅhZ ¤ ìâ“[SÊI]ûn3¨$„jn®=è„÷ÄÐ4–ª°?ÙɈqÙñˆ¬ŽÇQç>WDà��°ÃWŸÐÝ?÷„ÍqÜá3•MÕúúz×У¯ÝÌÜjÔp帊¾^ì{ÂóÑg½”µÁ6š.}:¯'·×QÌè¤ÎJe)À–2djÁªn<ÃouZÉJJÁªkz�™�‡_iÂÂÿU³¼ÒõóãWáë6‚pK3«ãsþm“qû25J™‚`_ûé®,Ì)`–ÚQ“7:‹_ªŽ�ÕùQ©>žòÆÌð]Y”µwá½—à¡w敉Ý|åØsßÉy5–ù#5:Ц¦fÇCwGмö�|ƒÃî|¸aužWj-Ïsóqt"Á<%Ë:ó ¹�÷u¢U,ET³?‚Àçüè%<¼lU™R¸ÇTüå†Í•eJ°=]t¶§Ùž®ô `{Züå8Öíiúàçî¶àáW›ñúòzåãbú°xbk[ÎH`ï/áÐíûÑnp"�8е—,^g[]G°=]ûñiÛÓz”Æ»½`¦3̃fî�uG"Ø’Fþ&«|¨!${ZÖ¨Q°ÑÈȰâvr  Ió_S]ý}hoïÐ%¨`>d>dÿ2û—EßSãm½¨òÞÎe§ŒTÚWűš\­øƒýÉ2F�ëOpÀêxmî«)o¼Û‡yÇ<©“»à¤-ðÍCg¢.&1Š­¤%©TJɬêå¥e5JŽ&qè¯a`(¥{ü ÏÀf3¬ZYœWë{W¿@ÚâAò¾á\°j4—YÕË1©Õ³¬Œ9Wu3'uQà÷O´áÒ; Y%oûÖ§øò6jVÑ‹‚cFÊ3«Rù‘d³/œ¥d´¥ëˆûñË“ËDŸUIŽÚ0šâ’cÒ«ácw­ÝFõm?kˆç‡S¨R¾tœN¼çR<ü.Vúë¦+¶ÇÞ;OÕýHïvz׺ù1B­ù£­µ]š³ÏÅa4­zîQ£�y�€b¬®.̃¦ÓI'ÀóYÙ°°Çü•3¬ª+ÛÓXØžöãÍ�6Y±ëxam xa /?J;YG°=íÇ5nÛÓ\Øžf{ZæÌe”‰fmꪴN´â_ÖZ4{Zâl4<<¤œìåä’¬J €¨M&t–�¦Æ|È|áîKðÈ{剀ŒöUe´¿–üÁþd#ÈuŒ'8`u<�6÷Õ�WßêÅîß|J'wñ)[bþ³”£ÒݸjlDý #œÉZ[Ú°÷‚§ÑW¨ó÷¿…/LúÄ�.[ª“‚Uãuò �12ªf�‰„-51ÐÂV7×>ëfLrñÛ×Þß�ëwæ1XrÉ'ØnVBÊæÖ?l¬J•ÜûB3Nûí´|}vbÍãV°*=×)>¥m/­ïÏg‚¹›&¤ÚòüP0š•Š?ÿîöØw—BÀ*DtE"îE¿û�?›šÌ¦X îï|ÔÃ̃ô‘ó`U}%g"ó µ)Íþd{ÚuõuýNÖlO»>ñ:B%weDÖlO»;nÔÎö4ÛÓfzÅ~e3„Œï³_Ùn¥¥ü¸NáC­Aµ§�Œù½)QC}½ýMÂmhh��M…œ¥#¢¶tw¯W|þ•‚U©¿Ì‡Ì‡fzÏ|h†ó¡=„ÄJÕ’­ðžXoŒ¥üÀìOv2‚\v<"À«ãqÔ¹ÏøçºñåžÖÝ¿ò¬­ñõ7”Ž7n3Uj0«j_RÀ*]»ó(ºz“º"��p&¶¨aÀjÏ ÐÜDÝKN˜ïobT}N­Fé¸(ÙGÑËTØ¡ðéz`zÐÔ ¯ùÂÛ'áÖ§Úó?¾uÃûhoRƒõª]Ãj hG•Ó\þýQ=üQaî�¸W~ô�µfU ß§¯º(`µNbléÃíâS©²ë‹ç‡¥J†Õ —n‡ýwWVÉ!æÔVmlüÄ":æAæÁjzÊ;H©9Èö´™~Tº/#QÃðÐâ��v› +GÙúzº»ÐÚÖ^5X• 122J™ve•Èæ/Ùõ™õšùðÂô hþäl6�P¨�•�ýÉf3…ï�W8`u¼Ž<÷Û�§þµ_9õ9ݽ«Ï߇í³Aà##­¯¿ q´µ2bRÇö?ñ ,ÿlH×LJ|5>” eÞ¤`U/.ÊðIYUk•Yµ«hmô&‹¬<éx ʬ:¹ho2®á¬?LÁ_ŸS3õn¿ñ0_¼¢ê£(X•œ•”­Õì*þÊí 9øýiŸ™¾O«^D[ÅǬ§ÿv îyAo³úªÝçùaŒN%ÃêÇl‹Cö>Wõº8Ñ1?•e¬Íh0VÇ�y°æÁÚÌÕâ§ZáÁ óÇ¢ïþ Ë^ä€U+ZÇöt-¶§­hŽ=Y^Gð:ªæð:Â*bòå­¬#ä?½65}=$‚ÛÓ"(É—ad´ªŨVsO~þ_.ÀcoÍB¸a†î!ÅþåñÀn <::ªdg•qú?õöt£¹¥Õ4X•úÂ|èÆˆš×É|È|h®%z æC«ˆ9—‚(‹?ÈŸüÔ¿Vé„¢ê~¾Â|b—sEâÆ$°:&‡•;e�¿?¿‡Ÿñ¼®øO.šƒƒ÷ vÖ¼‘áaåˆêDbíÊ#Yô$Þÿd@×ï¥Ç�ƒm¦½o Êt…ìR¶Ë‘$¯·ôHÛ£i5PÕ‹ ÅÒFR_»€¶«Ò³iŒÌ.í øÎV ³¥²ôÙ·LÁ_žU\ç²çÒUQ˜2çö«Áª"mXöf'þr¶›•ÀÍ'­BgKÚ¬Ùe÷©¿t?OË3(PŒÏy_Y�óé²¥sÚü¸øq¼�´ŸçGeô*}ÿ£ó¶Åáû޽€U3þp¢g~*Ë<èíh02ZÕ8æA«ˆÙ“Y#‰òàXà�“¿óžyim˜ûí:wý|'{ �ñRlO˜íi÷”�׼ްª]¼Ž°Š˜=y™ë{-ð_©±°A•íi”äÉ02ZÕ&æA«ˆÙ“áAª™ö]Ž»ãT<ûénº@º§ù—Ç ØCÚ¸íR€i$RÈfç¤~ªO V¥X‘‹ùP%y2̇̇Vµ‰ùÐ*böä�ø°RÀªöUeóÇI—ýϼð!iÔeXe²=}âRcXûcÌ=´€À#ϬÁQgýSWâ†K·Ãþ»O³P‹¿DGFF#-5:ZñŒ#ÏX†·>èÓ5|É‚s1{ê{Â�I¥Õű�l¥”í’‚]crlIÓ6×:o]ÐÞì] Q‡‰æ4Y±NÍþ:uBu8_x¯ ~1MÅ]ç®@SC.B´¤«ö «š¢€é]µJÖšWŒÏ_¾½­�ÆøTëNñüÅ[žŠ"¬°ê‡}UÙü±à¼ÇðÂCº`UB“ýÉÖuŠKŒ8`u|Œ3÷R�%O­Æ1ç¼ “þŸË·Ç>ó¦ Öà/±d2©}‹Åª6ì˜o?ƒÿ¼Ý£“Y|ܹØvšXÀ*NÁªvN)XÕN «´ió€½z^q‡ÀÀÐÖÔ‰Û¹vºi»Œ–Yµ¥˜f¬*úʪJ«tŠ–p.GÔtE= ‚®Öbžbã”ù±àŽExfÅ<„búlÕß?kuàL±Î@J”?С&2 ÁäX((óœ>Ú`t<Üù ˜Ű Êü0ãÁ±Ä'^üO<ÿ꺲üò.“q÷ÿpÀª‘f³=]@…íi±wŸ© ¼'yaeTÍeyaŽIe~˜­#Äz멱´A›íi”œËež3:ëâ˜Åð Úü¸ì‰Kñð»;—uîò3¶ÄW÷ŸaºŸ'† KÙE ··ñx#êêê,UÁ|h .ÛÂA›ï¼Ïj{¨u™Åpôëü8ñcÞkûªÄg_õ:^x½—ýÉb*ËRŒ8`••€(BàÁ'Vá›çÿK‡ÉÍWî€=çN N£££J°ªÈ€ó/x/½®?ÊýoÇ�‡9ÓÞ5í7-éˤ†ê1±¦õx!@AŒápm2n'�•ë��zŸbEÁªË×M À IÁ¥¬Ú;$¯>=¡ äLÆ8óü1 HóãŠ'¾…eŸîWÖ±+ÏÚ_?pC±û\Ê xÙúÒ‘®0½È-\"å˜-jS4HóœyÐæ cÃ2Hó£±ï4aûC 9R"<`ô¤=‹^]�PHÏ;ûΛŒ{nâ€U#ÌØž. Âö´œù«Õ¤÷$¯#ä�=¯#İ Òü`{ZlLÝ�²»)Çö´#¦¯3HóœyPž>0ŠaÄùQ)p‡V�ùÊ,±Ž{$%ÂFM±[ΣnU|L__/êbuhˆÇ-7…ùÐ2d– q¾[î¤AÞgå8=òóü¨Ä{FûªAç�S¿÷ªâO.½ØŸ,¢Å,3à€Õñ8êÜçŠÜûèJ,¸ø%Ýý__µvÛ~R PK¥RJ{E‚UIná%ÿÄs¯è³=8ÿ|l7ý�ªýNŒª‹Ä¸µ k‚%eq¥,°µ8žpút½šaÔÏÁªô<�åLIêN°ÝÞfVõ“#�ç‡ØTÚü¸b™ñ—€ß=ã‹øÆW>'ÖiKY寺b×H¥à[ p�Dª§[ftw$ƒ6Ï™åèó ŽA›•xð²Ó¶ÀÑm(lˆ¡ã\Ê œxÉ xé ý)Ô¢}w™Œ{8êáà°=]€…íiçóW«!hïI^GÈ{^Gˆá´ùÁö´Ø¸Ê–r²b{Z ö+W×JíÄ.ö+Ë›½ÌƒbX�µub¥À¿ù—Ýæ±QöNjppÙlÍÍ-¶Êþe[°  ê|î`AÞgå8òûü Þ{èím 7èºSÊ{¢ûy"˜x)SÌÇ]ø<^|Í `•ýÉ^ ?+@pÀj€‹›ê>w>ô)^ö²îA¿¿z.vÞv¢û—ô„tZ= Ý,8§øq§]ñ/<ùÂ] <ö|l·Aå€UZüPÆRújÚïW-�Š„QßÐØàNZÊ&JA¸k uC¦9)˜–œ&2‚zéK.ª·ÓžmoK¥H'i¬ëm—Zˆç‡œAœ'ßw zg^Y/;m+|óÐ�Ä:îS);üáEWì¶kxh‘hTèø&æA÷F2ˆóœyй>0ŠaÄùQ‰/Y´æ¾±XÇ=’rÊ'^ö^.9…‚šÎ«•�íé6lOË™èA|Oò:ÂùØó:B à ζ§ÅÆV¦”Óõ�ÈqÈlOË1}]Aœç̃Îõ�yP à Ï�…÷úß¿ìˆ�´7RäGN$hoŸ`û�̇¶¡3-äùnÚ¹*¼ÏÊq"ú„ù±àÎóñÈ7F¸a†®KÅûªVöóDpñJ¦”?޽à9ö'{>?gL À«cb¹²¸cñ ,ºüߺên½vgì°µ¤óÑe5´B=ôÅ#}h%X•ª:ë/á±gWéj­¶ÁFNÊdÙbýT —(¯¾–Áª”}–°r+-ÕM'cǪ'¬Š¹¬‹3'QuiÒ¾§XNJ¥!}LŽÍ>ÐIž"#¦~Äùqâ=—àáwËV/Y´æÜ€U»ü!6Úö¥È9Jm‹Åb–*Q2«Šl®1Z‚Ö’pPç¹¥N3ò:QD‡‚:?‚ƒ2øãØóžÅËÿí.Î}æM½7í,2ÌãN†íéÂ�³=í\ýƒúžtÚs^Gð:BD‡‚:?‚²Žƒb¶§Ù¯lUgDäƒ:ÏEúVM†y�yPD‡‚>?ü·2ìi‘qô‹ ù‘‡ÐÑé,qﳺ3¢AŸïvQa>d>Ñ� Ì�wœ‚§?Ùáú©ºniûªV÷óD°ñBƈ?ØŸìòüŒ±„¬Ž¥Ñä¾8Fà¶–ãŒï½¢«ç�×ï‚9[ØÿªÎq£,T@R бz�wÍËXúägºb•6Øh‘Lÿµ6Z}Š÷ò´Pó*`Ò¨w”ýÔI0i5ÄèË:d�¸ƒl¢Z°*egÝp²œ¶Ê¢µª)ôÌ‘$ÐÖdµ¤|yžâ˜u~÷¥xô½ò • OÙÇ1KŸIÚå7»‘J¥”`UÑ S­-‰D¡PÈR9æAwF2¨óÜ ̃¼NÕŸ Î� ð ,þøç<‹WÞ*XÝ{çI¸ï°j¤ëlOPa{ZômXY.¨ïI'=çu¯#Dõ'¨ó#ëÑ1(–c{šýÊvôƬLPç¹Y¿ªÝgdÕŸ Ï?ó¡,{Zt,k-G~äþ¾^%XÕÎÞjqûÙ¿ìÎh}¾ÛA…ù�ùPTo‚2?.}ìT<÷Ùþ@HŸ5‹öU¿qÐtËûy¢ø¸)W‰?ØŸì&ê\÷XD€VÇâ¨rŸl#pË=ã¬þGWþ/7¿Ðn»Î ¼ôºWpßcŸêšj´Á¤ãh‚€»Ý6'Z„: Ö‚U)¾yÃI@]Ônk å(Ë)ËÈÒ*ÚÒÉ� ³E´„{rôš?dŽ}˜‚5)³j$l¿]VKR6Óî`ª,¬>³’<ÏYH:«Ç«ùQéȦo/øN9fSg�àÒJ êh2‰xc£%4ȰB<ÞhéKzí!̃–à®™°WóÜj™y�hUgÜ�÷j~ø•Ýà�¯�õ4Þx··l¸8`µ²³=]À†íi7ÞtÎêôê=iµ•¼Žàu„U�qCÞ«ùá×u„˜Ö¢N7ÖC"ý`{Z¥ÚËx5Ï­ö”y�yЪθ!ïõüðÖŠ?dŒ%µ= !Ñ3]­nJz@ÁªÍM-–}ÐFõf³Y¥ ̇2FÔý:¼žï¢=b>d>Õ7åÜš•xïìã6âo|ÞÍ.U¬Û-þ`rM†“`8`5ÀƒÇM—�ÀMü—^ÿ†®âÅ¿þfÍl–ÿ0ÕxíoÞÄ-÷| k‘¶ÁFYUéò2ÑGÐø¦)hÚ3Lï°ß$-X•ÐnÐ4[;1ÛðÁ¤°Yïaæ] V]ßï û(êKòü�…¤³z¼œÇß}}¯<ÃêYÇm†S–µjn IDATkdX9CÏ?¥É@L&hlj²Ü¨á¡!åØrÚ¹˜í æm/繕ž1ò:ÑŠ¾¸%ëåü¨Èƒ ¾€Skôá†[üqÔ™Oã¿ïqÀª½e{º€ÛÓV4Ç}Y/ß“VzÃë^GXÑ·d½œlO»5ŠP>þd{Ú=|ƒ^³—óÜ Ṽ̃VôÅ-ÙZÌ?ÙÕµä§cj'؈’t­_‡ú†[§tUk3û—�ލûåk1ßEzÅ|È|(¢'n˸9?üÄ{„£›üÁþd·5•ëkpÀêXQî�#n¼õ}\þ³ÿêêXúû½ð¹©�€½Gíñªð�·¼�_ÿå=ÝãJ�0ôª-üœrG€Þ!gšôUÔòu«R†ÖVkÉ ‡…²îf³Þ3S°êÚ> ÊêÊ#àõü¨dX}ëØÍpú7kó% Ÿµ@ûÂܬ�v�£ZfÕ¦&g–0š�Pmï{=ÏE{Ë<(Š˹‰€×óÃ+ôyÆ2¼õA_Ùðí9w¸yg7‡5°u³=]:¶§ý£Æ^¿'E{ÎëQ¤XÎM¼ž^­#ÜÄÌ˺ý°é/ÛÓ"(ÕNÆëy.ÚSæAQ¤XÎMj5?ÜæÃ ð‡“±M&“JVU«™U{º»”2íd†©ÐpæC'#ê~ÙZÍw³ž1š!Ä÷½@Àíùá6ïYÁÈmþ`²•Ñ`YFà€UÖF �ë~ÿ.¾÷‹·t˜Fú|¿¸ý] yƒÍ&c‘XœYur0ÁY\WúêÏËÌ»#¬ÚLïôö¹þÐn…µ˜• «ÓþßçqæüÍx Š `Rú/�VÅ…‚U‰X :¥rÃÃCR¾†gô¯êÖbž‹¢Á<(Š˹…@-æ‡<èþ8üôexçÃò€Õ/í4þrž[ÃèzÙž. ÛÓþPåZ¼'E{ÎëQ¤XÎ-j1?¼XG¸…—×õúe=$Òo¶§EPª�L-æ¹hO™E‘b9·¨åüp“ƒÄvÇ6‘H(A§f>çâú©L__›,û EÛÉ|(Š”÷rµœïf½e>4Cˆï»�€óÃMÞ³‚�üÁþd+#²Œ¬²0:~ü›wðÃ_½­ûí‰Û÷Á”Ά1�Ôïî|×ý^¨ûàüó±Ýt}k-@ÏG® ý#jFT»WqfÕ‰­@g‹Ýšôåè«?/3œR°êên`ƒN ‘Ó‡±P ÏïçÇñw]†Gߟ[¦>‹ŽÙg/øÂXP+)} çh:�F,«ZŸÝ`Uª›‚U››å¼Ô˜¥ »ôJ˜ �2«óàØãA?ñÇ¡§>…÷>î/S¾/í8þŠV�f%ÛÓTØž–¾,°\!¯#xa¦4¼Ž{ë³1Ê}?­‡D0c{Z%ïe˜™Í´ŽyÐ{ÔÆÄ-ÿrÐøÃLG�î�ŒŒ(�ªV‚Uú•¤ äG‡ÃvkZ†êÿÃÝò>«)RÞ 02šió¡û|èï™�mñ}¯øƒýÉVF…eXe`tP°*m²_Ëþ´/:'Ô»Š3tL‡•ã+d6èŽ?Æn~]W¥6ØFÓ@&ÔW�wª ÕAY@½ ®”16dD ŒS«gV�Ò´7Éh™÷uP�Ϊ.`ƒ‰@ŒƒUóÀó£6ócÁ]ßÁcïïT6N>zœsüæžO�Zó‡Q‡)•.3Ç¡Ý`Uês2‘@C\^ösæAÏU×ô�̃zg"ó`¹Ê0Ž=ô²èI¼ÿÉ@™òí±ãDü�V ßãlO`a{Ú”ê]àu¯#ÌŒ×coa6æF÷Ùž¶ƒZy¶§åà(³æAæA3}b¬ jãâ†Ùoö´™Ú¹?2<Œh,fêsÖê&žïïïC<Þˆºº:;�*CÏ¡@XæC!¸<b>d>4S8æCoøÐ Þ3Ûâû^òû“­Œ Ë2°Ê:ÀèøÞ/ÞcX|=û×ýÐÞBî€%zD‡•§Sæ9+Á¯÷>º—]ÿªî;î<Ì™¦ÇÂJœÊÒ"19 49HnK�ލZWý4j§M•Zž2—®ïè‹.'ÁªÅ™U§w-ò⺤ö׬2ÕëÕ̪N—Íž´ûó kæAcÝcôžxä,œò–¶_~ä�ƒOy.ç€U+ƒÊöt-¶§­hŽùl¨Lwß¡‹9`Õp’²=]€…íiëk'%xÁëýáuÄø]GëÛÓlO›½/د °_ÙLKÄï³_Y+·$ý¸NôÚ¿\ {ZÖx ô£¡!.¬JÁIÑhLj’ £¾�rÉþeY£n¿?Îwû½q^’ýËì_.F –óÃkÞ£~׊?ØŸìüÝÅ5Œ/8`u|�7÷Ö� ò:~õçuRÿyð D£!©ØQÔd"�Ʀ&iõÒuuö"4_|½ Ç]ðœ®-Kœ‹ÙS½Í°Jœ5½j z»Ù,×ö-�µÏÈiu`?]¯«¶9P -X5QƒUëÜI lµk–åɈ¢àÝiÔl³µ¼£ª“6&7ù„­.ñüðÇü¨ttÅüÃ6Â%§nekl­òXi»ç(õ›‚UC=îÂÅ<訫d,Æë¦u¨Ž1;×PˆEŃ “)UÖ¥ø'á.¬îšê�æ¸p‘2A-X•‚T)XÕ.†ö[ §$QËתAË-ð�њᤊ£_‚Uy~ØU™ó£’aõÿù¾súí7R ¤ùC Ùе}xx­­ÖÓgÓë¨êFfU­ý̃¢#éŽó`WæAcãu¢Ö‰^ó`-ùãËÇÿŸ®.SÊݶŸˆ%¿žçÎ 1൲=]@¶§½Sf^Gð:ÂLÛx1~ןÁö´ü̪lO³_Ùìýëõ}¶§Ùž.EÀ¯ëD¯ìêZÚÓNç__/›ÄƒUGF” R7ýǬJ‰ƒêë��dÿ²ÓQwVÞ¯óÝY¯ì•f>d>ôzÅ{ÔïZóû“í½·¸ÔøE€VÇïØsÏ 8ë‡ÿÁ-÷|œ¿‰„ðÚß’†•f ÒQÈ2²Ä‘�”A}Cƒ£ú>\1ˆƒOþ‡®Ÿ�6¶š¢Ï6+ ˆ’Š´ÍƒÉí@}ÌþS(�½hfV nm”xÔ|:£¾Š>_ëe÷€Úg'mÑ‚ñâuÀôN]og)@”2«NjÚdšµóìÒ2Ãjð³}”Ѫƒç‡¿æÇñw]†Gߟ[6¼Ç|ås¸ü ÷VýÊ"zNYl††a‡û2™Œò7��T?ó ÈHV—atŽ!ó`ug"¯íé˜ìu¢—ô‚÷üÂìOvþãÆ°:¾Æ›{k‚Àß{·=°›F€æy™U©© Ð`1Ø–‚fé¸y«åŠ¡Ô‚š€éòúäÖxWªWû⯣èlñúéúçõ üë—`UžöõÁ�ùqüÝ—áÑ÷ÊV�>hC\qæÖö[¥¤ŸùìÃN¾ä7«[æ}æAgh2:Ã�J3Vv&2Úׯ ó øcïãǪµ#e°Ûv�Xò›]ìÌ.ÉötapÙžWt^GˆcÅö´5¬Øßä?ÛÓÖtØë!‘³=-‚ReæAgø±=]]·Øž¶¯_nØÓZkÜæÃ ðGéèPâÊŒg%X•NŸ¤Ìªn«R; ÓX¬ú ó¡ýùF%™�áÇ|È|h„€_âÜæ=?ñû“�¿Ë¸†ñ…¬Ž¯ñæÞš °èòãŽÅ+òRMñþuÏŽq#£ixhí:×¥U088€x¼QJÖ¹Þ�QÌûÚ#º¶=±ð l6±¼+­áEÕbó€‚Ûš¬gB­Ôê-øZ-Æ 'Sj�N‚t5§ ={J{ðƒU)P•VkuQ0óú~ %>~ƒUy~˜kß w]†G 2¬uÀL|ÿìmÌ+°(áwþ¨ÖräQfU™jX„OXœyPª2AæAûØi%µ`UæA=–¼Nôç:Ñ ô Ð}´áTzqÀjå÷ÛÓlØžãG^GˆáTMŠ×Æèð:bü®#Š5‚íiçï‘ØžA©ò»ŠýÊöñ£’̃̃¥aßÅM»Ú/ö´Õ™­QfÕ–Vá̪"A¤VÛa$/úæCûh³]h;ö/WÇŽíBØ…nòžßøƒýÉÎßg\ÃøB€VÇ×xsoMXxÙ˸ó¡OóR­Í1<ç~ŽpÉ«Êúʯ¿¿O V�F£ŽÚ¦N¥3Øæ+Kuu=yÒ騴³¼+åAE•È:æÜJ»Öõš�ˆ¤“°¨}Cö‚,éh 'íЂU)Àsb«Ìe3Yy½fOÓŽ§ €[«A¿fu[½¿ºhoòO°êg]€Óã�­`ÀóC ­ãïº�¾?¯LøÈýgâªoË X ¡Fb2‘@"™D°*õ�yPLÿK¥˜íáV\ŠyÐC^'úw�è&ú�?ö<öq¬Y_°ºëv�XÊV '/ÛÓXØž6çH^G˜cd&Áë^G!àg“›ëˆR,Øž6{ƒÈ»Ïö´=,™íáÆö´9nlOûמÖö]N¸ûR<òÞÎRýË~³§Í5µ AmïíéFKk›ðž§h©•vÉZyó¡=´™íáÆ|hŽó¡øÐ Þ# ð#hþäl6…P¨ÇÃþdó9ËãXŸãν®€À‚‹_½�®Ìßíh«ÃÓþ²m¼F†‡A™P'ttJÉ„J ¡úâˆD"¶ÛeTpö!K0šÊæo=uÒiؤ³¼+óaµX$®éUƒUc’`£>t“Úd"#V—¬JÁŒ`)óMËÃȬ]´¹öéz`Ú ©ÁLÚ½ûä(ZÕ­7T?ÕŽFÕÌóÃÌnÏ�E÷]‚‡ß+X=b¿øá9³�5¾¨t�ø£¸Ód ötw!‰ ½}‚4<¼¨ˆyÐỄÖð2’f4Æ�yЙn•ýÈ_úæcXÛ•(v0VÖQ¶§Ùž}ƒñ:B©Êr¼Žàu„s-*¯!¨ëˆÒž°=í†vT¯“íik˜3ZËíiq¼ØžÇÊP¯Àòuj 7÷]N¼[®Ù�ö´èH¤Ói%³ª•`ÕT*%Ø*Ú#9+ÁªZyæCkˆ3ZËùP/æCq¬¼àCÙ¼Gmö+�?yÍúA]°*µ—ýÉÎt’K�]8`uìŽ-÷Ìß<ÿ_xð‰Uù’“:êñä÷µQ0<4¤—vtN”¬JuÖ74H«¯¸c;íô Œæzú”E˜5á3[}¯VÈ­Eb¥ ŒH™*›€6IÁ�Ô::ž²‚z}ÑæÁ§]ÀÔv 9.÷é´áU³Ÿ]ÕJfVz�ËôÎÚ‰’Þ|Ö­f©ËÁª”É{Ô^²?üÊ{|c)ÖõdÊ�ýÉÎô’K�]8`uìŽ-÷ÌÇœó–<µ:_rúä8û¿½-×448ˆÁ¡ttL”– • ¤h4êJ°*upïù�cպ‘—ÿ<í$Ìh]c¹ïÕ $F�5=òƒ†@c}ù“)pdÅ: ¦wÈé -t×ö©ÁªšƒANÍæµÐ"q%yvqƒþš×PY‚0¬‹ªXÙ¹(3+á ›—¦~¬îQƒU陵º¨ÍëúÔ`UY™w�ô…ç‡ô¯æÇI÷\‚¥ï–gX=tŸ p�„€Õ ò‡6r]ë×)ÎBÊ*¤‹¾–§/ù�:çU¬^WȤÇyÒ¨�vƒU©.Þg5yõ>ó!󡘦X—b>´ŽYq ·ø�xoÉÛs ë�[µ³¯êwþØ÷ø§ØŸìL ¹ô8C€VÇÙ€sw«#pÔYÿÄ#Ï‚4gNkÄÿßËl”UuhhPj°*}5HA@ôå [Wi¡§N: ›t~*åq”ÕjM/04̘¨fñ´{%SjP¥,Zé{z&óN”S%�JM™¥ºÔúj¬ºª˜Ö!?èÀ0P_g?h“Æ„.‘àSZìR�(õÃnp¬]Ý).GFKÿ°¬Zë‹ç‡ó ½òj~,¼çR<ôîÎe�>xÏéøÉEsu&¨üA�¦Ìªt1Xu ¿­míØû¸'tG?3–«3ó ñgtôêó 3ü¨t�yÐÏü±û7ÃúXµ¢¡lOô…×¼Ž�;¼ŽEÊXŽ×Îð ú:¢¸÷lO;׫5Ðf1ÛÓ⨱=Íö´¸¶ˆK2ŠcUIÒK{Zkƒ,ÿ²Ÿíéj#SÌ¢¨”IÖÍýQ­½N‚U©Þg5Ÿ“̇̇æZb]‚ùÐ:f¥%ÜäÃ=�}°+ÒgͲº¯þ`²s]䯰:¾Æ›{k‚Àág<�¿?¿6/5kf3ÿúK¸õ÷÷a4™TŽB–e<‘!F—¬úŒ:“Íf±ë1�¢§¯p„á’ã/Âì)o ÷½’ e9]¾ ?)XÕi&K‘ãvéë¼¾!  ³Åq” ÖRÀmBíƒHQ9OUk¡E"üR�§HP¨•gS°j,j?ˆxd “lD‚�©ë€iÜÅÐLG¨Í£) %n)wdy~8ÇÕëù±ðžKð�A†Õ¿4 ×]¼�í™?èè â* Vuû8&Û$äÐà€¬J»Û1�¢«7™—dÔƒÆ+¨›I)Ã(«6ØÌxK¼”ôW¤<õ£wH^¶ÛJŠY)ã®&o%°È±ò TÀóC¤*"µ˜ ï¹½»KY«öß}*n¸t{[ :dÒéÀ«& $#hmmË�Ù¼¯?‚ÞþB  ó`A�™�§6ó ­Wž®ó 3 ƒÌƒdø�?胾ÑÚu»,ý ¬i/ÛÓlOé¯#xáŒí*—æu„3dƒ¼Ž(î9ÛÓÎôÀNi¶§­¡Æ<Èd>”7cõ51:CÖ ><ãAgûªAâö';ÓG.=þà€Õñ7æÜã*pÒ3xöß]y‰Í7nÅ=¿ØÝ³ÞÞD£Q455›ÊŠ ¤ÓiÅ8r3³*µ…ÚžN¥pÀ)/a`¨°Áöÿï—ØwæRÑæÊ­ê(ÛéôN lðëèAE…µìª²‚U)éê`ÃÉγÃZí#Þ®ï¦wÈÇÏi°ªÕc F€I…¸0«PÉÓ¢º¾®2VÌJzèu†ÜJ�çù!4¬…j5?Nº÷b,}§<`õË»NÃϾc=ÃêXà™YÅ�i…Xé‘‘¤Ó©2ÎÞé«3@Èã IDATdt®Eû>Ùw±ã_š=-Ê2Æ™øŒö8­žÊV¥¾°™ýË2tº¸æCæCÙ:EõymÚå½jûy2pqƒ?4riûØŸ,cďޱˆ¬ŽÅQå>ÙF`¯ã–á¥7zòå·Ûrn¿®üègÊÎ60Я«Z5‚ª5ŽŒÎºúz÷ƒUGF …” -0vËëšvÉþ�ã[ÛþÌ2–ƒ#ÀÈ(ÐÙb¹¨í¨J™<íÈÒ1ñÀY|Qp «–þn»� ¥#é«]d|~nd$í¢ É8VËI÷ÊÊÒb—½ÝŒíêZÕ~áâùa…WÞìÍÞaëNÜzíκÊèèÈáá!Äã�RK‡‡†PßÐ µNQn$‘Áv‡/Õ‰Ÿ¶×‹øÎNß·$ $GÕB¯®µ½@*L› jX*"£µ(•VÿfTIÎ8’¥l¡²/ V�„ÝÏvJí&= ¸Üzy‰‡ áX×´5ÉÝ•�{q}öKZå�=¾ù†2eÜeN'úmù)ö[6vJ²=]K¶§+ë5¯#xaõ­Çö´UÄôòAZG°=íl¬EJ[]±=-‚ª5æAæAk£&¸`{Ú*jy?ñ Ö*3ÿ²&d{Z„?ì�*”0)©�Õ`U:þ™Nžtãbÿ²5T™™­i ó¡U¼Jåkɇ¢¼'ºŸç ·ùƒâmˆJ/ö';5.;–à€Õ±<ºÜ7Ëì|ô?ðß÷úóåvÙn~ûÃ�”“Ó”¾¼ �±ò`"_2�¬VVžA²dˆQÀŽÑsº{“Øõ˜GuU:ç#ür¿³„CŽ7ƒKÒ3Œ$�©3«Št–úI]lØ´d€Q–ÓÒ+1 da¯Îjm¦Œ­Ëתy‘õ–úG�ÃfÙiEp®&³² èlq?ƒ«Óv—çùaŽfPæG%Ãj×í'áæ+æ:¼Æ2˜�¬\ âLºL+¦ õõb_0šÂ™`¬Œó`el˜ÍçØXàÁß\¥ÚMÚUÍþ0GD®„þØé«c`¨ÜÁ8oÛ<ü»]å6pŒÔÆöta Ùž6Vj^Gð:ÂÎëŽ×æ¨�…uÛÓæãìTÂÎzHä™lO‹ ¤Ê02ŠkKA’yе ð Ö“jþeÍ®º=m>jö%úúzÑÔÔlyO•€eïï÷‚ùP|L™™ŵ…ùÐ V~åCÞ³²Ÿg“bY/øƒýÉvG‡Ë�W8`u¼Ž<÷Û��zo8�¿§eÌËf³JÀªì R+GR:2 ´¥`ÕJæV­ÁÞÇ=®{Äž›¯Â;ÅÉc]+K_ÑQDSÚ]{„aÅô%s"i/S)e\£€ÞÒ`Nª“2†ÊÎJQ°ê¤6 ½É[œÜzùY—šYÕ«L¾nõÅÍzy~˜£ëd~T2¬æmÛ‰ß]½sÙÃÇ:˜£-OÂÊæšÕ¯å™ÅƉyP '·¤˜Å�e4ÇÉ ,þÐ�Z`f˜·Rž„]þØñȇ08œ.k¬V¶§ ذ=]®'¼Ž�÷^³S¯#ÄPãu„9Nn¬#Øž6ÇÝ©„Ýõ�ÈsÙžAIÍ�É~e1¬Ü�bC•yÐ''<¨Õ^É¿¬ÙÕcÁž6GÒºíÑR°QKK«å½ZâA‘Ö[U(Á|(†ó¡NnI1Š!Ë|hŽ“>4ã=«ûyæ­ÓKxÉìO¶::,?Þà€Õñ®ÜÛùw¼ûñ`þ·=çNÁÍWîà Jô¥ÀFéL{¯t:�P(Tõ8ä�WâÀ…ÿеb»�ºñàÑ \l™½ª)𓲫NjU³yzuÑ}Cj°¤Õ‹2¨RfÕÒ ´T'õÁ(ëªÕgË“Á÷ñ5 é„f'5ù§,}¶r=ÐÞ 4ÖËÇÌ?=uÖžæø9�§=p>xs�²ÍÛv"~wõ\óH�ðHèŽPÔg þq,ïYýÀ„yÐ|˜Í1rS‚yP ]æAsœ¼àAûü¥r$œðÇG<„¡Xµ2lOÐb{Z¯9¼Ž°2“äËò:B S^G˜ãäÅ:¼Î$Øž®ŽÛÓÎô«RiæAwp­•yP )æAsœœò ö„jþå__µƒé~žyKåH8±§å´ P ñS?«¶¶YöûŽ £!—ݤ²úØ¿l1ó¡9FnJ0Š¡Ë|hŽ“U>4ã=«ûyæ-¬°?ÙÊè°,#pÀ*k#P„ÀœÃÿŽ÷—V÷ž77]¾½’Sfp$=AÙNÝV¥/F誔YUëú;öãðÓŸÒéÂ&S†ðÔñÇøJ?ȘYßï}fUzn×0¹Í:ô…¤Æ"ÖËÚ)Amýt½š–VÇÂEFõ)Upbc¡WòûÀóÃSóãôÎÃýo~©ìasgOÄ®q?`ÕoüaŽºs Å9šÉ9‰÷Ì8ϨẼÕljyй;©�yP =æAsœ¼àAQûüµÎ%œòÇö‡?„á¬Z ¶§ h±=]À‚×Vf‘|Y^GˆaÊësœ¼XG˜·Â™ÛÓÕñc{Ú™~U*Í<订µ2Š!Å4ÇÉVã½[®)?¹Ò¼b”±Ükþ`²ØØ°# !À«¬ Œ@Ûú8>út(ÿË—w�†Ÿ}g;©ùÑ9úÚ;=8úìgtýœÔ–Ä+§%µïN*£Åôê`ê ìqfÕµ}j�¬Ùs©�ÅÙR×õ-q Þ£Kzþà@Ž•Ìª´ð]±NíÓôN ^çD‹ÆnYžæc+k~œñày¸ï¿å«äPtÓ°¢ú‘?Ì‘·/A›eý¨‹Õ «ÚÀ4ÇÉ.Öb_µVüÁþds=b F Xe}`ŠØêàǰ|Õpþ—¿4 ×],/`Õ«`#«ƒúâë]8î‚çtÅb¼îáV«rE>“Vv©A£23•Ò"=Z%ó)Ýׂd‹Q�:I²YÚG™U³ ^ï $e•Fà  ¡N4ëÍÓÝy )°r=@Ç/̘ÈÁª•PæùQYÿ“qŒf"H¦"è‰ ‰"��!•‰ •Ž*÷F3Q¤Òô"‹„¿ñÙ£ðôÇsʺÃÖ�¸õZ÷¾ô+¸3ûr*ötw¡±©õõî¿H™�G’yÐ- «—yP 'æÁñÁƒbÚ —?澉„zbEñµóì<òû]E›4®äØž. 7ÛÓj°*ÛÓµ{ð:B {^GŒ�uÛÓbóÁ®ÛÓlOÛÕ7Ë1Š¡Ë¬�eðï³²]èD±–e>�ù°€ÓÐhƒÂu©Œº‡ªü™Ž ‘Šbp$Œp$†t6ªì³f³a!€½ÞW­%°?YH%XˆÈ#À«¬ Œ@›ø(V®ÉÿrðžÓñ“‹Ê“ì€FÎÑP(乑$ÒÖ§_Z‹S¾óB™èò C8Da˜µ½è8øŽfï‚?©·´¹¶Š2º¶Wj5B¦4ÓªèQ°ªWÁ±^ô‡Œ¨ÕÝjfÕÉí¬Z s™óƒ75Dý»jthA�ôçh:Š‘Tkº�ÖæzdË/š¬fÌ(ÿΆ¦sFÍH*‚T6†t®~åyéÂstesÁ¤ÅõަՀSµ-ª±¤þ»„šÉê#ѳ™Ba9A�Ù,2ˆmÝý'î|ïgþpë}ÐÓÓ�ÆÆ&Ͼ‚g,IæA·´[¬^æA1œHŠypìó ¸62ùcÛÖ"™4Xݶ�üŽV�Æ…íi=*lO³=måý%S–×âhò:bì¯#ØžŸv%Ùžf{Ú®î¸UŽyPY™<¨=5©øy ~Ûâ`ò'Reߥµ©^ Õd5?tñ¿ÓE¾eÅœ +É(ˆT¹—{ýY*«ó=ç|ÌÔ¶üsr>ë|@Nñ¿Ód¡áÈô+kÕ¿,¢2íi‘çU“I§ÓÊ~ª�\(P)‰Ø*ë¤Ý̇̇NôÇ�²Ì‡â¨:åCm?5¿§Z´ç©ì_¦ˆ³bºýWÚ+]Ó›AKSÙLI%@´2Ÿ%ÒÑü¾j2F*Ós¡Æ¿E{ºÇ)û´¥m*þwn¯µbNøÐKÞ«5°?Y|Þ±$#@pÀ*ë#P„Àç÷«×%ò¿¶Ï¸úümcD}�èåñVýè3Ÿáì«^.+òê·æcbS¯aUHH—YæQ+í0’]Õ 4Ö­ÖNüpôX%H§˜2AnFWG�ªRx89¶:£@Ï @ÆTgK0úF_[xÒ—fôï´ât+Ïæ©qæî9Öô²¤óY@# ‡}*޵œñÐ78„€Hc!p³È¹¦ :ÍšÓP &¥?GR‚9³idF»Žu¡*)ŠÝRx«õf’@XÞÑ?ô.'gYéµÝV¸ý§òVýÎV‡CD~`  q%s�Wó iæA¯4Ïø9̃ZlæA)šp´‚�lþØöÐ¥HŽ–¬Î�Ý�G9êáа=­‡…íi¶§­¼ÃdÉò:‚ײtI©'àë¶§¥jCÅÊØžf{ÚM{JyPë™vRTbT ÄÌ¢�D 8àDñ—ú“7‹ƒ<)(¦·?©|àŠ6ª¾æ¢ljZPKÙs*y�ÆÅhœû•5�¼ö/‹ Žl{Zä™nÈÔ*X•úÂ|È|è†NÛ­3H|8ŒuÝÉü½#ö›�ž3ÛZDp™LÆôHcú⃾ú«ÅõÀß?ÅÅ?y¥ìÑO�|ú�¸úÉù¨�Ž¢.2ŠúÈ(b‘êÂIÄë2ˆEFÑK¢.<ŠXt ‘QÔåd¢$«–©�&•òôݯ�$•ßµ¿Çcܵ†¬ëÂ! £Å;T‚¤“LuÞÅtIˆâ¬�ZðäP2Œ�:f'Œ¦†"‘Üg%8GéXwå‹4ÕqWüÅ4-ÚÖÅÆˆòŵæAgX3 àpèa^Ä þ˜}ÈŒ¦ÊO›à€ÕÊ#Ãö´¶§­ÌâÚȲ=Íö4ÛÓUæ^À×lO{÷^µcOÇ£h¬K+~ã†hRñ'“_¹>’RýÏт߸.’RüÈäCÖüΊ_9ïN"+$ `¿²øØ™©—¥6õ`B=ª¶w8ŒæÆ¡\öÎ*§;iÁ+V}ËÆ§?© ª�@•?)ª(øEwRû•ÅØmÉbÌ=K±5rÞo\ä_Î9’CE¾æZû—E`rÞy®lYÁFvÛ%‡Å{¦u‘óa<¦í¿ªÜH|¨í©ª{¯Ä…*'ª¼˜Rä´¿·Ö6�÷YÍG4ˆ|htZ¢º¯…²Ï:Fÿp�ñ:DÂê©…Éâ Ÿû«ù Ÿ¹ ÏÒlÖT¾8»ué‡jiQp©Æ‰çe §'je+Žó¡¹âz!¡l�¦Õ}V%™�ƃÄt%ûªWÖx_Õ,2ùƒýÉvF€ËŒg8`u<�>÷½ ��ö~]½£ùß¿ºÿLüàÛÛØFŠŽ�¢`Õ††ÛuxQð¯K>Á•ÿóZÙ£¶žúžòÅÒ[k7*Üsy‘ØVŽÑl7êÂ#hŠÇsÉ$¢‘\ `QKC¡  ERa忌â‡s"ƒP8 Z:©2eA¦ßéÏ¢ò@#CýhllD$ÒÕ«”¥ƒ`ŠÊ‡sõR$›a½Jð›ºÉ­=Ÿž©ü]û]“¡h8ú»²àË• ‘?žk®ß©l™lé EÏÑßC 2õwÊ•ÿ{î~šäéïŠLH1*¨ Õ¡ÖFV“”#ÚÉYF÷D‘VÊ©²ôE›úgé4-WcÊßÉèɤéw*†ÚVú޾ÒVËÒ±ùKY¸æ²U*º•A6Õ‡P¤EjVLwæ‘:NÅŽ*Pè‡pD‹sÔG8j1¹ÀGÍÁ¥FBªgÍçZªâä¢$µsèÉ)!›B(6!W®\¾Í2PñÍ’Vds8+…ª[Êÿ”ß õÓ¿CC³<è¾"’F6¹Ạ@(¦¶WUZUÃóA (…ú•>×—û·R¦¨õg}d¨"’k«vKµƒrA§ÙPN…TãHm.á™BêÑMn^_˜Õ‚KNý"Z£ØbÓVi� Hë0½wR)å¨&;G=9mó Æ=̃ W2 N)æAæAÀ-TBEÌ-þØæ�%HqÀª•¡ÛÓz¸Øž.ØélO³=]þ2áu¯#Ü[G°=m‰¾ ûÉžŽGGÐK"’éQüÊ�ñ¸üUaK/ò+Wò+~f²sþã¼o9çÎû¡s~fòŽŽ  ©1ŽH$\ðC“?™ÊdÕ?©ÕUðc“+Ç™9Yò3ÓE‰4?²âλö4_wÎ÷œó%û–UrÎ¥Vä[¦ßÕ �TsDñ“ï�|·T"ï7&³æw&Ÿo6ç;Nç|ËÚ¿IŽ|ÀTùšs~fª/£ø•É/LuET´â?&5ýN2Y-ƒZÎ§–¥ßT?³öw ˆÉ_šo9p~eêA *ÞÒꟶ§P�Túœ÷“êEŠïå†* )”2©~úBäãÍ_šo¹äyÊýbß²ÞÇ›÷ùùo5Ÿq6ïã%‡-ùü×!ëD‘|‚Õ7žóMù¤5Ÿrqî#Ÿt©9ï7Ö\â…,J"ƒ\Ö‚|0©Ö­œs™|é!üÊüµ´«Ý²§“‹Å ˆûé´®Zø•µ¦ú‰[ê•„A‘lêÃÃhlŒ+ÿ6úÀCáOÑÞªÆS%{«Ú>k.$n#>@S“ʇêžmŽ‹÷r‹öhÌËíÝ–ñžÊ…nÌñœ2çõ{¬ù}Ö’=V�0ñPšÞ´J<%ÀƒÊi¨À›Ú¿sœJuŽjû­EÜUÊ�Ä� æömGsû°ê>jÎ~TöVsÿN‡�ÊR–Ñ û«š"†‹8PÝ€,ì…"�[Ã_”ÜSö; �’VøO·—KO$>̦޵íÃæ€Ìñ“ÑÞª²Iú&º·šãoµL™ä:„ë:Õ¤G–¸¯°çZ¶‡›ck ¯r~S!Öš\èCÑ>´Ñ{×¥}ÖZò^i7eóû“-8‹�{8`uÜ«PŒÀÌ/-Eï@*ÿÓÑmˆ+ÎÜÚHDptlt,V´x´U“û…V­Áïôâö>Äïõb`°€�îé.«æ×ÓJæÈBQyÁ_¦(*™#×#L€ŒÇ—_‹4\ù";Ú�`Uƒöóü°?ô.¹ííøÓõr3«‰?æ}VÞgµ¦Ḟ̇Ö4&ðÒ~á=7øƒýÉ�WOî€ÇpÀªÇ€óãü�À{,EQ°æ7ù¾{ú-7šR‡Ó—|‘HÄrÙZ8ó/âñgWײ ülF€`…ÀÁ{NÇO.š#­ÍAåiÔ¸"æÁ?ž`‡€lô_÷½ �Ió#‘,¤ÑYpÄ,\tʖ«䭫« ,²+V ! aú¤8>zë%tÎ*}_²@6”ûIÛ¼¥gåçâ{EÏ—QŠæ „Ô.ú«VI6‹l('—ÿ�nS‰l¡†Ü=ÚH&qõ^ÙÜJ Ù¬b,ª¿!¥!„èôHEˆnvØÆ\à �êØñŸ�EíJÐi ímjð)LmÍQ´µÄ0eb£ò'Rí­õhŠ»›1;èüáÆÕ¢NæÁZ ÎÏ,E€y�u *ñ`»Â}õèœPï)zÑg«ÏØòÀņE8`µ2’lO³=muž±¼|ßGÎÁÁæ´||¹F¶§YŒ°mOÓ[«Èÿ[ä°U|ÎÒüÊšOXqe«þe­~Õ �UÛ¡¸Šs¾ãÜŸ$œó:#›Íù´sþfö]úo>0úoLÆj‹&vÔƒlh%5÷ŸêcVÿ›Ø^�VÅÆVï76¸ë_«8õ+�Nûâ„K V¥+‹å›i›E÷Y ›åüI­Èí³j{¢*±~WwYsû­ÚþiŽåQå·¬Êwô§RA/RùÜ=ú]ÛƒOúçç¾2úyt‚ß¶¶fÚ/­CG{ mÍ*×u´×£½U H%¾#ÔþlnRùýt¹ÍìOöÓhs[‚€¬a”¸�ž!Ð1÷oH¥ A” �Úç-ÜBèùnœP#$ }¼r.ü‡Äk[U$B,F4B4÷§öïH$„ý # !!¦?¡üÊŸa%\V�o%/e!t6›É"CNÏl™té,�¡ß2Y¤ÓY¤r×äH6“Î(GŒ*Ïd�¢¿§3H“l:‹‘¢ÀéÚ"Wƒ§kÈPñ!kšÆ¡èç4Šé7ê#hjŒ¢¥1ª“67Å”7+¿ÅÐÒCksTç,TŒ¦Ö:´6H¥ý¢ùèõWÙc�?ü¦+vÛ3¾x0ŒX¦<ˆlF}»Åƒ of˜™íNÛqUNåÁˆÂy2yp\�hÒYv0Z×¶§ ˜�¯uÛÓÖg‹;%Jmfò9„BjÖ)`u÷ ÖÊötG-Xmkbò'+þãH‘h±ˆêK¦ß4ß²9U IDATâOŽ„rþå0"Kï`r/“SYÉ™�KÈ�Uÿ$o³ê3Î(¾Oò ÿö®NŠ"{¿Ý�Ý�Ý… `@Å€ž˜H‚"ˆˆ"ˆ¨xf=õLg¾óÔSÿÊîLgÎ9`Î ÉQE1�9ç€`–eÃìlúÿ^ÏÎîôvÏtUuuOÏÌ7?ù!3¯ª«¾÷¾~ïU½®æóß¼®ÜÒJÆß�ëÊæ5åÖ¢–¶˜,Ë4·¶RK Q´©óPŽÌ²w£…/t‡_®µæ\ºÌÈ©CÔ½,öÿ¼¶Ìx�™×�;Šsø >ø {¬X‡eðI¼–Îë÷é~`À®Xµ+"Ùäí|aQû¾*ûDÞƒåýרÞj»/dŸÉþ�ÿm¸ÄÄC‰Ø#ÆöUùÞmü;/î Û}ûÃæ–Ø~k²=Vc=™Ûµï±²OL<œ*=–êÿUáýÇ<¯È~ÍØ[-ã?±ueÃÿñ¿KBTQ^db` ¶Ÿ n©Vdî�mq=ùá?°žœ‰¬À˜Ó‰ VÓ‰>®8*†N3½öñÄC·¢³ŽÝ¶óá³$#-6JG!”*ÈË­§½�[(´/5‚æSÈ(µ/í�íXØk_ôcyng´O\ì,8åBÓÄÔÂB^Œ]'^„Úµ85~'":àä–2»zëZ¨1ÚB‘Æö¿#­±ÿon¥†H 56¶Pÿ»±…"írœÀ56¶R3'h-mÔÔÒjc77ówmÔÔþ·QPÛþ›!×ÜÚñ[´)V8Äí:Ú·ÿ›¯ïÅ'1¡ŠŸ”/ŽŸµŠM6/�×Û''6ÅE.* ~õ_8œO¼!VÌÿ_T@ÅÅü[~ûß±—çÇÚ°\ûï†,÷j£Ò’ªª,1)N¨²å“�þ#[tãäC±Ïø†•å�Ÿü Q³áKÂÅJ~0ÈúŠóÃÉ644ScSk–øÁÎÓÅáƒl�©Ç¦Ûò),ÆCe±M3öƒðÞÛå1F>݉™S‘XÜ‚|ZÞÖº¶@>C¤ãí3íǵó&~«±ûÛÆûKÜÛš=èŽ#�OÇ÷ûÁT?l%È×pòƒŽùt{ ¯y·Q“P$ÿwa{Áh—߸M纴umÚXWåµ5rápQl »ýz×�Ël�ýŠšÚ&£p‡×s#�­Æúql­¹•"‘fãàã߯ŸVjŒ´¯-¼NÌkÇíó¿ù`c­8¾¶ÿ­¥}M9a¹Åøsûø¿½*$‚/Ì@c•rIq•¶bÀëÅFqiI,W6òæpˆºu+¤Òöïº•Ä OÃa~à3V”SR”GåÅŽW†ÿp„Èw�LØÏKÅÉÆÒ‰ý1ïi&ø¾v_Ôá£:dó�&xÿ%~ O§ßìô}¼ßkMô¥æ=Z2öX¹Þã=™˜/ͧ¢ÂvŸÙEÛ™Ä�ÚúfÓºq$ÚF‘Hçž«±¿�í³:ùÁ¸ã}Vc¿µÝïÅ÷W�}XÃ'Æ&aš(Ë¿ÕG¼Ù_�'„±SVù�E䃾ߤ\\°˜÷L y´}?µ¨}?5¾—jì›&ì­ò¿öZÙ?Æ÷X‹Šò‰ÿmøF~(ƒÿ. ßåêÇ/ÿ�õä\µ0Ì[¬ª"‡vY‰@ù�i¦y�|øÖtæÑ}^—`�¶èf±_Ž0+ãѤ‚¢Þ\ã䮸Øy‘Ä#(\uËI\SBÒ+z�-^6F›©µ-�š›b œ,/~í(ŽmŽ-ŠòÓÿ+~k žûÖ(Þ�'TñÁñwÚ¼œ¶Þ¢[lQ´©•¢œ òjkìt�؉¶�ÿoœxkœJ;õÖ(àmÿã©Ëöß¼*Àu¬@cN`x¢ ?¶8a<ÅÊ's7Ÿè�Ï‹¼ØÀß',¼‡òbŤœèÄ H 9ʧpIÈø›IJÂ\xÚ^HZÄ‹±ˆÛÅ Ocm: L=Hv2�©Ôÿ!`ä�ÿð^1™Ä�T~Ðð‡ü°‡ƒljŠ=òÃϵôè´àM,•,àòóùµl1)ëã¾.î+ùA‹tøA;(2‰‚ª œ‡¢;ì3Ýv\Ãô yì¸1a@ȧƒ ÿÆ€xHÖ:óégfýH_~¿Îöµœì Çíº‘q–òé˜î�Oë±átõ‚x(]È»¿.ü‡{ �zÈ4~páŽá›â…?íkËFñO{./ž�¯-Ç×¢c·çÔÑæVzzÆôõ�µÒ¾�¯Ïí�þ¹¯ö5ì¦h¬׳â"'ezü;ºkËÆŸxîÌÿOÆ)‰¡âsãÿ9¯n—5Nîøwûº4¯C'}ÇúŒåâqY>�˜¯ÉŒ5éøºrûA‰…6±µëØ6¯=³ßÖQh“iüðØ2ª{øïÕ~x�q×+𾬽øÕØó4Š2/Ž�í‰ëÌ퇴|�C´…ž˜þ}÷s��dÿÆ~�÷qãû«ì‡ùÔvÞkåïã'¾ÇO¸�ŸþÛW�ŸŸÞÓlÙŸÄNô�=¤ÉóââÿŸøË/U�Ë�ÚÛëÈ ýðÁÀí§s›X?±·Ëþ+ÅÞ*˄á˜ÿj/6�æSÄŨíß›öZ‹boEÁÇüòXOöFè5»@Ájv볓@€ƒ¿ªa/›ZœvT_:íÈ­“¬ŠïÍÍÍÆ“üxš_B!‹úœ8MƒmƒÇ’©Åª©æ§Â�å¿6Ð^Ç.0N56N�±9æ“ñ*C'Ãrù;øá@�æ*üè"> ~xr.óã£/ªéмž±~ü?¼GÀŸ+ðâ|¿‰(X•Aù´ Z™/‹û½÷:T‰‡.¼þz~îÏ'­våÁã7£KÿÞßûÁçøÀï @…Þ� WAüAÉ�L®óã¬+–Òì×Vf¤/?ÜÙ¾Hë\ç‡FA•?¼× øá=Æ^]!Î�S.~—^}ç·´ù@ìws¡/êA¼²sÕ~ýôXOVÕÚå2(XÍeícî&ø©Ùõv6oJòéª|ʪQ5Ð¥pŽƒŽ]èðá“3ùØ}þƒ�3|Š&ÿñ²¸×Ïà$ÕŒ³9xWåGõº&qÈ;ÊP2ç>0†z÷*u6¦,”?²C©ªüÈŽÙ{7 ðÃ;lýì9×ùññWké�3k÷ƒà‡ŸVìݵr�^!kÇ,0Ê£�|Z3/Zà~ïªþ÷©z¿¿âÎOè‘¿·=Q‡g1pÛJzü†Ü=!üðß–½¸¢*?¼K6õ ~d‡6Á¢ó¯yŸ^Z°\«/?À�ì@À›Y€Þàêw¯ðÞ î7?N»ø]Zøö¯Z} (2Øïæ·|¢DÔ^Œýþ,¬Áz²Œ@Ä@Á*,´#il¥ F˜ VÏ:v[:ñЭ,«txYP©C)ìè3­HÖ�à$(#ïü'ëPw úpÃ�øqùÉì—?í¨­éô£úºš3øaøáʬ„»á‡Ð4�à‡3Rêü úì›úóé¯%]XTñƒˆ¯”Ì1p�ÀoT’ŒX`”Çù´~;:þ -M«™¼åQ ø�'�øãe!pPŠñX?MÑ(…KJd ²•å@”?A)NÖÁ�AÌ¢ÆH %;”¸ge-xxO* ©�Z ~'x· øáú¶àªðüpe@.ëð../ÔÔ~|ñ] pêkFì©Ã"¾R­E(ã+5$Ä[ùÁñшI¦âGªÆ�TÑüFŠ]$‡¤�O§Wٸ߫áŸm÷ûûžþ†®½ïó¤1Ï÷â3Ða7SŒˆ²í~¯ D—†XoÒ…dò~�/xƒ1ü‡®Ùæ?ÔP�kå—ÿ¸üŽØiãÉòi_~Èé8. ~Èãæ?äG–Ú/ó¯ØÏ“Cü�Ë¥Á{Ììò�3ÿ³”æ¾¾R‹ÕöóD‘òFüç‡70÷Šõd?PÆ5² ¬f›F1ejj›©÷虦öÿ:i{:vrË «Êñ¡!?ÉÄI¢—‰¢îip`͉ZA�»S>R�+( Ûis~+kÊ“®R ˆOõãuíAyý˜Œr8 e|B¡�L3iY¿t�j`Æ?(öÒU7ï|¸ŠŽ9ïMGŒøÄ˜Å�ïEUE޲,”ù ¶]üHŽV®òCÆ~ddÁ�ähÁX± нø¥¿çûÒüåtþµï;R8•„ÿ€ÿÈV~8C@@”--mÔß¶=b�ÑhäÓ¨YDÔžÝ^Ö¯{ òiyMuÕÍþ§¼J|Z{ê5*¢É{mBWœ=Hø‚~ÇCÂK!~ òëÞ~ Ÿ–¹gÅ^²™{»�–ÿZ¯ì á?à?²™2÷+;Yðü?RÛ@º÷»G6—V¯�*û@Ñ{ö»í‘?‚ÍQûv#ÇëÉý&N#> //Ï\û‚õd7È¢m6#€‚ÕlÖ.æ&…Ào«éOãæ˜Ú\|F:tŸÍ\¬J "‡„eÚL†F6‘çcüùÄY¯ �ƒüš€Koýˆžœþ££º9ð?õ¨¾tÆQ}e3QüH®µ\æG&Ú²c?À/ì*(}ž{õ{4}Ñ/ŽÃIæÁðÃÑxrX@†© Vwê_Eó™ÃHÚOù´¿&!cÏþŽLÿÕ�O‹aºjM#�:bž�paa>½ûÜx* å Égšø�x(ÓlÖÏñ‚à‡Ÿöæ÷µÜúBðüðÛf3ézàø‘Iöê÷XƒÀ·>P3äç¢HA.Ž@øá—6¢Ñf¸ß ÊË+°\ëÉ~i×É4P°šiÃx=C`ÅïÚfü\Sÿ—�9€š°©RÁjP^ æ`.:æ‚3Ƨ¨HìtL—J{Sĸð4??_h,Œ�—'Îrÿ<.ˆMç'?F9�~_Ý(4´ªò"zýɽ„d3IüH½ø“ËüÈ$;öj¬àø‘íñÕÈÃçÒêêÔOÂÇ­ «?À�lç‡ß"ˬʣ�|Z3Õ²ö¬z� ´C>m¯»ûý³³~¢)7}(¤¶¶6¢«ÎHûïÙ[H>“„ÀÄCˆ‡RÛÖcíñÉõõØLºÏ§«_ÿÿÿÿÁ ÿÏ?²Åw¸�GPü‡(Šø~ˆÚJ\.(ü�·Š|¬0—hà~³l›£`UU´ÉP°š ZÆ…øyem?Ñ|ÅÏHŽë-]°êõ €B ¨P.'²'™F£Q*,,ôìdÕ¦¦&£o�€É¿&ãÇçßÖÐ�§½f±Ü¶öoºžý§Ë=vî´ãvUµvùa�É1Ëu~È[Söµ?À�l�¯ÜøAðüÈv~¸ñj*ü@Áª<âȧå1Si¡bÏ*× BäÓöZHv¿?ý²¥´`ÉJS#.L5>yƦOŸÞÝhú=£ƒ jmc?!Jnàø‘ üPõ…àø‘ üP ¸ÀðüÈŒøJÕŠÞ�ŸËå碸f³\.ú�¶¶<ê¿ï [µ¢`5›­ssƒ VÝ ‡¶Y…À�+¨ß¾æ‚Õ+ÏDû�ÝDª`•‹¹€OôDͬÑa2Œ 8†Ãᬟ¶lðÞØØHÅÅÅžáÂÅ~\¬Ê±º>üÔ1÷ÉD?©øqÇc_Ñ-iéŠ÷Øø ¼ÙÖõRCû÷ ‡þ·‹èå-~$WøhÓõepàø‘ ñ•ª¼ïò¡ˆ¯’Pþ×[t /¢ê?P°*¯VäÓò˜É¶PµgÙëAù´½’ÅCѦV~ðljll55L•Kóo¯>²'­ßÓ»u?m ü@¾� ù‚*§Àð#ø¡ê ç?8šzT„°_aCäÓªwÝìiÿÿ‘ þC•±A⇪Í‘ŸËåçª6•Mí‚įqMäÖ“½Fýg#(XÍF­bNJ|÷s= ܾ©í5ÿÚ‘&ŽÙX¸`•‹ùôJ«ZU`'ÍÍ.)QÒO&5’}�T$ñtQŒí’O#õ² VD?Nü8äï¯ÓÇ_V›7ØŠTy]‹cùßï½8�Š Å‹fEÆê· ø‘qðÃok ÞõÀðÃÉÏjÕF¤ê—<±;•——ª]4ƒZ!¾²WV®ðCÅTÝø,0Ê#Ž|Z3™nìYæ:A�Åý^þ~ÿÊÛ¿Ñ)¿ciè3Ù[KöÙ}ºö¼AAP»«1€È%·ðüÈ~¨úÂñ£zÑõÿ7Ä•ʄƈ¯äã«LЫ—c„ÿ€ÿÈÿ¡Â£ ñCÕŠäƒðð² ?dÇ/#ß•XO–A²@ † Va @ �¯¬£Á“˜ð¸îüÁ4aôFŽ«|Òd}}•””J¿=�KÁ Ÿ Ë'ìŠ~" žñrRÉö™ÎSmEøQ½6J#››tƒ�06ÙlNY=vrú×IÛ‹B89ð#Åâø8{õ{@àø‘+ñU.ûA‘û â++J"ñ•¶Ù*ãÖ`�QÞ2�OËc&Ú­=‹^'r¸ß«Ýï/½å#zrÆ�¦ÆñÓUã_vý7_T˜o<*ñÒ” ˜‰i àò…\ÉTÈ~€¹Ä�\ö…N÷ÄWjñ•®Ùü;üüG.ùY.‘^ù@øø�là‡ìDåíø�õdQô :@Á*¬´#ðå÷µ4ôÏ MxÜtÑ`Úk×�Rbħ>®­^CÝË+¤ ƒ ê멤ԻÑøµ=­--ž^ÃiÞ¢üxvÖO4å¦Íl| å™6Ïâ'Ä$ v+-¤·Ÿç4m¿ë´ð#¹ZÀm&ëkGà‡?pƒþà¬û*©ø‘I~Ð �÷§kÙý~¨ –þ6:íFG|…Fy›@>݉YÐìY^›b-tÎSìŠf)Üï;ñ}ä<ú}uc—|šÌ¹´‘][?ç�¸=s`(µÑi7:î÷J“h¤sž—³ˆ€*¨¥¿�N»?°Þ”kû™ä SÝmtÞTîjð*¨¥¿�N»�ÿ€ÿÈ5ÿ!Ãà ò#>þCÆ’‚# ÿ¡WXOÖ‹'zË P°šzÆ,øì›u4ü�E&É[þ=„ÆîÒ+eëµk«©¬¬…B!�«Ø‹è ”ÑÞPöxÿT×ã¾xnEEEn‡¥½}º1¯¯«£Ò²2íóŠwÈŪÍÍM†m¦ó#Ê�Ó/[J –¬4 ÕUn$R\®ðCŠÎ}€ÎÅ%Ò}/K)ø!®77’à‡8z™Ä�LñƒNè§sðÃIC�¿§[WA÷X`·¥¸$ò鈇ämG¥î÷�¨}þm xÚkæ\Úx=‰¹`•ÿm—OoУ˜=º§Š¤Û€Ò�)5?ÄaC<$Ž•.Étc~ˆk2ݺ’É2ɦÒ@º1?²“Ⳋå2ØÏ³G ü·¤tßËdü‡ø¬‚Ë� ø@ðCÜ’Àq¬tIú‰9Ö“ui ýä(XÍ%mc®)øä«Úå°WL2·]2”Æ ß0i;. äBU™WÀwíÌOGédütXaa¡“˜Ðï|:ÏMWB’}��`·Bb|âh¤¡ÁÓSOƒR¬*Ê�ææ6ÚùàÙTiéÀ�qêzºjüG»M¶Í7)£™÷î.¤U!ðC9ñvà‡8V, ÿ!‡—iø(:÷!ê?Rõ”IüÈ?è¤9ðà !=¿ç?dPÓ™0/Lša{ù¡ý*iÁÔQ2CË YäÓDȼ7uä VŒïæ[ºö¾ÏL?Ø=üÉÉ}èš4´_•§ ?<…×èü�Ã8“ò™™éŒ‡d®+"‹|A%÷2¹˜/dŠ/L¥]ðýí‹ô�‹üÁ…eà?ì‘B|%jA19ÄWrxé�¾÷©¯éú¾HK>~Èiü�ÃK‡´ßñUâz2ó#/¯ó=7XOÖ¡Qô‘� `5µŠ9)!ðÑ—5´ëáæ‚Õ»þ³�º�mnÛ90áO~~¾Òxu7âd½¸¸XK·<7þãæÔY-éÒ <.7ÆnÆÅ×oŒD(\R⦛”mY�MMQêÖ­»g×éX†K?^M9w‰9¡j³žH¶ÉöÔM#©_ß ‘áIË€Ò�I7?Ä!ƒÿÇJ—$ü‡.$�û‘ñv½e"?2Á¦Òøál׺$r‘¢ØéÎ?P°*Š|§òiäÓòV#×ù‚=^Ç�ÿ½ùÁ?Ï~Úœ®š*ŸÞ¶O9=w»w…øÈ§ål]EüG-óÑÙ鎇D¯ë$‡|Á !}¿çj¾� ¾0™–Á}öïÔS®òà þþÃ%ÄW"Ö“A|%Ž•.ɸÿ8ñÂwÓ’‚âš?ıÒ%™®ø*¾žlÊÕ¥¼üκ¬êÒ.úÉ6P°šmÅ|”øàóµ4êÈWMíï¹|í:x}KŸnŸ‚áöüTGPN�D"TTT¤­xÖï'VD”žî¤›¯Ï‹"ºŠ‚íæÌ›@Ñh#uï^.‰g2²ü¸åá/éŽÇ¾2�§ë“G‰?&Û€²C=|ííó?´Cj{O?Äp†ÿÃI§ü‡N4S÷%ë?ºö–©üºL¥5ðüPE èñUê‚Õ*Z0u¤êÔ³¶òiäÓ^7òi{t#‘~ðljjn¯RMqŠj¼‡d§¯¾pûnÔ·�þ_ƒ~¿×a·ˆ‡t (ÖG®æ bèÄNÇK×CúÉÆ~ˆjϽ\®ò#|!ø‘yûÙ²Þ$zg�ÿ°"…üCÔzbŪØïÇK‡d<¾jnÎKK>~ˆküÇJ—d:ó^Oî¿ïËDm-”—o~£1¿Õëɺ´Œ~² ¬f“61W¼÷ÙZ}”¹`õ�+‡ÓðAë¹ê׫äÖí"T|\Aß<Ð1Oîƒ ÓµhëG@ÊŪ��*/÷æ„Q­$HèlñÒßé?·~L?­¬ïø¶  �8¨ë8Iµ­�Úòˆv´>�}ü¶TZT@/Îÿ™î}ú˰^¼c7Úz‹îÚ^=~x¥ùÎ~ÁqŒua¥ã¾Ê£?Äu§*©Kç©®Ÿ©þ#[â+;?0#ÑŽÛ­¹ß–T.òƒN6§ã>€øÊ åàü®ë^¢Ãn2Å´¶æÑ€I3l•ˆF{ÛF>­çÍ)º7‹uð÷ûàÜÏGR½®‰nyø z|Ú¦öÞ°„~ZÙ`¬�P~åµµQí2x=:ÿÄí‰ V�=ïMª©m2µ7²Ýxáã;v“)÷{·o=?‚É»Q!’Ó•Žûø!‡y:¥3•É|¡á)Ïä ÷ܵwЖT.ò…©ô~ˆY+Ö›Ì8é°ÄWb¶çVJ×=ë±âš?ä°b?·®¾Õ6ìêw²>;yK*))Ðæ½.P†ÿ€ÿg„«tÖƒD£-4p¿—)//d™Ö“UµŠvÙŽ V³]ØŸ0Ë>­¦ÝÿòšIþ¡ÿíLCû÷îÃIPW¢ÃÁ`^^žëQ# TXT¤­�S÷æZss3…BV§î„sâïé|’&¾ÑãupÄÁ{$Ò@•2Ф]6ÒØJ»1—j뛵�ep¿4å”í�¢U·Oà‡6µ$íÈ�Í‹LåGWÐà?äìþC /ðÃŒ“ßñ•W~ðâÓú~0Ùü?ÄH/?DÇèUþ�VE5Ð)‡|Z³®-¼²g7#C>í=oÛÞýÄ×tãÔ/´^äü“¶§#÷Û ëM‚¨‚‚@@ ù´œ�/ˆá…|:ýù‚W¾ðèÉ}�O‹Ñ ©ø‘~~ˆ¨ù‡%ìWˆXNLñ•8V,©;¾J‡?Äu~ˆcå?ä®iœË IDAT®GšuÞÔÔJ;0Û¶C¬êÁ½d(XÍ>�bFмûq5íqŒ¹`õ‘ëFÐàí«{47ã¢ENÝ`rüq{Z¨Îb<]sKDŒ_ÎXqa®ê‡±â±¹Å\õú|mþã¶p2Õõyñ§¡¡Þ(Vuƒ•êÝ´ûaE=M8n¡›.lÛ>q3šrzWý‚®àj ~ÁdéºÇˆcÿ!ŽUº%3™^ùÁ#&mN�ÚÏV5ˆ¯Ä,6“ã«Äf2?œ4¥knÉò¬:iÀú;òiyÌâ-¼¶gÕ‘!REΟvç]ó>M[°\ûÅ=2†6èYêª_äÓ®àjŒ|Z&äÓâ0uH"_ ù‚§t­7yå _{lOêYUl1ðüC üH5Väöè ¾·p]6”.ÿ‘ üðÛ‚à# ‹ûÉÖcÅQ¶úÚ Ôƒà�]ªD»\F«¹¬}ÌÝ„ÀÛ­¡=�]lúîñëGÐÀíܬê:u�ŸÀâ�ÛL�›±'Fš¨¸Øºˆ£jb¼èWXXèªÐ3Ý›kªs—i_­¬to£2×Õ%ÛÒÒFý÷µÕª›k>isš’¤PG¤_ðC¥àËd:?âÃÈÙü‡^à‡§tÅW~ûAðüC üH5V?ò�”«ý«hÁƒ#UàÌê6ȧÕÔë‡=«Œ ù´ jþ¶¹õ‘/éöG¿ÒzQ~^ø•G÷¤õlŠtD/„|Z©`Ë!_@<¤j¡ðªÈùß.Ö›üô…ȧÅlþþCÌR¬RðªÈùß.üG2Ô2)?÷Óúaeððªv$ÿ�õdU-¢].#€‚Õ\Ö>ænBàÍÖиãÌ«OÞ¸+õ߯ÝkÖù‰Žh4꺠“‹)¸/.ätó‰D"FnOhå1pðÞ‰PI©»Ó7çÃA)亟®Â“Äq1öA:Á”õá“U+«5.Yۼ뉯覩_Í6覃Æojüÿì×VÐ7?¬£6Ê#þ�Úb=——…¨!ÚBôÙ}zoXJ·_:”þ´yòW!§#ø!«Á˜<ø¡†›S+ø'„̿Èá•-þ#[øq×_ÓMí¯óe?8pÛJšóúJÃïåQ[‡\¿ª˜òóó(i¦úFy?~€b˜¥r9ÿÀ£¼Å Ÿ–Ç ù´ã5úõ�ˆ˾c6¦Í6.£ÖV¢·?\EK?^Ý®6 PcSkRO8d+úç_·U†ù´tȧÕpsj•-ù‚Ý<á?œ´ïÝïÙà?âëxÙ°_aç {÷*¥;ûÚ´žÌs. Pi¸€"-ÔÐ{ƒ�ÝÇÎ"Ÿãø�|ZÌR¬RØÏSEÎÿvˆ¯ä0÷Òtõ�[nÚ�¾ù©6¶—š°§ºéÆ¥D­Dõ‘f%(7c5iøø5Ë! šÿÀz²ª&Ñ.—@Áj.ks7!ðæû«iÜñ¯›¾{êæ‘Ôoë WH5Ô×».èäL9(**r5�']ð+‘H••us5¦ÄÆ”r±ª›dum¬'Ž‹±çOP V§†ú:ª¬ê˜1©óã³ïé÷U5t*-)0ººîþÏé¾§¿±t;í®Ñ´ázaúayý¼²ž~þµ�~øy-ÿµÁxUÓ)‡oM}6U³IðCM‹à‡n"­à?DPŠÉÀˆa•mþÃí3A‰¯–}º¦ÃN_ô3]|óÇ…Þ2e�ÑËø¾¶¾Ùäú¥Îð‡=* mý ø~ˆ!`– ?GågþÑÔÜF'Ù¿ `H¿*Z8'¬vµ+äÓrLóÓžeF†|Z­ôËþö{ -^¶–l[izhsñÒß餋޶ ð¢SûÓn;­GËWÖÓ�+8Ÿ®7bŠÕkiÜ®ÓQûo¡<)äÓjÐ!ŸVÃM¤òi”�O‹£[wȦõØlɧkêšiÞâ†/ìÓ»ÔØ¯Øé W,ª=lºãÒ�Œ;~ù­Þä ZQO«×FiÏ]zY|!òi1–€ȧÅ,Å*…üC¹ô´C|%Ž»þ#ÑÞóÔ74mÁrË<4–z­6¾g¸ü·:Z¾²�Ø÷q>˜ÊŠÏV]þþCÕz‚è?°ž¬ªM´ËeP°šËÚÇÜM¼ñÞj‚¹`õÙ[GÑv[•+#U_WG¥eeÊí¹!oófV8 (U?:78ˆ«ê*âäñ„B®N�õ"8a¼ƒtÚïõuµTÕ£gÆ«¦âÇÃ/|OWÞõ‰ÅÜï»r8í2h½ŽïÁñ;ø!ŽU$á?ĵÿ!†U®ø14‚_=øÜ×týÖ6î¹|í:x}ÑéuÈ�b��ÖÅÑ\Ï?°À(Æ�D)äÓâ˜!ŸÇJ·d®ÜïyÓqïãZà;tâftñéý‘O+òiÐÒØù´8øÈİÊÿ!†Fpóéø~Å�gS$b>E•דy]Yæ~ˆ¡~ Ÿ³«â+UäÒÓñ•8îéð9w‰Í[6ˆ>zy*(à#Wcìw‹ëQFüG+ü�[~`=YiÈ�NP° kí,^ºŠö9é Ïß>жé£V°ÊÁI¸¤„òóó•1æb¼æ¦&×'´êx’+> /þtﮆ‹üT^~A»ÂŠ*÷ô†ñÅ>YÕ�]ažNü˜õê/ôÏ+ß³ õÊsÑþc71¾?Ä5ÉX�âx¥[Ò‰"ã?DPŠÉ€âXA2ÛùñØôß覩_X ~äº4xû*) ¾ƒ+—â+Dà?Ú}NX1“ òi1È�O‹áä…T®ÝïOže)Öé×·’žºiWäÓ’†|A°4‹g{¾€õXÿ ,×ü‡™�/ì|ðª©�­…Æ?ƒwèA�\»‹Óô:~G>-øaÆ)ø!¦ÙÔRà‡Šàø!f)V)•ücô‘óè÷Õ�¦Î6è¦E�ŒU†§íÀðCÕÀTø¡z-Ùv(X•E ò@€«° ÐŽÀ«ïüAûž¼Ä„Ç‹wìF[oÑ]#~:¤¨¸ØUQ!;Üh´‘ÊÊÔ^o΃nmm¥ÆH„ ‹Š( IÏ£k>i©¡¡žºu“Ç$ÙÅ9¹åSZ¹¸Wõ�F�>²½Xµ®v�q²j¦«ŠðcÙ'«é¨sÌ|dûøç_·¥ÙÊ(0?Ä~ˆá)~8�üpB¨ówðC« Hæ?n|ð ºûɯ-p?wÛ(ÚvKñ‡…_‰Y,/ŽæR|å„ üG'BX`t²ëïȧ�1C>팑W¹x¿?ú_oÒ»­2A åѲç'P[[3òiAcC¾ T@Är!_Ð5ò1$sѤB&Sò…ÝŽ˜G¬1í$>´á¤}ðà ¡Øïà‡§Lᇘv“K�b‚à‡˜¥X¥Tò�hS+ Úo¦¥³�ô¤©Wï¬:ÏÚ�à‡ªq©ðCõZ*í°ž¬‚Úä:(XÍu Àü;xå�?hR—‚Õiw�¦­6“+å@«¨¨ÈUQ¡ŽSWøØòššµFÁ«ŽbUc¢¡ÁUaiWsãä–ÇYZV¦l‰ANxb\8ì¦È4«‚wA~${…á‘ûmAÿ:¡¯ëS~ÁeÊio~tB ÿ!n^ðbXå¢ÿH…L&ÄWWÜù =òâ÷–i̼owÚ|c±x ü?İ.Žº}‹B6ÅW©‡îPI ¥sV·A>í¬^äÓÎÙI _PËþwÏgôàsßZ }üú�iËÞ…®Þš“M÷ûTV‰õ&5Φ«òiqä‘/ˆa…|:só…±Ç, ¿5˜&ÀoÑã·é9}À'„b¿ƒ™Ë1 ÛK�bè�à‡˜¥X¥Tó�Ï¿­¡O{ÍÒáAã7¥Ëþ>@u8¶í�Ÿ«åçÉ”� û: (WüGc´…vÜ–-dXOÖaIè#@Áj6jsRB`á[¿Óþ§¾ij;ýžÝ©Oo±â#Q×t²*ŸbZ^^¡4�x£êê5ÆI¨A-Ve¬š[š]�ÖÚØØh‚Êœ¬Ê+|«_>E§  @ùrœÜÖ®«¡=×sUô*:·ÉFªëÈ𣹹�Lšaénì.ÒåÿØüP(ø!’¤HPø‘*¹…ÿS*ø!†“Œø!ƒVÂÂV—‡�.ºñCznöO–Î=º'mУØñ"ˆ¯!2r5¾‚ÿÏ?R¬ö«¤S�7»Å¬1{¤�O§Ö¥îbUÜË÷ûé‹~¡s¯~ÏÔù'þ‰Ž>p1“Ha½É¬7¥6+ä j´ƒÿPÃ ë±æœSÇ›à2i½iÂñ‹è‡_êLƳå¦Ýèå»G§4(ÄWb|ËåøÊ!.6Ê$~ˆiÙ*~ˆ!~˜q?Ä솥ÜìWÌ~m�uÅ2ËÅÎ9~;:î -Åá ‰ø*·ã+UCÊ%ÿÑÚ–Omj»¡XOV5!´ËrP°šå ÆôĘ¿äwš|º¹`Uö4«âpØUQ!ïuuµTYY%>pɵk«õž¬‰P8v5¦ÄÆœ´56F¨¢¢R¹Oîƒ AeŠU½\O¶X!3¾®}pW[»ŽªzôtUô* rss³QÌë¦À6Ùµøé)Y~ì|ðª©m2uÙoëîôÔÍ»‰NÉVü°‡üHmVAãG×шßà?ı•?D‘2˱-v�¯Î¾jÍ|e…¥Ã·žÙ›º—…R^ñ•˜r=¾‚ÿË?P°*ƧD)äÓÉ1³»ßË#ÜÙ÷{1ôrý~Ï…:\°Óõãö”äÓȧÅh–B¾ ‚Zì!+¬ÇÊcÇë#X��ᦲ› ùÂ~'¿J_ÿ°Î4•M7*¥Ù÷�IjPˆ¯Ä¸–ëñU6ðCLÓÖõ+ìç9#~˜1Â~…³ÍÄ%ÜîWÜýÄ×tãÔ/,¼åßChì.½Ä’BñU'8¹_©R®ÅWXOV±´ÉuP°šë€ùw 0÷�ßèÏg¼eB„1x1ÃéS_WGá’÷Ūµë¨²ª‡ÓåRþôÍI '~¡�Ôâ£ßÅxü4\q±óIhvÊä±Fi]m õ豞'¤v‹+ü�›Ýd†©Ê»ÅÅ�7(¡yS÷Pæøaø‘Ú¤ø¾4~$ŽØ¸¯ÂÝà?„`’?¤àêN¶ù|ê%ïÒ¢·~µtúÉŒ‰”ê€xÄWÎz@|eÅþ#¹Ý`�Ñ™S]%�OÛc¦»Ø÷{gÛÄý¾£�šM5uÍ&ж۪œž½Uí”häÓȧ�ho Ÿ–GþC3n�õØNÜT×c³a½éϧ¿FŸ}Sc2¢^ë‡iÁCcm ñ•3ß_!ŸvsÈÖc�9&+�õXYÄbòÙ_]xÃôüœŸ- L»k4mµY75°Z!¾B|¥bD¹_a=YÅRÐ&×@Áj®[æß�ÀìÅ¿ÑÁ7¬Î}pÚdÃ’¤(ñë¾êë먤¤Ôu±êºšµF±*¿â^õÃOõ„ µòÜ#ãTL>uSLJ_À󬨬Rî““[žc(”ú”±øxyüÇ ®2sw‹Ûºu5T*ôµX5�©Ø&ÃÇ-?Ž¿à-Zòþ¦îC¡<úpÚ>2*é�?¬°�ΦT~ÄGÎIü‡³�)ø1 $¤À °ÚE�â„cÏ“Þþ`•©ã¢Â|zÿ¥ I/†øÊYˆ¯¬Á¤¶›hS+ Úo¦!ÔÖÚHyù�¢áNöØ!Ÿ6ãât¿w¾sY%p¿wF ÷{3FÇ�ÿ½ù�9§æå�^Ú‡8·–ù ŸF>-c/qYä ò¨ÁÈcfÄk.×±á?²+_8ì¯Ó‡_T›&Õ£¢ˆ?±—e¢ˆ¯œ9~d?œ5Þ)~8£~€AØï>êœ%´ì“Õe|<}"¹(9@|•€¨ÛýîxWX�u¾¯Æ%2q?/q=¹ëL±ž,®{Hæ(XÍ-}c¶)°Û`[ððXêµ^8i+]Ǿë(6âä‘&ÑBN'cpóÄ”]ß<¶ššµÔ½{¹rñ¨ì“˜~ãñ¼Ù&JJ�OåµÃ¨¶v54Ôzä“Uué2•®YÏm­­Æ Áº?nùqÁµïÓ‹ó—[†ÅOÃóSñ2ðÊøálAAæ�^Wr ~€Îl°J€*¨9ŸøsÀ©¯Ñ—ß™O‚Y¿G1½òèž¶D|å¬ÄWVŒà?œí†%¶Ÿ0Ý(V¥¼ÊËë|Xnè•´à!µÓ Å®œ™RȧÍzC>­fÇȧ;qs›OsO×Üó)=ðÜwej9ÉdüÀz²Ž�Œ Va@ �é‹VÒág¿cƒO³âS­º~ø•V|ú¥›bHÞ×V¯1ŠUÝœ¤™ ›\,P\v5OCåÓ?øã¦8ñzü4i¿7/ŇçXRRªdØÔ¬[k\ƒ‹U9ðõú‰DŒb<ÕÛTãÓÅ�gg~M—Ýñ­åRž²¹ßB�V˜ÀgÓÉ~À8ëQEüpF üpÆÈNB¤x©¥¥�úï;ÃÒ|̰ é¶K­ Œˆ¯Rëñ•äâüÅ£8VqIäÓ1$Dî÷²èâ~�û½¬ÍÄï÷E%´Ë!ó¨­ÍÜÃàí«è‘ëF8v‹|ù´£‘Ø _PA þÃ5¬ÇÊÙ’®õØlXo:ùßïЫïüf°  �>zyŸŽï_!¾’cXìMWÙÀ‘yƒà‡ˆ�$Ê€²ˆ‰Ë;íWÌxe�sÕ2K‡gÝ—N>|kË÷ˆ¯Ä±gIÄWrxåºÿÀz²œ½@0(X…�v¦-\IGžc.X]üø^Ô£²È„Qss³Q”è¶Xµºz5UVöpUœèÅæAQQ‘cq¦ŒÑðB5ŽúQ„ÉãbLø�›"àÄù9雃{ÀøôX›àcí«×®ñ½Xµ¥¥™ÊʺɨRHÖ /‘N8¹e~¬X¢ÃÎzÓÒäðI›Ó”Sû9v~X!?͆øž• ü€ÿpÖ¥¬øáŒøáŒ‘�/‰ÄW?¯¬§qµ>È„Íè’3û›ºF|•Zˆ¯¬øÄã+ø1c�Q §D)äÓ±b#‘û½ º¸ßã~/c/,Ûõ~ð™‹é“¯Öšºá¢�·žÞ›JK’¿éù4òiYÛcyä *¨Áء派ˆõX3jNx‰Xf6å güg)Íc¥eڟΜh|‡ø ñ•'e²‰Ns?À'éú;ø!‹˜¸¼È~Å5÷~FþT‚VtÀ9ÔÍø9ü�¤á?R#”iþ#Sù±ìÓ5tÔÙoX”qúQ}éÔ#;Ÿˆçû â«ä6‹øÊŠ ò'/`ý½¹¹�L²žxÌ’CûUÒ‚©£ä;Íòȧ�‡4ݬ Ÿ–# î÷b÷ûëîûŒî{ƺ�yÇ¥;ÑèaÈ�®(�|ù´¢ét4C>-‡ ò…ÔxÁˆù9«óFZÕœ}Õ2šùÊ Ë Þ{qåçµ ŸN¡.ð#ûù‘Š­ðð²ws¬7É"&./º_qÌyoÒ;®²tüö³{S·ÒPÇ÷ØÏÇž%‘Èã…ý "¬'ËÙ ¤�#€‚UØhGà…y+èèóÌ«KžGÝb¯gל¬Y³ŠÊË+){^ˆàâ�›küòîWuqI Ö~ê*V¹vMÍZãdU•k2&l ~«®^õ•”–zr²ªWüØãèù´ò÷ˆIô Ó¢GÆŠ¨H‹ ø¡#øÑ‰›WüPÓŒÞVà‡žàøag9³^ý…þyå{–Ÿ.;s4aSã{ÄW©9‡øÊŠû äò÷êT Œ;õ«¤ù(Xµ€Š|ù´,Óù½öîoô·)æ· ñ•�9 �÷·íeÕ&-�|A2£øá?Ô´£¯ø¡†%ø~8YÎù×¼O/-Xn[òÔžTRœ‡ýŠ$"ŸF>�ý¼äwðü*?v<`&56¶š´éF¥4ûþ1NîÒô;â+ÄWR“ ŒýŠN0°ž¬jEh—Ë `5—µ�¹›xnÎ/tìKMß½õÌÞÔ½,DÑhÔ(JtSÐÙ±Yܽ‚Â%%�AŸGù$�§ŸòIlüô«ê~�œp¬þøy¢ÚÚµÕFá§J±*�— øi#>Yµ¸¸Øs{X³z•””zb{^òã„ÿ{›Þxïw >ï>7>åë u ~¨! ~tâæ%?Ô´£¯ø¡†%ø~$³œ‡žÿŽ®ºûSËÏñÐ_¥æâ«›È?¤oØX`”†Œ�O'µº,š¸ßã~/k3©Ö›£­4ôÀYÔÒÒfê¶oŸrzávoO‹F¾ «É˜<òä j–CÆ,Öc“£‡|!wò…)7~HÏÎþÉ2á…�¦ ×ë†ý š€¹Ã»»$üòÙØûݲˆ‰ËËìw÷S-M<éKçFoD×�?Xø¢È?�KAø3 XOVµ$´ËeP°šËÚÇÜM<3{9÷ËLß½óÜx*+)0 ù$LÕO¦'^¶®'/|d,mØÓû·Þ!¾r¾“eC|å�Oëá òéä8"Ÿ¶b#ºÞtÓÔ/è®'¾¶tð'ï@Gí¿…ãMè%“î÷É&�xÈÙ,9cd'~¨á†|ù´Œå\u×§ôÐ ßYšÌy` õîåía"ðΚ‚ÿpÆþC #»Vððn¬)èùù¹W¿GÓY×’Ÿ¸aW°­ó�?àø‘Íüp37n«Â�øzr[[ µ5¯£üÂNb=Ù­FÐ>[@Áj¶jó’FàÉ?Ó‰SÞ3µ{ïÅ T\”/ÝW¼oTW¯¦ŠŠ*_Odp°ŽB*»kp!%Ÿ´éæ´M§±'bË'õøuÒ_‹Ÿ¤ ‡K”NEå"ÕÚÚu�6Ÿ´.)�ªINæi%¯"O6H}‹ðcÉûÐñ¼eÆI‡þ‰þqì6J:5?œ²þ~˜1ñ‹òšrßü�Çü?D­æØóߤ·?Xe/(È£^�ø* ˆˆ¯¬ÀˆÄW¢6©S.Óü Våµ�|Z³®-�O'Ç÷{w÷ûeŸ®¡£Î~ÃÒÉNzÒÔ«wvo¼ =dÚýÞnòìK±Þ”Ú,tä¼é^oÒjø‚��‚@%ˆ!ŸF>-o5D×Ýÿ9Ý÷ô7–¦ÓïÙ�úô.SéR¨ ü‡3LðÎÙIÀÈãÿÿ!o5æ™�Ÿ�åôÁð#ø¡:G7üàõä~§µ4Ÿ°Š‚UU- ].™o…] IDAT!€‚Õ\Ò6æš�ǧÿLû·¹`õÃiûP(”§„/P¬­^C•UÚO1UP{#™‚G7×ñ²­ß‹?<~’&\V*4å͵úú:ã$Òü¼|*)U{’›&DOvõ2™büùôQ·'«ŠðcåïÚãèùsÚk×�見k73ðC Rð£7?ù¡¦-õVà‡vàø!j9ûœ°ˆ¾_^gïµ~˜<4V´ Wrˆ¯œáË–øÊy¦z%2Ñ `UÞ�OËc–®¸ß;#Ÿ�÷ûÑGΣßW7š&ŸŸO´øñqTY^è Š€D&Þï»N üpVt6òÃyÖî%À5 ‘O#ŸV±œ›ú’î|ü+KÓnß�úöé®Ò¥cøGˆþÃ#; ø5Üà?à?Ô,ÇÿVªþã«ï×Ñþ§¼jðؽè–)CRNü?ü·tµ+ªòCíj±Vnø�6ÓÀ}Ÿ'¢<¢¼|ÊË/î NXu£´ÍfP°šÍÚÅܤxtÚOtÊ%ï›Ú|<}"ñ¾ì‡hÍÚjª¬êaöáÃO„ð¸ü:‘Ô«9ûœOÒT¯¡ââ°R¡)/ÄÔÕÕRii5E£J¯<†x±ª§×¦Ò¿Ã(¼U!F{Dzü´ßLŠ6µš†õ§Í»ÓKwî¦ÍÌÀ5(Á3néà‡šæäZ�rxÅ¥ÁðCÖrOžE‘H‹©Yÿm*éÉw•íJZñ•ÚjÒ@'iÿ¡ I}ý´¶õ›8Ýè�ŸˆÏË ut¾SÿJšÿà(}Ë’ž�Og†"q¿ÏÝûýe·}LO¼üƒÅPÿû�tàÞ›º2`ä jð!_@¾ f9éiÿ‘»þÃK‹óÊÜñØWtËÃ_Z†þôÍ#i‡­+´O ü?´•‘‡b?OWÄWˆ¯Tì&]mÜø�‡_øž®¼ëËЧœÚ�Ÿ´¹í”Àð#]¶®r]7üP¹ž~¬[WK;ºˆˆ×’ŠUyé §hÀN–Où …:7ZuöïW_Œ-€Šž2ªc\ÕkVSaQ••u“îŽÇÊ'«vëÖÝ·ª=D" ‡ÃÒ××Ý€mˆ fUçÁãQáÇAg,¦O¿^kš×Ë~8M­ ¼+.à‡º¥€�Ø¥‹êÚk ~ˆád'~€2ÖS[ßLÃþ<ÛÒd�]zÑ­ÿNýT¼Ìuìd_¹EÐ]{øwøyÕ:^°ÊŪÔÖFyù�§b�ÑuäÓ^Y£¾~q¿×‡¥JOé¾ß/yÿ:þ‚·,Cß}ø†tû%CU¦d´A¾  !_@¾ n=þ¶„ÿðï®WK·ÿðjö^ú�{Ÿú†®àsËлa Ú¶Jë”À­pJw~HCækðÃW¸-?Ò‹¿ÓÕÝòãôKÞ¥oýj¹Ìô{v§>½Ël/�üù‡“]åw·üP™‡~”–v§ö™FyyÖÓ𰞬¢´ÉP°š ZÆ…xøÅé´Ë>è�ÍË#úd†\Á*;кÚuT^Q骨OhÀ‚B\(ÉP¬*X‚'¡uï^.ߘÈ8YU¥Ð5ñbñ“U• ±‘ŽWö¨òãܫߣé‹~±Ìfæ}»ÓæÛ'^¢S?D‘²Ê��˜¤“êtn ~8c”Lü?d­çÛŸjiß“^±4;lßÍéß§õ“íNX>]‹?ˆ¯b*‚ÿ6Uß¹`u‡}^´«ò@vê_Eóéû˜‚~AäÓÁÖî÷éÕOî÷|_ÛùàÙÄÉ$~ CyôÖ3ã)\,ÿz!ä êv…|ù‚ºõøÛþÃ_¼»^-þà ¼ö<÷-]sÏg–¡O½zgÚi@OmS?´A©Ôø¡›o�Àß ¶½ø‘^ü�®®ƒC˜E �æ7uõ¨(¢ÅOìe{yäÈ?œì2(¿ëà‡ì\tñ#ñ�]]Ç€õdY­@>W@Áj®hótD`êó?Òÿí,X …òèÃiû8¶‹ °åÓ4+**…Ûø!ÈOÑxz)7§‡Š Œ_“Ê×(**×"ÃÁI^~¾²>ëëꨴÌ]1ePŠUuê†É^ãtÛ%CiÌð ] üPƒüPÃ-Y+7üÐ;soà‡ºà‡n¹Î�7ßÿƒŽ³9õìÌc¶¡“û“^PÛ{C|å ¬¾v ÿ!_\%ª h´™NzÙt²j¼-íQD>-j]V9äÓVL�O›1Ñu¿¿ðúèù¹?[¿öüÁ´Ïè�¤�ù‚4dFä j¸åz¾`7øø'6éòNבýÝkÿñèKßÓåwX_“|ÏåÃh×ÁëË×Vù´ÓÚI®òƒA‡ÿ€ÿp"øáÝz“ÿñÁgkèð¾aQãäq½éò³Z¾Gþádñr¿ƒÁ懜6õæç(X•Eò@€«° ÐŽÀÏý@¿üÃ<Š óéý—&áÃÁIccÄxõ{�>üj~…»—¯˜8xçk{9 Sß¼S^UVª½"¨¡¾žJJK]�7ÛŠUÝðcæ++èì«–Yð<ã/}é”#¶VÆüPƒüPÃ-Y+øï¨€ÿÐk«éè-—øñôÌéâ›?²À|Íy;ÒÄÝ7Ö?ø¡Rß;Ì%~t×�ü£¹¹…Ožg«×aý«hNXµ`ƒ|Zí6à‡=#ŸVÓMPZé¼ß/xóW:ýÒw-S3lCºíÒ¡RSF>-W‡0òi5Ü�O[€ÿ°b‚õX3&:ý‡Næúá?ž˜þ=]v«µ`õöK†Òî.?`,�Oë´ˆôô•Ëü€ÿ€ÿpbøüýŠü‚î~òk‹*¯>wMÚcÓ÷È?œ,^îwð#øü�Ѩn~´µñ»¦c=YF �ÍyP°šó&âÜ÷ÌtÖ•�«ÅÅùôÞ Î«œ4E£®OÓÔ­ ?xq& ézGœ<3¶á’ϮѵcN»ªj¯Š44¸o¶«ºåÇw?×ÑÄYl`·�6 ;/ÛIÉ6À%ØŒ“`À5ììZÁÀ$Úü‡usÍ­ÿÐÇÖΞ¼òWÜù =òâ÷–!¿pû(êÛ§\ëT_i…3-�Áøã?¶Ÿ€FG>-ƒVLù´3ÄCÞÆCÍÍm4ò°9TS×lº?ç¼è‘=iýb {% ü?œîªˆ‡ü‰‡œô ëw¬7éB2ÖO®óãÅ+iÊ �oÒ‹£{ó”!´çˆ^®ÀF>í ¾@4Îu~`?Ïl†È?¼Í?t‘ù‡ÉñÇ-¤WÔ›¾ÌÏ'zýÉqTÑ­°ã{ÄWº,ñòsñüëÉzy‡Þ²¬f¿Ž1CAîyê{:ûêΓ­JÃôîóãS¶æä–)Âá°àU¼ãÀ�ÿästêчûçy{�ÜF]ŸT* Ïimõc^=z®§t2m$1N‚usª-÷${ÅÏNN'?†4›ÖuÙTëV¢·ŸÝ[jˆà‡\Âà‡n©Zé䇮Ñ�jH‚j¸�fþzþ[ôÖ˜¾äâ‘�§OäCßµ}8ÎA|¥ δtÿámqF"?°À(gâȧÅñB>m�òi3.^ÝïùÉüªä®Ÿ3�îK'žú &ÈÄyž(‰|A 7ä Và?à?DØä•ÿ¹v2¿ýÇ´Ëé¼kÞ· çÚóÓ>£7Rž òieèÓüð/ŸöZ鈯ô# ~d?>û¦†þ|úk9d}ºû¿ÃŒïÁðCÈ?äó¬'ë²>ô“+ `5W4�y:"p÷SßÓ9 «NÅpü4Ikk+9öí—€_‹?<÷ÂÂΧ´tÏ�qmh¨§²²nº»¶í/¼ó¼¸XU¥Ø7�˜¸)Vͦ“Uuó㤋ަÅK·èoú=»SŸÞeBv~Ád?ÔpKÕJ7?tŒüPCüPà ü°"0êðy´ªºÑôÖ›v£—ï­ dÄWÚ L[GðþæX`”3uäÓbxqì€|ÚŠòi3&^Þï?ýz-tÆb‹6Þ „æMÝ#©!#_ãxW)ä j¸!_°"ÿaoðþùU6§ÃÌ|e�}Õ2Ë�¯î¡§Ü@«¹¡gÌR�;ŸøŽþuÍÇ’åÝ éͧÇÙ¶ä@�µ—E›C6‰ø‘ÜrâÉOÙñ)¢^}øõõuÔ­[w¯.aÁ�OVmjn¢ž=×W*Vå§«¹ÈÕM±j6�¬ê?n{ô+ºí‘/-6qù?Òä½z;Ú øá‘­@|s üPÃÏ®•üp;:ðC AðC ·T­r•kÖ6Ò®‡Í³@3näFtã…ƒµ�øJ Œií$Wù‘Îü Œr&�|Ú¯tÚ³óèÔ$©á–îxhò©¯ÑßÕX†qÏåÃh×Áë[¾G¾ ¦gðC ·tóCvÔà‡,b1yðC 7ðÊ€]|5ÿ�•tÆ–Z„ÿó÷ôçñ›Jƒ�|Z²À5@>�ý¼D£Ä~ž™¢àGfñc�£çÓÊß#&%†By´ä©½©4œo¼IûyúÜø‘YüH¥y¿ò¬'ëãzÊ P°šzÆ,¸ý±oéüë>é�¬,/¤7ž´¬r2ß‚‚�^³G$7×X;ÕkVÁ{�ë)é”íÁ­-p±*ŸÔ«r²kÐ,Ì+~¼öîoô·)ïX¦{È„Íè’3û§ðÃ^à‡¯ø‘v8 ü?Dl4—ù±dÙotâëfÚ©GnM§ÕW¾”2~o®!¾r­2K¹Ì�t>,·Ã>Ó©­ÍªÏaý«hÞƒ#õ+:Ã{D>�Z�ˆ‡‰PܯûýÃ/|OWÞÕ¹þÛÞ£zÑ ÿ7Dd¨ZeÀðCÄ üâ‡ÈXü”?À{?Ìů¼ý�r±uyÊ©ýèðI›‹@Ú!ƒ|:_ ¯ ƒÙSl„õ&ý ?2‹µ–9Óú¶ŒÝ‡oH·_2ûÝš)~d?œÔïW=Ö“�4�ß�€¬Â"€@;·=ö-]�P°Ú£¢ˆ?±— ?žš¢B8(ãÍâp8ìéðêêj©´´ÌÕI¥2äà„çVYÕC©è”íÁÍ©ªú-ýßõ�ÅëUÓ«�í)Ò4«eø¸{þc·YÌE¬\l©ãS_WG¥ee:ºꃃ~Bš‹UÓu²icc#…B¡Œ-VÕQ�(¤¬v¡}NXDß/¯35ÉË#Zúü §çioðCFƒr²à‡^A”?¼Ó øá¶~õœÈ�Koùˆžœñ£åÒÓîM[mÖÍÕ�_¹‚/-�ýޝÒ2I‡‹Åôßwµ´X�X6 Šæ=€V»ªù´½aÅžusù´{DÓ}¿ÿÇåËhÎâ–‰3¹�wÒöî'(Ðø!’¢òEàÔ üðNà‡wØúÕ³?Þÿ¬†Ž9ïMËpÎ9~;:î -…‡‰|ZªÀ¦;¾ NüÀ~žº–à?Ô± JËLæ¿h·#æÑªêFœ¡Pͺk' ça¿Û…¡Á�Q ‚zFÔÞëÉî1D¹… VsKߘm nyäºð†O;$6è¦E�ŒÍi̸ µ…‹UKJ,8D£Qã5ö:>‘†ÛkèèÛ®Þ\㫦ëÃøñ©ª™z²*ûòÇÏbß ®}Ÿ^œ¿Ü¢²®Níç»*Áï ?¼ÃÖ¯žÁï�?¼ÃÖ¯ž»òã¨s–вOb±IüÃd|<}"ñߪÄWªÈ¥¯]:â«ôÍÖþÊAò&Ͱœ>È£FÁª½î�O[q ’=ëä:òi÷há~ÿæûÐq¼e™Lqq>-~|••¸ŸhŠÀïàE¾à¶~õ ~x‡4øá¶~õ,Â�÷>[CGþó Ë�Î:v[:ñЭ„†Š|Z¦@ !¾J7 "üÐ1FðCŠþö~�ñÑLÞïž÷ÆJ:ó?K-†3nÄztÉé[c¿Û¥À�ÌçG2õ§cý ëÉ.Ȉ¦9‰ VsR혴7?ü ]tcgÁj¯õôà!ï VƒqðÞÜÔD%¥¥žL$±=½Õ«‹rp’—ŸO•^]±_Æ– =3µX•_¹Ä?ÆŸÈ�ǧý@ÿ¹ýc ¾?fúÛarÄ]§ø¡Ms_à‡8¶ððâÖ Étù�`Ì>6 ;ÿ1ä€YÔÐó­ñÏÖ[t§ïØMy舯”¡K[CðÞ^(D”ɇ¨¢¹8aÕ¢äÓÖ˜ù´ ŽÝ+�O‹aë”/xÚkôù·5–ÎþqÌ6t’‡96òi1ý©H�â¨9ñC¼'½’à‡^<{?ıÍt~|ôe5ú÷×->ã/}é”#¶vB4_pìHPû‚@¥C>¼|Ú½Vc=€î‘?²ƒ'\ø6½±ìw‹AÜuI5|3÷†¢Øâ+qà2=¾Ÿ©½d®ÄWXOvk)hŸk `5×4Žù&E ëÛÆ”м©{ä$bü´9?i–�Ū¡uï^ž6½fzðίàO(òÃO¾ZKŸ¹ØrÝ1Ã6¤Û.êÛxÀï ?¼ÃÖ¯žÁï�?¼ÃÖ¯žíøñëª�9j¾eFoD×�?XihéXüA|¥¤ªŽF錯Ü�\_ë ú��“fPSs›e’(Xµ×;òéN\‚hÏ:ØÊ›Å¸ß»C2h÷ûççþL^ÿ�eR=*Šhá#{RaÈÅQïI ?ÜÙPªÖȼÃÖ¯žÁï�?¼ÃÖ¯žeøñÅw54ùÔ×,C;ùð­éÌ£û¦2òi¿4ªï:A‹¯ôÍL¼'~ˆ÷j•?Ü —ž¶àQ6ðcåïÚãhëúñ›”ÒŒ{ǤǸÚfÈä‡IÁ�ìà‡Ò¹~_Onkk¦¼¼ÎZ ¬'§íV… ¬\AžÜôÐ74å¦ÎV7íUJ³H_ '3s~*G׫Ù©µ¥ÅûbÕ† —”ÈLSY¶­­�ÖV¯¡¢¢b*-+SîÇmC^åSIuéÊíxdÛsðζVTT$ÛT‹|[ÑàÉ3©±±ÕÔ_eE½ñÄ^I¯~¤†üÐbž”n~¨Îü?TmG¦øA”,¾Z¼ôw:颷-pò&o¦É~ü|-ü‡¬vìåÁ�äüЃpg/²ü´ßLŠ6™ãNî ŒöšA>Ãù´nævö‡|Z?¶--m´ûQóiUu£¥óËÎ@MØÔXе†~è×a¼GðÃ;lSõ ~ ŸöÃò�/ÈÇWßüXK“þöŠE='º�uì¶IÕ&›/¸Ñ?òi7èu¶?äù¡Š<ø¡Š\úÚ�ÙÃ�kîýŒxö[‹1]|F:tŸôœ®Šü#=ÜFþüüƒ×“£Q"ʧ¼¼üŽc=9=œÁUƒ� Vƒ¯#ŒÐ'n|èúwBÁêf•Ò¬ûƒ_°ÊI‡®Ó.ù ɶÖVï‹U#>¿Æ¹z {>¯T¦š Oò³­…ÃaŸi™£ÎYBË>Ymùqæ}»Óæ[‹‘ÁguUƒÎ 9H°��²?œ?œ1r’?ˆRÅW<÷-]sÏgož2„öÑË ^Ó゚tÿ!¥;að#5?\œÐ� ?í?“¢Q¬Šêùt°íYT�vrˆ‡Ü käûý�O|M7OýÂ2É>½ËèÅ;Fb½ÉAýàGvó#Õì�O;ëüpÆÈI"Èþ#Èüøá—:špü"Ëÿúç-éܶ³ºJ¾à¤¿T¿ƒnÐ ~|d~¨ ~¨ –Þ6ðÙ“ŸóƒÔ£�œGk×5™Œª[iˆ^}tO ‡ |76ìwûyǺêARc„øjà¤imj£¼<37Q°šÞàªÁG«Á×Fè7Nýšþ}sgÁ/ÎO¿g÷¤Wç§`ùI>13]>�‚O»ÌËsÿš6~B’çTRZêÙt¸ÿÆH„ŠÃa-cv¨ñ¤òÚj ‡KÒZh™ Oš5E£R¶á?®½ï3ºÿë“„—ÿs MÞ«·É$À�Ô ?œî b¿óâOPø!6â˜ø~ÈØ‹ª,øAä_]tÃôÜœŸ-ϸwwÚb±Sá_u>©¬j«éh~8óC‡^ÜðcǬ'ûó˜°Àh¯äÓȧupÖ®äÓ^!ë·zm”F6×ö"Wž3�ökγUFã©ôÙµ�›û½Êõ‘O« fmƒx(øñ�ЦÁÔÀ;ÔTýÇò_h¯cXºüËþ[Ð'ï`úþù´ÆŠõ‚õX¬ÇŠYŠ;)ÄWÙ_½´`9�Íû£8r¿-èÂSÌ>Í�刵F~.†“n)ø�Ìñ;4‡ŒV»|°ž¬›è/[@Áj¶hóp�@× ¶-7íF/ß=:i¿»¾®j¼`£«ð³¾®ÎFi™Xa„›1‡KJT›K·ãbÕ’’Ò´½Âž�F�¢æt6K—Ѐ“ÛÆÆ••u“êÆ+~ÌY¼‚þqù2ËXÆï¶]ÁàŽïÁgu�Î9I�Nã�ÿ~8#~8cä$~‰ÄWûŸò*}õý:œ%Å´ô…ñN›|â+a¸!~ˆñC‡²Ü¼¶«r@>�|ZÎbĤ‘O‹áäVê’›?¢§fþhéfÃõÂ4÷�=(RHZ$r;~nïæ~¯r}ä *¨™Û ÊŒxHEÓà‡ jàGWÔÜø�_WEhÌQó-Š8|Òæ4åÔ~¦ïá?ÜÛ«ß=ÀÀxisÈ?¼D7yߨ¯HŽÍ~'¿J_ÿ`^;féiw�¦­6“Û·u«]ðÃ-‚jíÁgÜ‚” ýójlÄ»œµ C«° ÐŽÀ ~MßÒyÂêŸ6ïN/ݹ›-> õõR§M꙯ÏŪùù­««¥ü¼|OçÃO*s@ååé­]1®©Yk«ê†_¸¿lÞê©{÷rá9³ —üXW×LÚm÷¼óÜxbJ€Îê?œ1r’àÅÑ ñÃiÌq~¤F ü±¤Ô2à‘H|US×L;Ûø´;®O÷^1ÌQˆ¯Ò÷–Gå¤?Äøácn«ƒƒ'Ï¢H¤Å2<o¯äÓÞ¾©ù´Û»‚ÿí3é~ÿÊzšpÜB[�Î?i{:zr%Eâ!¥Žé¸ßËŽù‚,bVùLâGâè±Þä¬{ðÃ#' ðÃ}¾°º:J#·ž~ð„ÍèÒ3û*€ÿ@>íÄE�¿Ã8£ ÿ጑“ü‡{ÿᄱßþ#Ù>{ ß�n½d¨ÈpµÉ`¿[”RÁ8Ã4ÿ�õdg�A$"€‚UØhGàú¾¦Kní,XíÛ§œ^¸}” ŸÖÖVã•ö~^vU'EÅÅZN쬭]GùžÎ‡1ãÍ5¯OoMÄiݺ£X5 ¥Í¾ù„Q¾¾Èɪ---Br2“áE·¼<õSP8¹­¯¯£òò áËúÅ�£ÎYBË>Ym×ýW§�}KÁ��±EélåG*õÃ8ßÎÀðCÄo;Y’h|5ëÕ_èŸW¾géîÇlC'ö§”—A|å¼¹†øÊÉRÅÏUÿ1ä€YÔЈ‚UQKA>-Š”œî÷¸ßËYŒºôÅ7DOÛœ²Zѽ�<4–JÂκH¼ºh<¤>b"ðÃY'ˆ‡ÜX˜¹m®ÆC2"ŸF>íg>�Ê6«×5шCæXD&�ëM—Ÿ5þ£þCæÞæVþÃAøø� ø'kõ;ÿ˜ô·Wè›k-ÃzöÖQ´ÝVr 9Í-ÕïØïvƒžz[øgì‚è?°žì¬7H�DP° {í\wÿWtémŸwà±í–åôÜm�«¼ÈË|²§Mê˜_…Ã'ãéÞù‰“ÂPaÖ«ò¦«êÀHUw2Á;†òI¹:NË��—“&þ¨öÉcb++«„!ð“w?ñ5Ý8õ ËØŽ˜Ø›.8¥Ÿ݃ª—?¤!ÓÒþÃFø�ئ6û�dV�.~\zËGôä ëëw»a Ú6¹ö{q”q?À±u¦ÅWC'Ï¢zœ°êì@‘O c$+ˆû½s1òiY«J.ÿÓò54éÔ7)µ¾ºî¤CÿDÿ8vá‹eÚý^tbˆ‡åb<~ˆ"~‰u -´Ó�³,ÊÛo�M芳ø~¸üø$~¤º«!ÿ@þ!îõÜK¦k=Vuä~ócÁ›+éôK—Z†;jèt×vR�†t;ìçIC¦¥øá cPã+¬';ë@ ¬Â’ë^ IDAT€@;×Þÿ]–P°ÊO'ñSJüáÓøødÕpIIÚðâW©…Ã%®‹ñx.¼yP\Tìé|8xç×e—––¹:ÉPpžs±ªj¡¦èµRÉE"*,,ÒSSS“!§s¼:Š�ÖÕ¬¥ŠÊ*áqùÍ�/¾«¡É§¾fQæ•ÒìûǸR#øá >ÇÆà‡#DžÀ¤†þ#†O.ø;KH'?&ž¸ˆ¾û¹Î4¬’âZúÂø¤F‹øÊyóñ•>W’N~¨ÌB7?x“›7»»~vÔƒæÜ·«Ê³º òi½êÕmÏN£C<„xˆ×›n|ðKºï™o-æRT”Oó܃zV§4%äÓNLs÷;òiwø©¶ÎõxÈ 7øø� îW4F[iÇýgZÌwÂnÑegöÅ~E b#Ÿvºë‰ÿÿ�õXkÁz¬ó:_*³9ÿ8ð´Wé‹ïÒ{º*òë—�ÿÈlÿ�õdýœ@�Ù� V³[¿˜�]7Øvغ‚ž¾y¤Ñƒ¯Ð’qpR\ÖòŠûêê5F±jIi©Ì¤d/.VíÖ­»T;7‘†O pEÆ&¼G£Q£XUÇÓµñ±1îüQí“O§©Y[m«Êô‘~ŒùË|úõ�ˆE-ÓïÙ�úô.Q—­ ø¡ �cCðÃ"Oà?œa…ÿˆÅ9¹â?-"�üX]¥‘‡Ïµèn;m@w^fÿ”<â+çElÄWÎ÷µÓ͇Ÿ4«^³Ú8�ÔË“býNn�Ó=©¸¸Ø—“\“逃÷¢¢"¡SI¹˜‚OUÕ±`ãÎX¨öÉŪk«×PeU©bU76é¦íÅ7DOÏ´¾FùÜ·£¿¸¥t×à‡4dR À)¸´ ä†þ#†O®ù�¸U¤›//ü…þõ¿÷,FzÎñÛÑqYýâ«|Ç{#â+Gˆ„ÒÍá�¶ zÅ�áͶ-ÚBÁª½†�OËZ®½¼Wöœltˆ‡u]oºë‰¯é¦©_XL&?Ÿè¹[w£¾}¬&#ŸÖì7y‹£l�O‹Ø òéàîWl?Á¦`uç^tÛÅCDTëJñâ+ìç%§ø~€Îü8èÌ·èÛŸ¬§«>~ý¸]•+%Òûy"(é—Aþ‘ùÖ“õs=f7(XÍnýbvüïÞ/é¿wt.Ê÷ë[IOÝ”ÞW=fZpÂE�MѨ§§·&ª”“[¾¦Ûb^ 3±å‚Y¡:}X–åtŽ™GùÕ!ª}ÆOV-¯¨T.xuš·îßç/YIg\¶ÔÒíð�ëÑWÉ=)ï׿ø~èæAªþà?œ“[ø�X±j®ù¶Œ ðcÊ�Ò³³²êS7�¤~[W˜¾‡ÿ€ÿ€ÿHŽ€—üØù ÙTcsÊ Víõ�|Ú=S½´g»Ñ!ŸîÜ,F<Ôi!ü彎]@¬i´˜�݃ÝȧÝs?UXoòßd½!_�™9üò{q+›)ü´ßLŠ6µš¦›ê�&nq‰·G|…ø*“Šñà?à?tÝûDúÉÿŸKºø1mÁJºèƵì}Šè¥« òÔÜ·?²g?/¾žÜÖÚDyù�wa=Ù=OÐCv"€‚ÕìÔ+f¥€ÀÕ÷|I—ßÙY°:`›JzâÆô¬rpRTTlœÚéæÃ/kV¯¢²²nžž¬ÊÁ{sS“§×èŠC:^Eßu 2¯žå§ÒòòòŒÓ`u}Æ^µOn[»®†º—WdÄɪqÜ~_UM{þu 5uYxäšáwžO%aç׸p_à‡.K´ïüðßd½Ã8ãÿ+VÍEÿ~ì}ÜBúiE½ÉXKŠ hé ãMß!¾rö爯œïy¢Aá‡èx½æÇÎÏ¡šÚ&Ëp°Àh¯!äÓ¢–k/çµ=Û]ñâ¡dëMÏÍù™.ºÁú J¶£‹NíGGLÚÜ0)äÓîxïÔù´BÞüŽxÈWøø�Lد:yÕGZL=bÇõéÞ+¼}•2ø~d?˜È?°ÞäìñõI ¾rÆ’ýGSÑØcКµQKƒçnEÛnYîÜ‘ ä.ÀsÑüp/“â+^O^[SGDy(XuV-$€¡`FÚ¸êî/銻: Vn[E�ß0Âw|ššš¨¾¾ŽÂáå"Äø ýÚ<ˆÒM‡}Ç+�ä9ói©bÉ-�U'FnqçE‰ººZêÞ½\ètØtb¿v"?N»ôzã½ß-úþ‚iün;üp„È•øá >¥ÆðJ°¥¥øá?ìAâÇêê(�<|®„1]^OèÖÏû�²ž+‚zp”é%Hü·üØå�9´v�µ`u—{Ðì{Ó÷`£(F~Ë!ŸVGÜ{V�w-q¿÷Ûd=ËÜï�:û ZöéKWe%4ó¾1Ô£¢Ð—‡£Á¬7ùÅ~8� ëMN¹ûþÃ~*­3‘v¯c6°'=xÕÎ*dLðÃUe"?_!¾ò‹)à‡Ò7>øÝýä×–Fì¹ ]qö ¹Î$¥á?$Ó ~hѧ.dø±óA/ëÉyùæ鰞쓲p™ŒC«§2 Ø+ºn° Ú¶Šó¸`•0_#Ï„«WÿAU®‹U9éä“U»uëîé©§ñä–ŸMœ‹Wz J¿¬+>-U´Xµ­µ•JJKµ ßí¢�Ÿ £ËËͯÖ6@ 9ñã¡ç¿£«îþÔr¥ýÇnBWž“:y?4((Eà‡·ørïNüp3ðà zÎmÁgŒÜJ�ÏÏý™.¼ÞzjÙù'mOGOîcLñ•Øæâ+y¶�"3ò‹#�CÕ5(XÑ Ë ŸEÊ,ç—=«�λVˆ‡¼Ã6Þ³Ûûýw?ÕÒ¤“_¡VóÛ”�îÇ�Ü�.:i3¬7y¤FðÃ#`ºuË�T#D>í­þÀoñͦõ¦QG, êó uƒwèA�\»‹÷ ¦é à‡÷ÀÃx�±WW?¼B¶³_ðÃÆ+~k  ',¢h—·J†Ã4ÿÁ=¨ªÂÝÛXS�üp§;‘Öà‡JÁ”‘åÇîGÍ¡š:ëÞ Vƒ©_Œ*ý `5ý:À‚À•wIW&œ°:xû*zä:ÿNXåM.VíÞ½Âõ)œì<׬YEÝ»•{^¬Ê× …BB…›QµëaÈ'--ÍTVÖÍõuãè(VmlŒ¸S[[›Q´ëÇÇŽß/¯£}NXd¹<'n¯?±WÒa�Þj üˆá›n~¨jüPEN¬ø~0ÿwÝûô¼å£yáöQÔ·O¹Q¬Šø*5§"‘!¾»ï¤’Bþ‘Çͥj›×°a�Ñ7äÓòœÄý^ìáÜïåm«k ÕûýÕwJSŸÿÎv·LHcGôv?¸$=€àG:×›T ù´*rbí�O#Ÿ±”¸ÿwÜkôûêFS“ÛTÒ7fç›ÀðC†ØÏKŽÖ›D,ÉYF5ÿ°ë9W⫳¯ZF3_Ya�à¬c·¥ÝÊtE øøÓA~.žŸïuü¬'‹d€@;(X…)�v®¸ë ãT˜ø'ñ‰[.Ékó)�Oßó±äk«×PyE%ñ©§^}øi dù„Q‘SF½‡ßýÊïMMQêÞ½\Û0�bÕhT¹™ÇßÜԤܞ'Â…x¬¿ôžŠ{·�~ZQoÁ÷ÑëGÐŽÛUY¾?´™¢mGàG°ø!«mðC19yðüˆ[ÌÈÃæÒê.Epåe!zó™½ ÿŠø*5·xóñ•ÜýÇNù‡3†»6—Ö `Õ(äÓÂ% â~/¶Ø�û½’y™¹¹ßG"-´÷ñ -?|�^ë‡iÆ=c(\œï~�]z?À� ¬7É6òiYÄää‘O#Ÿ±˜Dÿ±÷q¯Ð/¿5˜ší°u=}óH‘®2Jü?D ñâ+ÄWÉ™’n~|øy5vÖë–n´A ;o …BÞÿÿÿ‘U~`=YĪ :@Á*¬´#pù�_ÐÕ÷t¬é׃¾&öŠ.Võ&Œ½ÖyÍêUTZZæú•ññÅÑŠÊ**,,ôT·Ñh”òóó�ÓUsåÃ=üI츘‚O1­¨¨Ô�ÛbÕøPÅÅÅÊcb{å‚U ”/’ÐЉWÞù =üâ÷–K}@:ÿoÛ›¾?th$yàGì~$~Èhü�AK^ü?âVóãŠzÜB‹�¹Ýxá`B|•š_ˆ¯äï?v-œâ+™«d³ÿ°+.glFìØƒfÝ›�'3É辫,òi9ôp¿Çý^ÎbÔ¤uÜïù”>íÇîsĤÍé¢Sû© .E+ðüÐnT6êàG¼ÛlއüÐ…Ó5�O#Ÿv²‘øï‰þƒónο?üF~³I6}ÀðCÔž_!¾µ7rˆ¯äÑkii£ýOy•¾ý©ÖÒø–)Chìˆ^ò� ´€ÿ€ÿ0CþCÎ`=YÔ² b `–Úøï_Ðÿîí,XÚ¿'=ô¿��_½*X妺ºZ „\�xj×Õ«z]LØØØh\#—ŠU9Ñâé:}¸˜"i ÊJë ŸNm“ý®£X•çà¦�™Ûó¿ô.Â�×—ýN'^ø¶¶ªŠ"Züø^”×^iÎ5ø¡j}ÎíÀ�Xr4~8k.&~ˆ"¥&~€‰–óÐóßÑUwj1¦)§ö£ÇõB|•‚fˆ¯ÔîA][‰ÄW¢WÊvÿ1êðy´ªÚüQÆ«ö‚|Z”9DȧSc…û½¸-¥’Ôy¿?ö¼%ôö‡«m/wÏåÃh×Áëë4�N@‚N‰ý®“Ù‰!ê�òiäÓ¢ÖÕ5¾šxÒ+ô]—âŸ-7íF/ß=Z´ËÀË�à‡¨‘"ÿ@þ!j+nä_©¡wë#_Òí�~eiœx¨–ZÏÉ[ÁÀˆÚü‡¼ÿÀz²¨uAÄ@Á*,´#Ðuƒm§=iêÕÞ¬F¨¨¸X¨2•¢8`¨¯«5ŠUE *Ý(�ǹ`ѯ¢E7cÕÕ–ƒ÷¼¼<ã�Ó‡ñi¨¯£ª=�D…çbÕhc£ò ¼:N}ô»�ÁáGss�<|.ÕÔ6Yð¼åßChì.½Œ aðCØÜ¤Áÿ“[Q~ˆ(üAI]ü?ºZÏg½Aï¾ÆbT3ïI›lX†ø* Ý_©ß‡º¶‰¯D®– þc·#æÑkP°*b,ƒ|Z )äÓÿÏÞU€YUuí¦;èîFºC¤CPRDìÆÖÏú  )ARBB”îî¡A@f†i˜þg�áÎÜ8÷ž}âÖܵŸÇçû˜»v½{½gí½Î:k;ƉŸ÷bz$"eäóþÄ™ëxbø~ÐùÛºÐÇ¢Ë'µý¯ÞÂü`~èÕ!ÑúFòƒýM¢¨«—ãó4Ÿ§EµFÎ~P¶ºÿ&[4QºX(þšÖZ´Y�–c~0?D”÷W¼¿Õ½r¼¿R� eU%{EYVÍK€>,›üÈn]Ø~°ýÕ)¶Úìû“E5Œå�l8`•5�¸�ÀçŽbäO¹_15®]Ó¿n,ýêŒ «d胃ƒuãïŒì öEÿ€¦°­9ª£cb Ö¬*éï½{BÁ¶öÖÝ-Áª*øñÕÄØõÛ¿6Ãoݤ(F½SÃðl·Ì�\Ôn™ºùRl?ŒÁÑÙ­0?ÜäüQa?é€3öW—¯e Í€Õ6ÝÖ©…™#›ðþŠ÷WÎ~,±ýP‰p«'ÿÁµxX…�ÏÓÊHñyZÙÙÏçe=‘pÆyá§…§0jÚQÙî›Õ+„©ÿ×Hdhve˜Ì] ¤¢²3ø¡¢{M¢Ìæ‡&ÅÑP)/ñ£×KqäT’ %Š„àïŸÛh@Ƴª°¿‰ýM¢Éöƒí‡¨®è•ËKöC/¢õïÝz¾¸ÇÎXÚ*ª?|H5<Ó«¼hSÂrl?Ø~ˆ* ÛíöƒýÉ¢ZÆrŒ@6°ÊšÀÜGà³ñGñí´Ü€Õ&µ bš“V)#Q`` ® B6m2³2éôuä/i”7'©)ÉRfU£²ÜÒá�Ö84,Ìéëk¯w«ªåGÜÉ›èýò&›)PBÜ¿¦4A©Æe»µ‡óƒùá*’ªå‡]�eûáÔ%SëüaûaÌrx:?ìz¼;¬*t¯` ^Ð óÃ=ÎQO燜êº{ÅFu>O+ï‡ù¦ûßy?¤Žsö¤�ù¼ï÷úì—ÉOcùèÅšè×µŒ¦I¸ûy¯iÐ:+ñ~ˆ÷C¢*ÄüP¶¯l?DµÉ±œ3í‡1#´mÅ?{u3O´¨T¸@0ÖÍnë¬á¸¤]¶l?D�íÛQ]Ñ+—×ì‡^#ÇçiûKí úìjEäç}Þ|ÞS¶øGž[�”´,• Ì�%ãD¹’ê>¸e~ðyÚUÏ'>O» i}ý°ýÈ›öCŸVÈ×V²O¼¾û¬>²ˆ� Ħyí�1—´Éü`~ˆ*š?DÛñ&9æóCT_=�ç.¥¡ÛÐuÈ̲ <ðχe“Bébƾf~0?¼‰¢c5JÎh~°?Ù¨•áv|Xõ••æy*"ðɸ#ønúÉ9ó+Íh˘O±e5FÏQk©©)ðËï‡à�åNuJܾ}[ Â4*Sçp\RýÞ½{ÂÙo)X5))±± D¦ zBfU 4"g~PP�K07Í[4HØzP?/9ƒ“ãlÆZ®T8VLnå´90?CËü0NõØ~‡¥3[bû)P՛쇹>8suöR:Zk£~æH9S7=¡mæóCT=eÕfÀjPp–uá€Uù•äó´<.ž¢Ï¢ü3BŽŸ÷yûy¿rã%¼þåYU©T6‹Çµ„ŸŸ˜�ùÁçi#ž9"mðyZ%÷˰ýÈÛöÃH ±ý‡oÅîCñÝFE`ë‚FÅem1?˜¢Ê&ÂѶ¼EŽùÁüÕUOá‡\pšÃ[ƒ«aPïò¢Ó’c~0?„€§ðCt¼FÈ9ƒìO6be¸ _B€V}iµy®°~ÁÖ¼~!Lù¢Qv£"V X ¦D`` ­9n"33S TÕDèô:¡-›“˜˜†e!õÕ`U½KŸx>ù7îÞµmé×±-P½b”Þ.lê3?Cj Ve~®zšdû¡:¡Šl?ÜãüZ!gócœ7û¸ÍH¾x­zv,%0Bïa~0?D5Ø“öWmŸ^ƒKWÓm†Î«ò«Éçi[\O+*‰‡ 8û¼`>]æóÃÃÔ_q8žÈ�gÞÝŽíû¯[Œ=<Ô;uTœ�§ ðþÊ7öWFèÛ¶Fè‘+ÛðDûáìùÛó׬�cšÚ=Û¶¢ ÅöÃ8ûÁþdQ­c9F XeM`î#ð¿±GðýϹV[Ô/„ɰJ›÷ÀÀ Â#-¾»7'Fe?p–‚S0ÞÍ›  `<£‚‡)+Ý­Œ „†©»BÏÈ9º#3žQãöá6lÜ}æ¹§-‹÷Ÿ«aT7R;ÌåÍ;óÃP•ÓÝÛÝÖÛà4¬!Wð£Ó µ ëžÌ‹¿>l[С!~†ÍE©!Þ_)!äœß½yå ~˜P÷´ýU»§×à"¬ “‚ÏÓ–Pyš> /¤‹y?ä" Ut£æyŸ’–…Gž[/›…šºüâõÚèÙ¡¤ÝÞ™|žV¡š!ª†zÌü`~èÕ!W×÷T~ ù`¶ì¹fGp°ö,é¤">Ok†NWE>O‹ÁÇöƒí‡˜¦xŽ”§Úg d²{âÐÿ­-¸GI²ÌJ€>,›üJ uF÷Šmòù\"— ø"?\²`‡jùÁþdA`YŒ¸�¬²*0÷øø‡#=#7`õÁ†…1ñ³†Ù¿z@†Õ´ÔTKO�]Ü}¸½uë–K¯¢W‹'�/11QQ1V[]V>#=wîÞAXX¸!íii„MôŸ¿¿¿–ên­Cüظ'¯¹Ïf‘aþØ4¯(0ȈÂüpŒ"óÃ-3¶ ¶Æâ©§5æ‡ôœS×ü8v& =^Øh3�6�‹`Ü' œ31™Vyå2¨-:òöý•/Ÿ?: \‹ÿ®XšÓⶨ_Lnæ…òà^ù<�»8|^àó‚SUvhZöCû�$ ßÛ£³÷¼ï›ËÞtÂü`~ø?´Î‘ùÁüЪ;Å~h«Z~<÷ñNlØyÕ¢»À€üØ÷{gMCàó´&ØtWâó´„jù!Öª¸óC+#%™bhz ?“2ÑmØzÜH¼e3ð�^¬‰~]ˈMÈ`)~_a0 4çÉû+¦gÑD^´ìO6ZK¸½¼Ž¬æõæù #ðñ˜8Œžy*G¾U£ÂøñSÏXMOK“‚UóçÏ/<­‚YYYR?®èKnŒ4×à�äËgLp¡VìÕËÙ¼GFKã4¢ÐæóvæmDGÇÑœ¦6èjúÏ]ë®iÐ÷+™øq÷n>´è÷7’R2mšóa=´o^LO7R]æ‡c™ºUÌðØ~©æ™š¡sZEWñãûŸ�bÊüÜ=¦iB#ß®‹‡[wÚüÌæý•K`¶é$/ì¯\±7ôÔýUÇgÖâüeXeŸ§³‘òT}]GgËñ~ÈÙ«o_Ï~èǹ'0vÖqÙN ÅaÉø˜ó;óƒÏÓê5Ô½5ôðCíș̵:ãnyOçÇKŸìšíW,`òóˇƒË»¨†ŽÏÓª!3¤Ÿ§Å`dûÁöCLSÔ¸&˜²^¹1Ã*¥7*‹§Òb»ûpK)îCBB=6h’Ö‚2«FFD!4,L N¡ß=!X•êéWÙÓšÿ÷ãaÌùý_ñÖ�Š`ü§ú²Ø1?«4óCˆò.bûáR¸vÆüðœµ0�Ä•ühÓ5._ϰ!00?¶/술@çŒÄû+÷é_^Ù_9AOÞ_u´ç/qÀªèúóyÚýÁªü¼ÕVãå|ùyÿüÿvbýË v&„kW�ÁœQÍ@ß^{òóÞx�Pß"ŸÔcæì®ô%MB „‡GHÿQèK©[·2#4#ú¤ùR1Ÿ³(FôoÞ†3øqèÄM<öÊ&›¡RÂÞM¿´GLTnv5óa~8F‹ù¡F›Äd�Á±žÕK1?˜êµF_ oâÇÞ¸x<ùæV› wnU £Þuî×ó¼¿âý•Z¦ñùñNƒÖ⬠«Ÿ§ù<íHYø¼ L%aAOÙ¥¥ßA�7ÈøÓdúu+ƒ÷‡Uc“ƒ•e~«½° §ðCdÀ|žæó´ˆž)ã+üxóë=øs½mÀê¡KR(>OóyZIG¬çó´ZÄ´É‹¾Ëâý•6|Õòû¡9kû±'.ýßÚ‚û¯fsš È�Åã[¢|©p½]æÔg~@ºITä�¿a ßoˆù!†¨/ì¯ØŸ,¦ ,Řà€UÖFà>ŽŽÃ³r¯kmݤ(Æÿ¯¾ô+]NŸæ'^ô8É`S}ñuH꫎n¥ª4×””d„††Á•Áªj6­¦Ã-e�ŠŠÖ;e©¾;‚UiÃLÅAÉÖ éÑ9%~t¶§Î¥Ø¬Óð!ÕðL¯òª×OÏXUwfU�ùá:稯ðC¯NÉe½ca~0?Ôê�’ýPÛž’<Ù�o§ÅŒ¥¶™¿Ç~\m›UjBóïÌæ‡Zåq?Üù±œÈù£Ë�uø÷Bª ”-êÀ“›©…8ÏËóyÚ}Šè³Ñ Èçi£Uמž3ª3ž÷gTÄ‹ IDATΧ Ï+›�–qGv"Ÿ¼T�=\VÝ$ �æýï‡Ôª‘3øáh z¸¬vnÖòÌæ‡Zò6~¼=b/–¯½h3Íý˺ ÀŸÞöØ/ÌæG^ç‡Úù™Ë3?˜jõÇÛì‡Úù9âGbR&è}å�Ä[6Í~þj-ôêTJOw9uù|nŒšѳ§÷e~h\eEWóƒýÉ*ˆÅ}Xõy`L|ð}ÆÎÎ XmÓ´(Æ}œ°ª¶ÐUôVk¦+¯;ѳ‘R‹‹µ†ÉóOÊV Ê�9ß6CõŠQâ j”d~0?4ªŽËªyÓ~Èe ˜ud ¦`“qè{ãyZï a�>€E+ÏÛ€¸sq'„…øÉ‚Ëöƒí‡q¬sNKl?ØëͲߪ/Ú-ËÙ�áßìÅŠu¶™¾Ë— ǯ?´pøñ„–1(Õáý•Bêg~ˆaækû+“?ùÞÝ[È—?($ö'‹é Kù°ê{kÎ3¶ƒÀ{£cüÜÜ€ÕöÍ‹ȧê¾pÊÌÌ”‚U=gú꓾T¦ÿ\]h—�pÑѱØkÚ¼"¶@AC ¢6ÓÓR]šYÕ“6Ì®äÇ›_ïÁŸë/Ù¬[år‘X:¡¥âz2?Äœ?ÌEUp%?„eG�ùÁüЫCjë{+?z¾¸GO'ÙLwå´Ö(U,T- Šò¼¿ríË5Où@Í[ù¡¨Ð há]Ûvꬊ.Ÿ§E‘Ò/§EŸõ÷ª®>O«ÃKDÚ[ž÷ƒßÛŽ­û®ËN):*Pz9[¼pˆÈ”5É0?x?¤Iq\X‰ÏÓ|žv¡ºI]y‹ý ±É�OÇÄü?ÎÙÀ½í׎ˆ ó·ù;Û¶®æ¦ÚþŒä‡Ú¾™Ìµ:ãjyOãǤy'1fÆ1"ðh\K”(â¼ó�ö|>7^#}u¥I_´äO>ùop7ùü#r ã€UµÚÃò¾‚¬úÊJó<°~Á¦6%?mNè Çàà`žÜ-àÎÍ;a”‘‘ŽÀÀ §«ñ•)mÞ);™¿Ÿ¿”YUïÝ´ÞôÑíÛ·ž»9q¶ÐF�ð Êý‚ÇÙ}ÚkßÕü8~& Ý_Ø(;œ©_6B³º…ìBÁüP~yÀü0–I®æ‡žÑ3?˜zôGK]oåÇ®ƒ70àím6S¦«p'~ÖP ëðþŠ÷W†+•Á z£ýxä¹ 8y6Ù v0Ê+Ÿ§ &��æøyÏÏ{×hšö^’Rn£ß3TS«¥‹…bþ-nü­DÌæ‡vÍuMMo܉"ÃþØ\¤|Ù+ª/rrFóã‹ ‡0wÙY›®¶Ìkú€Â¼°ý`û¡Gw]Q×h~¨3óƒù¡F_Ü!ëiüX·ý ^ød— þþù0sdSÔ©# ï¯x%¬,v=�zçc½£¤lzb8œÒuèjœú7ùü,–°?ÙÈÕç¶ò°š—V“ç¢ �wGƳ «�,†ïÞ˰Jލ¬ÌL‡¸ö«(-vçæ„ú&¬œ•�Öˆ«úL_šùùù¡@�Bº6:¦õ¡qÑÜ\–ÑÖ“tÒ]còþlÙ{͆&MjÄ´¯ËÒ‡ùáø©ÂüÐòÔu\Ç]üÐ2æóC‹Þè©ãÍüxåóÝøgËe›éOþ¢ZÔ·ÿÑ„¼xÅû+-zãÊ:Þj?ì¬>ذ –OlêJ½¢/>O;™øyÏÏ{çk™¾LÏû«ñ·Ð÷Õ͸z#C¶ÁÚUc¤—µþÆÝøÃü`~èÓ^ç×öÖý�2ì�ÍEɓΰž4%=r?¾ž‡™KÏØt½qn;ˆÉMîÀöƒí‡’~ºûwgðCtNÌ懨®¸KÎÓøqèÄMô¾·nݵ�däÛuñpëâÂPñþŠ÷WÂÊbGÐÓø¡w>æõ=™Ý_ »ÒmâAØŸl¤p[y XÍK«ÉsÑ…ÀûßƸ9§sÚèܪF½›°š/pïž|ó”ù‹‚UCB�¿ÚUׄd*ÓÕ¥ôµ‰» } F� Î(”Á”æ§'›¨éKú'6¶ !c%ý öœ5o9,=I'Ý9º†�®#”+K'´Dår‘?1?3“ùaü“Ë�üP;æóC­Îè•÷f~\¹ž�6VÛìK ÅÊé­õBcSŸ÷W†C*Û 'é¤'�E }o¶”­Ÿ²ö[v0ʯ:Ÿ§•Ø ÿw~ÞëÇP¤OzÆzÒX”°³~ÞŸ9Ÿ‚¾¯mFJZ–lÕ¶ÍŠbìGõ•šþ�ù! •.AOÒIO‹¨Þ¼Ršûcsò$�ô¤±(é�³ø1rêL_”û®Ç4ŽusÚ¡plnÀ*Û¥2æwOÒIO‹ºÎâ‡R¿¦ß™¢Hé“ó$�ô¤±(¡êiü p�—6"ñæm›¡îSoªª4¥œßyÅû+ae±#èiüÐ;óúžÎ�^/oa²‘ Îmåy8`5Ï/1OP�¾�ÃØÙ§rÄ»´*Žoß­ë°º7]S+Šƒ7ÊÑæäNV–® aS0ÍŸ2«úûû놂¾ð¡aW«Þº•�ðp×]Ub(Oà‡½@ƒŽ-‹âû÷�{9¦[YœØóÃòpËüp¢²yaÓÌæ‡3ÔÖÞ‹±�^¬‰~]Ë8£K§´Éü`~8E±¼¨Ñ/lÄ1X^1>O Cåq‚ü¼çç½³”rסx ~o2³ä¿ïÝ©>{µ–³º7¤]æóÃEÊ£�0?˜yTµ ™óƒùaˆ"åÑF˜Ì�¼¦ÚéwÐç•M8}>Åfj5.‚ Ÿ4ž2óƒù!¬,>(è ü`²*&OY°ª >®œ—°~ÁöðCÅ1òû«ŒH_¨Ð5ïž^hœTÜ™]ÕYÑæäöí[º4Mל>”YÕˆ5¥¯O©¸2X•t2--‘‘Q΂[¸]OáÇŸë/áͯ÷ØŒ› ¯œÖ%‹†J³ÿ]I³oŸÎ¥ñé+¸/g €ù‘‹,óÃYZæ½í2?˜ÎÒÞy+Îá³qmš¦Wy RÍYÝÚ.óƒùa¨Byqc½^Úˆ#§8`Ut ù<-Š”çÈñóžŸ÷®ÒÆé‹Ocä”#v»{¢[|øBMW G¨æóCHQ|TˆùÁüðQÕš6óƒù!¤(>*Äü`~ä5Õ¿{xá“�ذóªÍÔ Æañø– ÿ)Ì懈žøªŒ7ñƒýɾª¥O»fÃ:áç=?ï S&Á†FN=‚é‹NÛ•ö¤�{˜ÌAµöI1æóÃ'_pÒÌ懠ªø¤óƒù‘ן’å¼õÍÐ-�Ö%"Ì¿|ßåK… M›ùÁüRò6~°?ÙG•§­XÕ WÌkX¿`{´m |õ–mÀj^›·7Î'##éº4Í3«FEF#$4T7îÖ”‚US’ÍAÔvV�®ähýÔ?ˆ¿yÛFbÈcðÆ3Uu¯½'5Àü°:Ü2?æóÙJ¸i÷5 ýp‡Mm›ÅØ�ê;³kCÚf~0? Q¤<Ô;Õ-&Ÿ§ÕáåNi~ÞóóÞ]ú÷Å„C˜»ì¬Ýî‡ö­ˆ×Vq×ð¤~™Ì·* ‡wÎü`~x¸ŠºuxÌæ‡[ÐÃ;g~0?<\E5 ïÝ‘ûðûš 6uCƒý0cDSÔ¨%Ô.óƒù!¤(>*ä�ü`²�*+O[3°ª:®˜×øxLF›eXíÞ®¾|3;`•2cÑ×R\Ü�€Ñ›“Ȉ(„†…21 XÍŸ?¿!m‰4BÁªÉI7ëÒ~EÆæi2“æ�ĘÇl†â‡usÚƒþ7/æ‡åá–ù‘´Ú¸90?˜Æi“|KÏ},ÔŒoš a­Îî^WûÌæ‡.Ê£•û¾¶�%âÞÝÛÈ—?7#?gX•_p>O{øyÏÏ{wkêÇcà׿ÎÛÆËý+ãù'*¹e˜Ìæ‡[ÏK:e~0?¼DUÝ2LæóÃ-Šç%�2?˜^¢ªª†iïC¼ÀÀü˜ñuÔ®#Ôóƒù!¤(>*ä­ü0ù“­—�ýÉ>ªÈþáFÏ8™3ÝJâÿ^¯íqÓwGOOÁèÍIxxè?#ʽ{÷��"›]T(X5éf¢¬êç—7‚-�€Î?RÓï E¿U¸uë®M7o®†Á½Ëѽ[Û`~Xn™¶êÈöøÌÜl?Üú¸sJçzùqþR:Zk36ºúiùäVN³Q�²ý`û¡¤Kzù¡Ô¾§þþøk›±ÿÈU€Výs¯q{¨QAüþcSO¶ÛÆÅçi·A/Ü1?ïùy¯¤,®zÞÛËFdßð!ÕðL/מљÌOá‡Ò8Üñ;óƒù¡¤w®²JãpÇïÌ懒Þ1?ØK:Âïóä™â�ü?çÆÏ>n3!?¿|˜üE#4­SPé± ýÎöƒí‡’¢x#?”æ$ú»7óƒüÉŽ%ÚL•ýÉ¢«Ïr¾†¬úÚŠó|í"`ý‚­g‡’øÂÃVïܹ Œô÷÷×¼’Ôeuep¥æÁšUÌHOÇ­Û·­¹¹[·n!11^ÂÐÈ̪š¤±"no&&HÁªztAc÷[M‰ßLŽÃŒ%glÆ€53Û"$ØÌæ‡Ç*¸Î�)ñC¤yæóCDO¼QÆ~|>î ~YqÎfúŸ¿^½:”ôXXxeéåý•­ªÁoµ�½¼�^µV%„ØÁ(ÿHãó´Ç>ê¥�ñóžŸ÷JêÊç=Ý`ôÖ7{ðçúKv‡õÊ€Êx®Ÿk2­2?˜žÄ¥±¸úwæóCIç\i?”Æâêß™Ì%�c~ðû<Ò~Ÿ'ÏoäÇ„9'0N&X•rýðQ}´mZTé±Àçs+„˜y‡BÊ/ äíû«~¯oÁþ£ 63e²ÀⳈO"À«>¹ìªzS�#—¦¤$ƒ¾$2*X5:*Á!!šqtgEZC º�ŽŽE@@€;‡âQ}‹ðãÊ� ´{z îܹg3ö¡}+âÅ'Ë3?îÝóãTÛ�ÁˆðC©#¶ÙÁªÌ%Mñ¾ß�àÇ•ë©è8xnß¶ÌâMD¬ŸÓ�ù=Þ_Y. ï¯ì;G}ùü1ä½­8x*ËœÖ� á· M<Ž×ݽòýóóžŸ÷"šiÄ~Híyáî]à•/vcÍÖËv‡8 {9¼;¬ºÈ4É0?˜"Šã~ˆŒËÙ2Ì`çŽضm RRRƒ¦Íš¢zõØk¦|¾Às=ˆ��E§N�QºLY~_a¦®}QºLg? uµï ü�ˆíï¯Dˆã�üøzRf.µMˆCóýzx<Ò¦„âÔ™ÌE%¤ÄJ¾ì�õöx�'ߨ‚½GlVÙŸ,¢ý,ã‹pÀª/®:ÏY�OÆÁwÓsV{w*…Ï^õŒ€UÚœÜÊÈ@hX˜æÕ£ì¢”YÕ›‚iSã:‚‚ƒ©kîäI…=ƒ‚‚4·åΊ®tþ(͓ֆôÉŠ~|>á~YvÖfØL´rÚƒ(RP;Ç\�óÃs·ÞÊ{:Ìöƒí‡‘Ï·¼È�/~<ŠE+ÿ³�é�gªbÈcŒ„Ï�¶Ø~°ýQ$5û«¼j?žÿäöıƒQD_H†ÏÓ¢H¹NŽŸ÷ü¼Ñ6w>ïécÒ?Ý… ;¯Új×ÖÅñÍ𺠬EFæóCDŸÜÉ‘ñ9K†ù‘�ì¨Q#‘ž––séÒe0àé�΂]¨]Z› .àÔɸpñ"nܸŽä¤$é[S!¿wHh( ,„²åÊ¡r¥Ê @K£‹¯ðÃZÊ”)‹Î�;óûŠû åê÷3~ž†óçÏ£a£FèØ±³…ZçE¿Ïã÷yF=»™ú�ütÜAÌ—¹Y‹Zýì•Zèݹ”b¼¿â󇢒ÜVåxïŽyêÍ-ìOQv–aî#À«¬ ŒÀ}¬_°õé\Ÿ¾ò€Ûñ!çOjj "#£4�%-5þ Ô܆«+’£�‚U)jXX¸æî)Њ‚U)³lLL¯ Ø5Ÿ49n **Æí·¤“„§'¬ªåGbr&Úö_�ô[wltªg‡’øâõÚšuÍ•™¶‡[懭ªå‡œ³ý`ûaä³Í›í‡=~\M¸ƒ®Ã6‚²„™—ب@¬žÙA�žñq‡ill?Ø~ˆpšíGöùã©á[±çPöG æ…¿ˆ—×">O‹°Ëu2ü¼ç罈¶yÂó>+ë†�؃•ígZmݤ(Æ|PþþÆD­2?˜Þ‘q-ãL~lÛº7n@›6mQ¿AC£‡nx{ûöíÆuk‘’šŠèè(´iÛU«:/ë³Ònݺ�¥KáÄñãJ¢6¿W¬T-[´D‰’%Uו«à öÃ�‰4"éÁúµH•ô  4@õ5=ú}Err2öí߇3§Náú�kÈHÏ€¿Ÿ?b Ä‚n+Tªˆre³oÓSÜñ¾bì£qóæMÔ¨Q=zöʾ'ù›NŸ9�E  ~ýhÓ¶�&ˆÙËþXMŠc§’'ñÃíLJßïÇâU¶‰ î¯ÞªƒGÛŠeVå÷ݹ êûa�SÌ#Ÿ6ÚÚræùCÛˆôÕb²>ü¸¶ï!À«¾·æÂÓÏÏÏ­ã ÎµòcÒ¼“3ã˜ÍøÉG·tƒ¨T6ÂísSóÃöpËü°Ô­ü0o…íG¼d{Ù~(=‘Ä~'[æíöCŽÃGĪM—l@ �žèã'O+l?Ø~(é$Û�ÜóGÿá[±[&`µM“BX:¾‰”>÷;Ÿ§=kÉùyÏÏ{%�ô´ç½£Á4—&µ bü' ¬ßÁü`~x?”ÆkäïÎâGVf&¾õ-ngÞF£F�Ñ¡c'áa§§§cò䉨_¯Z´l)\O¯ §ùc�;Š%KÛL+2* �:vFxD²²²�‘žŽ„Ä\¤L¬§OIÿ¦BÁ‰ 6Bë6í ÝGîiöCï:«©ï,~¨ƒ’ìž=»ñ÷ª•ÒUÂŽJñâ%Ðç±¾ˆˆÐæw?ÆŒù^Ê*\£fMôè‘°êiþ¦ËÇ�P²d) |f�Ò’ÙüÎþXöǪV<�Þô¾›’—¿3r/–¯½hƒ0]>9âízèÒª˜ÐryƒýšˆBî²rCg~° 4‘×øÁþd”‚›ð)8`Õ§–›'ë�ÏÆÅ·öVécÓÜ›u\$9n&& *:Fsp lR�¦hp!9µHVï×µzºy3Q VÕœi VõËØÂè»ÑõiÃQ¬btóªÚ»}û¶„£¨>©j\¥°~ܺ}­ÅÕ6½¶lP“>—ÏòÀüP¹H.g~ȃ¬‡¦Ù~ăí‡q$Î+öÚÇΤ ÷Ë›l€*[" Ë'?r^Raûaœ.ÕÛ¶ÖÈ�?¼½ »Þ°‹Våõ‡ÏÓü¼7êmd;ü¼÷®çýדâ0sé»*P£R~úª "ôZ±¿)^æ‡wñÃÈg£½¶œÉ�cÇŽbá‚ùR×ÝéŽÚµÅo8:|ð–,]„ê5j gÏÞ®€B €ó4ìͤ›XóÏ?ÈŸ?EŸ"îða ‹ÆMš¢}û²¸deÝÁ‰ãG±aÃz\»vM’)S¶,úöí§é&6ö7yöûŠC‡aé’EÒ:‡‡…£~£F(Y¢òûùáÆõëØ½k®\ÉÍhnô©†XîäǘÑß�2ÈÖªU�<ÚžèoZ·~�ÄÏÒ¥Ë`ÀÓÕ@ öDz?V•Â({"?¼å}÷�;÷ðÊ{°v›í-~~ù0úýzhÛ¬¨Ðr9s%4r§ý°†�ùÁñ ΢û“�…,·›Wà€Õ¼º²‹¬úìÒóÄ­ø|ÂQŒüéDΟ-V]˜aÕ(ç�è Ó!øVF‚‚ƒU9©µOs GX@@€è0$9 ê ë‚ÕÖ3ïĬ$e§U0«jÀN6}iŽðpmWó5¼´ÔTêZ£Æb?è:�GŸß€“g“m†V±L~Ÿø ôwæ‡Q+gl;Ìy<�â‡èj1?D‘r­óÃ5üØ´û†~¸Ã¦³ê£ðëØl?\«ö½1?\Ã¥ñûñ̻۱}ÿu›épÀªü óyšÏÓJÜwåïü¼÷îçý¼çðÙ¸ƒvU¦@L¦Õtv-ìoÊEŠùáÝüp¤óžì��:e._¾,%(xkø;ÂþZÚ7~ÿý·HKMCóæ-кM[QÚk’åGbb"(klõjÕ©ØWzZ< †‡‡+Ê“€’?vٲ߰ß>DGG㥗_jóø±cX¸p¾t^m×¾š4i*T�æ{íêÄÆ@ddÕùü…:1rÆy!557o"""\hÍLÃñû‘š’*q…J÷=Q³¦ýD,4§«W¯ hÑâPÎZž”œŒŒô4äÏç‡[·ÒmÈûЬÌL$Þ¼‰»wï 8$‘ÊvݰZ¿~I‡õ¼Gr¤—„QRR’”L&22Òá�sæþØøøxL™O‹°Î± Ÿ§õcÈç…¼u^X³í2Þør/ng泘Ï�²}÷~]´iRÔ¡òèÝsðyA?7­[Èëç%ļi?¤4~ܸ~?þ8^jŠ®ñ~¸k7¥f¥ß‰»ÿü½J l£Ò±cg4lÔ(§.QŽó½°ùÆ›Ãí^RóÑÿR ¢œÿY­ý¸qã†,KmÒõëÏ ‚ÀÀ@›yQfÕ™¬zõ*üýý0hðP.ìøaQ~œ>s sgÏ–ú|õÕ×…³†Ràð¸F#%5]îŠzõêË®ÇñãÇðëÂ…r‚‘QQhÓº-j> ÿÅ”ùÓÏϯ¿ñ‚ƒƒ®¿#~P@azzbbbU\¼xK—,e¼´WÂÂÂ@ÅT~¸êÖ«g!êÈ~ˆèñ#!áîܹ+ùØíéŸ!¬„¬Ç–™™%†“N–-[O>Õ_#Gýµþæ}PFÕß~[Š#GâN94,Ï?÷¢ì»‘Ñß�’t·]»hÒÔq†`Âÿò•Ë(^¬„b&Y Îýcùr¤¦eëƒ\‰ŠŠÂÓIW©ÐÞý§©S¤lµjŠžlѾf?Ôàj.«w罹_µöCMÛjeEí‡ÚvµÈ{›¿éÜ¥4 zw.^M·™nTD¦ü_cÔ¬% …^Ù_ FÁ~hmG¤óC%oã‡Ü,ØeŸìOy:° #�‹¬²60÷ø¿‰Çðͳ «. XuÇæ„/ÜIÎ"# Í�²µFD(_ƒdDæm˜6ïá‘ ³üÊUo_4/£0R mÞã­è¼SjKÏït˜2éG^V%ŒNü›Œî/l�ÍÚòú3Uðìcõ@™S—ù¡Fæ‡çnÙ~ˆé3Û�¼ŒGÉ?:Zƒ Wl˜¿ýø ŠÄÞåý•E˜y“JKïmöÃÞ‡M°*¿Ò|žVb€ãßù¼ ?ªÍç…¼y^8p4C?Ú�¤”L»JòñKàñ‡KëW"™Øßd,¬¾äo²‡œ·í‡i€(?Î�=‹™3³³¤¶iÓÍš7WT,²‹ˆJÙs »v“^M…®)ÿaôwÒ?¼*VªlÑ.e7Û¾mvîÚ�”ädé·ð°p´i×µjÕÊ‘ud?æÎ�ƒ‹þCßÇŸ@©R¥,Úß´qÖ­[+ý­z�èÙ³·Åï\9{ÖL)ë"¥¬—jùAíN™È#ämï»�¸‰g?ØŽ›É¶ç�"ƒ1cDS”.ª¤†ý.º¿ÒÒ!ûcÙ«Eo¬ë°ÿÊ1ŠìO6B˸ _B€V}iµy®ørÒ1|=9×Qñx×2øøÅšNGÍY›w{_pI‡û›‰Ò5ï!¡Æl²itu|d¤øfFkÚ¼GQ�§ƒ+Œ´ôGNrÄiÍüJN k'�½qP_7o& ::Ö­MI?ÈÙéÖq˜pr?>øn?–üýŸÍÒ„‡úcÕÏm¡ïÃü�×z懖§’eWðüG¶âkÆöCßsSiû’ÎâÇìßÎàˉ¶Ù@º´*އ•áý•Àâ1?ò.?òÚùcè‡;°i·m†ÕöÍ cÑXÇW¹ P!ωðyZû’òy�Ï ÚµÇqMgí‡\ý¼?~ú:Þüæþ½`?ëÙàÞåñæ`m×ëÚC‘ýMÆj¦/ú›ø<��Ο÷‹ôÿšð2�Nž8� æåÀøÈ£ÝQ«VíœS@è¨oGHÿ¦¬­¦`Vò7QÐÛü_æâ¿ ¶þ>’7ekuä�½ðߘ>ý'©ýÎ]–Í õóËœ9 L§TÌ3>RÿsæÌÊ Î£Àµle—TZøqåÊL™ZÔ:bð®�;ñ×_Hu¨®y¡Œ¤?ý4·22Š'žì�¢Eå3YÓüó÷Jìß¿_j¢uë¶hÞ¢…M×°L�ËÍš5G›¶ír~�;|K–,’MÅz� K ü½|ù’E» L�ÊÖ…2ºNš<i©i «Üûô鋲åÊYˆÞ”ÓLL?Rpçä2›*ØÓ{úGõ((vá¼_påêUÙe°Îìh­¬stž¾zå*¦OŸ*S)R¤ˆ„w… ¹ ”ü±´þÓ~š"qˆÞuéÒ+V–}O ºþ4–?V,Çž=»¥qµlù Z=ÔZví¶oß*á×¾]‡œ¬Áæü˜0~,’““Ñí‘î¨];÷y@ó:îvïÞ…¸¸Ã9:Ž®]»Ù´›:§gÄŒéÓ$ù"EŠ¢wŸÇc3¶•+ÿÄÎ;@Ù__}õ éý‰ÜMWÄNÁ­Tú?=eJ—^^Wï¯ø}žíÒ(ñü¿Ï“Wmo;lÝwÏÿo'nß¶½Ñ¡b™Lûª1 Æ óX¯ Ÿ?ô"hY_ËþÊØX¶æmü�ÂýWòbn?ØŸìLqÛyXÍ‹«ÊsÒ„€ÃlùäúM4µ/W‰œÉI7 ¿Æ™6µä�±.´9KLˆG~??DGÛ¼µLŒ6't «ŠgjéG®Í“‚<£¢bdç«§j›‚UµfW5e v¥Ã-GÇÄJ}º«Ð˜“““¤,¹ZçmäØ]Å�+72ÐqÐZÙCé€îåðî°êš§Åü°ï¸ çóC³jIÎg¶Úñcû¡;{Ž _°‰Iiè/hÓåZyíyŸ”š…—>݅݇ì_íܵuqŒx[>;ž2b–|^P‹˜cy_õ7™Pñu,�-^ô«G÷½¤Ì…öŠùyaÖ¬8ûï¿9¢Ýº=ŠÚuêäü›^ õåRÆMSéý{îœÙ8þœäwjÞ¢%êÖ«�|÷îá�?VH´ô÷�OB`P€]ìæM›°víj©¿~O*TÞ{^ú{VÖÌ™3S D$Û¶m�'O`ù²ß¤ßŸ{þE,XÐbx‹ÿ „%ß6áRÚNÀàÞ½{°bù²œº=zöF ³Œž¦ìé�œþQ�´´4)XùÊåËõoÈ�a(\¤°´¿‹œ§)»ì’E¿"!1!§.aТeK”)SVzcÏKë?í§©R o`Pyä)XUé}…Òú›gY¦Ìª�õ}\xÞÖüñõW¸�y[ÊrJÙN¯^½Š¸Ã‡pèÐA$&&æ´[¢DI4lØÕªW·ûžƒÚž4q(H—‚{<ýŒÝwL§OŸ’ž+��òì³vßç­]»›7m”Æ1tØsRY‘ÂïóDPr,#ÂG-ðû<ýkàmçJbCÉläJÝê1˜øY#D„¹î}-Ÿ?ôë y Z÷WÆŽ"·5oã‡ì¿’×kûÁþdg±ˆÛÍ«pÀj^]Yž—j¾š|_M:–SÏ™VMW˜dfÞÖ�Q“®æ!Œ)XÔ^JSf¼|ùó#**Z5>r(Ð2--U V <3¤Óû�8ó Fú‚˜1JÎ{ó¡5¡"RŸæ‘’œ„¨è·‰Ò˜éŠ Vuwq?¾Ÿ~SdgD°.K&´D•rêqa~ÈkóCÃÜÁ¶âkÆöC+gH:›æžÂ�sOØ ½W‡¢xkPÞ_),*óÃZ/Þ¦³ù!÷±“·Ûʲ±~‡mÀj‡æ…ñëœaÕZûø<-ÎG“$Ÿø¼ ^k”käõç½½RLÈ}P¥rîôt-ù´iS@W†WªT ½ûôµë�]²x‘tå=•—_y QQò7‹íۻ˗ÿ.ÉEFE!*2J –¥R¦l9<ñÄ“vûÐÃ�K—.á§©“¥~(”‚AE‹)€´|…ŠÒø¨�®nذ›6fÛ٠ҕ냂7'Ošˆk×®J× S&Uó÷¦Ù蘼ôÒ+R?OûI êmݺ�xŠïF��‚TŸyf0J”,™“•³T©ÒRð¬éýÇÄÇãúõëhס#š4n’3$ó Þöí;¢q“Ü߬Ç�˜�ˆqãÆäü™2kV­j›©Û‘˜ë_×n�€øñן+@WÌ+é_�5Ñ£g/Ñ%“2žŠ¾¯ÈÊÌÄ–­[°mË)¸ÓTÊ–+�N�:Ûùš~'Þü½j¥ôOÊJú@­ÚBï+¬×ß:›ð pìØiý( 966VhÞÖü `®‘#¾–ê–+_II7qãúõœ¶‚ƒƒQ£æ¨W¯¾€ªT(3ð²ß—ÂßßÏ} °[åÈ‘8,úu! ,€ÁC†Ù½™nÍš°eóf©�W^yMz&X~Ÿgü ƒjø!·Èü¾B‰-Ž÷ÆóÇèŸ�aòü“²kß¼(Æ|X_(*kkÙ_‰vÁüEÊ9rÞÈ9$Ø%¯röƒýÉÎá·šwà€Õ¼»¶<3•|=ù8(+Œ©ôëV½`ÿ‹o•ÍçˆÓ>þÆuéš‘˜ØB‡~G}Ù»*ļÉP0"õ¡uèõ(“Úí[·¤9¸#X•2 R�§HP¨š g¤§Ã? @s»¦+w”¯{•6x©)ˆŒŠv*†J:Bc¾“•…à�5P9EÖ]üˆOLF×aÛ�”’ll^ªUˆÄÂZ‚2è‰æ‡ý'\¼p11±HHÈάܾCG46 N¤¿M›6U’«P¾z?Öt}ûìÙ3%y{×®S*!JÁs/¾„Øù³ÜÔ)“¥kèýüñÎ;ï;¼YlÖ¬™8ûï‹iÑ탇<‹;þV½þXʤIW·SéÕ«7ªU¯!L^ÊÌJÁ��5F‡Ž�¤w7®_Í#55Õ«WGÏ^}„Û#Ám۶⟿W¡d‰’0ð _7e¿\ºd±„á»ï}€cG�‚2¡+VL ¶5½¯0áHÁœLKÁ„T ~Å‹Ï�ézyºž®†7•E¿.À‘#G¤¬°CžêpÍHŸG|óUN]ÊúIÙ?­‹#=0é_ÅŠ•гWo�‹Ãï÷³¿ÚÓ¿cÇ�báüùŠúg>­þ&ZË-›7a×î]’ïŸ ½Çiù`+)+±y!øaÌ÷RxÅŠñXß~ªÞW˜¯ÿÀAƒsš¦ä*#G~�¬Ì,iMͤ½S’ã)S°²u)[¶œ´^¥j5ˆgC4­Õ¥€c{…°Y°`N?އj�VØ™×£€_ ü¥òæ[oËò_ÉvR]¶â�­ü0õÀï+ı–“ô¶óGzƼòÅnlÞ}Mvâ=Û—ÄoÔÖŠÊÚZ÷W"Ý0?DPržŒ·ñÃì¿’GÆžý`²ó8Å-çM8`5o®+ÏJ®zÁ–˜:¨»2Г6¼”Í5,,\2¶UÒRS‘š–‚ØØ‚ºnÕÈ”‘4:&V•ÓD¤Ú¼ûùûÛýBV© ÓõO"Áª$›‘‘nX66{c£¯{õª9�+Í߈ߙúPd~¨Ã�ù¡ŒÛeŒH‚í‡NΔbû¡]¶êðcû¡ŒW^°/}² k¶_Á½»™È—?÷c´Ž- cáΰj­|žVæ…I‚ÏÓòXñyZ\‡ìIúÒ~è¯ ñÆW{‚öÞ°èß½¬0°¼†Jäý�2^ya?dš¥~P6Sºv›J§N]РaC ð¬ÏÓ”��²R0]é>kæ IžìZ=ÔÚ¢î¯ àèQ P,"eåœ8q‚t-xùrðÄSOÙ,Ùú(wîœ9ˆ�¿!îµjõ�ìbR&G’§+çéêyG…®Ÿ4éÇœ @Ê.úôÀAA–æõ�ðÇRp.öRéѽj< –xãÊ•+˜2y¢TÏ”™•ìǺJ~ñ"éïÞ{… RVr3‰“'ŽcÞ¼_‰W^}Ý¢®y–ÝAƒ†HýЕõ}ë‹*Ur3àþóÏ*lÛºUªK>z ²,W®¼¤æe×Î�øë¯?P±Re<þx?é§”ädLøq¼”`£GÏÞ¨QÃq/éɸ±¹Víe”u¤æú÷è£�bÁüH¼i_ÿhœ¼òã„ñŠúgš¯þ¦””d)sîÁƒr`¤ào 7ÊvKYo�^sþ›‚εÚóàwgñâ%¤@áèhõ· ¦§§ã»Q#¥õèÓ·¯E&fkÅ_¿n-6nÜ€ðˆ<ÿü‹ ²ŸÅýÏ?W`÷®]Ro¿óUñÈ$ÌöC 6#øA¶†ßç‰á-'åMçJFðÂÿvâÌ©²~驊xáIÛ´££\SÏþJ©uæ‡BÎÿÝ›øa ö_É#ãÈeò'[×d²ó9Ç=x'°ê�ëÆ£vßL9Žÿ›˜›¡á‰neð¡ÁVoÞLÄÝ;w¤Ì ®ÊJJÁ±iT°*mr“’oJÁªFg7UZVgf$Õ»yW{mÈ­[ˆˆPͼFæ¿^tØ6]—d]—tƒ~s•.*��ù¡„�ãß™êðc~(ãÅöC#’`û!†“3¥Ø~èC—í‡:üØ~(ã•WìÇ‹ŸîÆš-ç�»ÈçŸ{K;åu€ÏÓÊÜ0íø|Kÿjñ·>�=†*UªÉÊ™‚YI�N�>‰%‹#0 o¼5\ñ½Å¡ƒ±téâœvi½hÝÌ‹’¬\ù'vîØ�ÐÐP4hÐ6¬·«æí*éŸIÖhÓùóç°pá|¤¥¦I] xú”.]ZúÿûöíÅòe¿¾þçΞÅÌ™?K}PPp©R¥5¿¯ €Ûß–.±X£ªU«£s—.Ò¸Õ”ÓgNaîìÙRz.Õ¬ù"#"¥±å÷ó“2 ^Û·oÇ…ÿÎKÔO>Ù?/{}-_þ;öíÍþ æ½÷?Ô”ì…í‡ØJÍG½šÛ±Ñi“âý•2nZù±~ÇU ÿf/RÒloX È�¯ßª…N–P€�z÷WކÂü0p¡46å‹çs�PÉVóf~�?yí¶Ë6ób²‘Âmå%8`5/­&ÏE#¦Ç?:/`•œ?ô†®rUѺy·7>Ú �“1 0Pè«C#çI}ÓðQQ꿘UGzZšätÐúÅ+9\é?‘ÀOúê&++Ó°b{s£I`P�И”ðqÅïÌ}(3?ÔáÇüPÆ‹í‡2F$ÁöC 'gJ±ýЇ.Ûuø±ýPÆ+/Ù�?Ù†5›Ï"Ÿ¿å-ì`”×>O+óƒÏÓòñyZYw”$|y?”˜”‰—>ß…=‡²¯ —+UÊEbâg Q¤`°ìï¼RÒ0Ëßy?¤ŒW^ÚÅʰJ™ͯ·>OSæÏ™3¦KYMkÕ©ƒGº=*�ýíÈo�‘‘� *Jo¦Böcã†õR� AæËŸ_ò[˶Zûc/]º„Ÿ¦N–šzåµ7‘ûqýÍ<{i½ú Ð¥ËÞ=Øo!C_K”,©¬0%Ξ;‹Y3²ï÷èZz¥bžé´C‡N¨^£zÎûŠýûöaٲ߄2ÊÊõC�›À)—‘öÔÉøå—¹Õºw<`ñ·„„Œ÷CÎßÂÃÂñÊk¯Ûø·�;‚…  TéÒè×ïIiÝOŸ9�¥K£LÙrèß_>Xؼ3ÊKYaMEC%=X·v 6mÚ¨¨Öx)éÉ‹ú›(S,ß–æ™Fíí¯((Ü”µØÄâÇ�}{±rÕJÃ×ÿâ… ˜6mªAß¾�Kà"ïPätlË–ÍX³ú(XeË”ÁîÝ»%±Ð°PtêØÕ²êš·i°ìˆ; Û«W”.SF‰bøý·%8p ;“í~l7‘ˆ½†Ø~(B, ˆòÃ^k|þÃÙ‘”7�?&þrcgǽ{¶3*V0ã?©‡ª\÷ÞžFaÔþJn�˜úõ[o ÞÄ{seÿ•<2"öãåÏwcõ–Ë|c—^"q}ŸA€V}f©y¢J8óm3³2¥4 Ã~§«…è«ñðpK‡›Ö(Ø– ±ÈõZûp´1rVFRZújÖÑU.F͇6xôÅzpHˆQMʶC)ú©­Î§N¦qæ‡>Ä�ù…/óCßÚQ›ù¡Eæ‡:üØ~(ãÅû+eŒH‚í‡NΔbû¡]²¯}ïZEÝ IDAT± ëv&Û4Ô©e,ÝH_y°6Ÿ§/*Ÿ§õ+=Ÿ§å1äç=pçÎ=|7ý(¦/:mWÑ¢#0ö£¨_3ÖB†Ï ê¸Éçe¼ø¼ �]ßN׸S²€×ßެÌÛþXºŽ|Þ/s¥L(0•®ª7ù5'Ošˆ«W¯ÈÒÑ5çëÖ­É锼ôÒ+ˆ0 @•³”ÁuÄ7_‚2£Ò•âÕ«[^w‹egúlÞ¼Z·ikwñ7mÜ€uëÖJ¿ûûH‰ ¨*\C† Õ”aQYÓóÀC¹ì Öm\½r3gN—‚ *$e€½s÷NÎû ÓuëÁÁÁxkø;"C°�¡l¯”õ•')Õ¼X¬R¯½öülúù~Ô·HM˾®¹a£FR¦]ëb X-V¼8 (½¯Ø³g7þX±Õ«WGÏ^}ŽŸ‚£§Lžh!Ó£goÔ° xt¤¤W´öDi*rú'7%ýSsž^»f56oÞÂbðàg…ÖmÜØ1 @W À|üñ'¤÷—._’²½þIIIøaÌ÷Ò¸}¤;¨][hŒrB«Vþ…;¶Kw)ó.q`Åòåˆ�¿!‰W®R�:w± @—kkß¾}X¾ì7駪U«áúõk9’Mò”¹¹VíÚhÚ´9Bßç,Y¼‡’šP›a•퇘j¨á‡X‹ö¥øü!��·œ?Ò3îàͯ÷bÝö+²©[#?~Ú‘aþzUEU}>¨‚ |þPÆ‹í‡2F$á*ûñê{°jã9w‘/PÎàØŸ,¶N,å{pÀªï­9ÏØ#:�Ï'ÍùõÉGÊâƒç-�UZÀ#'9ªŒ 9÷ngÞÖ K_qÒWéæ…œ(ôŸ¿¿qwÂ…œ”JA•´yÏ̼플¤´9¡¯ïÉãìBó ¢5‹«èøRSSâ4g¨è8Då˜òH1?D5H�óC/¶Ê™·l?İr–Û¶„ï¯ìëŸ?l±Q»¿ú`ôq¬Útɦ!v0Ê럧³qáó´s,??ïùy/¢Yÿl¹ŒwFìCú­;²âùó/õ¯‚a}+"_¾ì}û›D�Í–áó´2V|ž¶�ÑÙÏ`Ö¬™’@ûöQ»N�,e#üó�å —í”óñ¾ý˜ȸ`Á|?vTºëÝwß·ÈXhÊpiê¹N�ºèÚ표�8²°H�‹Mš6E»v,¿k×.üõç éo=Ô-Z>(;¹íÛ·áïU+¥ßb Dÿ§úcÁÂù¸tñ¢b]e�r,a 0%©§>#]µn¯\¿~sæÌBrRüüÑ·ï(T¨ Åû Âê»ï¾•²•>÷ü‹R€°h9zô~]¸@§,¸tl^Nž a�–š†¤ä$ø£HÑbª3¤.úu!މ“Ú}û�÷„ß±ýS µükU^ŠÏò¸x‹?öâÕt<ûÁvœù/ûëòD·ÒxoXMøùÙN¨Ñµþ¦°0Ë›|ÔôeO–ùaŠúÚð~˜fÉþ+}ëm¯ö+ŸmÇß›/!_~˳؟켹UïG€V½ y!ðí´øl¼±«äh#'OHh¨A£Tn&99IrâDGw…9ðiT"2¦Ñ“ó€ä­c­gçÌ/]¹y'= âìì´´ö¡¡aЏ*k‘k$˜ò83?œ£Ìe\Ù~(cDl?Äpr¦Û¶„ï¯äõ€ùa?ÞøjþÚ`°Ú¹eÌç «6@óyÚ¾å9+‹ÈðyÚ6 ›‘û >/(£é ç…Sç’ñÂ'»pþRšÝ 5ª]_¿QÑþN¹‡Ï ʺäl Þ·2r­¦N™„Ë—/KÚwyøa©ém[·ââÅ Òÿ— V¥¿›g0}ó­·-2š2.šÆ9äÙa(Z´¨ôO¥óÂÒ¥‹¥«ÔË•¯€'Ÿ|Êbª¦ëíé�íÚµG“¦Íl 0eô¤( ÁÏ"66t­ý”I¥däû¦1QFS£ËéÓ§0wÎl©Yê»xñâ²]?v ¿ý¶tí;ù÷íÞÊ——}_A�Ãtͺ\–T{ã?wîæÏ›+µ_¾\<ñ”%–ToïÞÝR&LSyvès(R¤ˆl“ÇŽÅÂùóžšV)¨–‚k©˜²¸R`3eo¥Œ˜rû+s�©Q³&ÊΆ٦m{4nÜØÂ¯.§æï+éŸÒzËéŸûa \±b%<Þï ‡]ÇÇÇãÇ ã$l5nŒ:åÈ;cýiï°~Ý:ìÛ·Wz7òüó/"2JìÂÌÛ™Áë¦,¾ìLAÏæ…2ÿ±bYN r‰%¥çL‘"ÙÏëBAE£¿ÿVʲ\¬X1)È™’µèµ æÏÇñãÙïßxc8BÃ”ß zÃþŠßW(1ZÛï|þPÆM ?Ö︊·GìErj–MþùðÙkµðhÛ’;çó¹}x”öWÊ«*&ÁüPÆI ?”ZÑ}S?¾h?†³«6_³�šýÉJÚÇ¿û*°ê«+Ïó¶AÀèl4Jÿ9;£¦¹ÑOLˆ—®SŠŠŠV 05RD7jú¤M¯é«X5õ”dÉy–‘‘Ž À §¼˜°îŸ¾ò%g Rp®Ò¸ýN›Ã¤¤›RZ#³àê“R]æ‡BŽg~ˆãÇüPÆŠžµl?”qbû¡Œ‘+$Ø~èC™í‡8~l?”±Êëöãͯ÷àÏõ°ª¬ Ù|žEÊVŽÏÓö±ãó´<6¼rÌ·”´,¼=bŸÝë?©vtd F¿_¼jTáó‚QHêk‡ù¡?gžþý÷ -úUº~ܺԮ]�»t•õk&ݼ‰™3–üžŸdáó6ØQ{E‹Ã�g‡JM‹Ø�M7bݺ5ˆŠŠÂ˯¼f1¤];w⯿þ�þÖªu´lÑÒâ÷ÓgNá—9sr")HÐ<«è¶íÛðÏý̫ŋ—�Æ­t˘ڕ;~üÌŸ'U3Ô5µC�³«ÿùG�fg{¤Ìª?üªT©b÷}Lþ4m*ЬYs´z¨µ]Ÿ6nnݺ[·l’‚þ""#1pà OS1�Nœ<™“‰–2€R&PG…²Ÿˆ-`÷vSÀjLt ^|ù•œ5§Ì¡)))hب‘”É×£¦�À§fVŸz´,Þ®†f|äR©knL bZj*2³2¥`UWš'mŽ´d¥zrÎ:g}¡E�„„ˆŒˆrIÖ[š£’Ö뛘˜ 9mµ¬�+uż/æ‡2òÌeŒD$˜Ê(±ýPƈí‡2F®’`û¡Œ4ÛeŒD$Ø~(£”×í}¿b]öu®æ¥ËƒE0ïûFÊù˜Ÿ§µ-8Ÿ§íãÆçiûØð~H™o¤?SœÆ3�áÞ=yyº)øÙÇ*âåþ•u_Êçå5q•óCiwž®\¹‚Õ«ÿÆÕkׂ’¥J¡~½([®œòÀe$ÌÛuèS@!‰*ùcãâcñ¢_¥Ø÷ÞÿÐB~ÿ¾}X¶ì7©GÊ®JYVM…²>ŽŸ0)ÉÉÒŸ:wî‚ú ,³=Æ?M� š/•Ž;KA”F–£G�à×… ¤&ëÖ­‡šµjáVzpìØQœ?wN ؤƒÞ½û P¡ÂŠIâão`ÆÏÓAÁ�11±¨Y³&Š/ŽÐÐP)klbB"þ;G�•®P§B™eâIÄÆÄZLÑt^8sú –/ÿ]úíá®Ý¤ñê)¦€Uë`ãÇcÉâ_¥¦kÔx5¨)AÓ:ìÚµS Ä¥BA‰ ”2ßNüq<®_¿ŽF�£CÇNÒ{“î˜ëA£ÆMкu ÿ»œþ‰ÎË\ÿ Œè¨Íï+þûï·� ŸÏë�3“VY÷ÌöCù¹æNûñÖ×{ñÇzö'+¯K0ÙpÀ*k#p�烈Ä'ãŽäà¡7`Õ•ÀR€gzz"#Å®S1jl´y§¾éÚ#µ…¾Ä"焵ó�þNÅèL¡4Îøøëˆ�DhX˜Úá:”§ë�¶mÛ"}ÁM΋N�:Û8@ íð~ct@Hº™ˆÐ°p]_þ:clžÔ¦«øa­:tD±â%|žîÒ…;v`úµèÑ«7*T¨à®ax|¿®â‡5¾f?Üe'ì) Û1jÍQ=ð5~ˆ­†ñR”-gýúµèÓ§/J—)“ÓóC k£ù!Ö+¤,\uþ +ä–¯e£èÚðyZ©\9Wê³úÑYÖpæyZïØ´Öçç½rÞþ¼ßs8¯¹×âoÙ�píª1øá£ú(ëø¶½˜bº”¥¼�ækâ�þXÿÚ5«±yó&øûûá•WÞº~Û4ïk×®aÒÄ Ò?ßþŽ…ÿîÔ©“øeîé·¶mÛ£i³f9pÅ9ŒÅ¿fE6oÑR b”+DøóôiÒOüöÒ˯Jƒ¸Ã‡±ø~p¦½†ÉgߢEK4hØXÂH´¤¦¤‚²ORP¬£B~õêÕC›Öí,®n§:æü ³ðÊ•"0 ¯¾þ†PàŸ£~Ï�;‡™3¦£J•jèóØc¢Û¶nÁš5«¥ÀS¹ÊÐiº*þ÷e¿áÀ¾}RmÇN�-ÞW˜ëAëÖmѼE ‹&�Ò¿_x 1v2ŽŠ®a²ì÷ßr2­Ú«GA¾4ÏÊ•«ØmZÏú;Ú_ý½j%¶oß&4%ÊüÚ»O.\D’OOOǨoGHÁ£ï¼û¾â»# Ö¦ ÀëÖ®É BøÌ`/^Ü¢ÿ¬ÌLü³úoìݳG:kÚ+… ưaÏ+Ž}Íš°eófIîµ7ÞDxX¸l¶ŠPJÏg½ÏSîÝ9|þÃU-?Vo½ŒwFìCZ†-‡éµ¡}éµ*ÈŸßqÿ|>[gI1?Ä�U˱V•¥˜Ê™$ØŸ,ŽK2„¬²0÷°~ÁÖÿѲxOG†UWKÅ´´TDDDZ\‰äìþis’‘‘.eöT[hCE�ªÖ_9ë -ë�×ax°*Í}Ô¨‘ +sL…¾Öí߀ZXTÉ›Rþ‡††I_ûÊe 8þ¼ô%ñ…‹qãÆu$'%å|YO�ÑWÁôEyÁ‚…¤L•+U–nóRq%?¬õ d©Ò8ðÕpæ5~¨À€ Ä�iÓ¦àò¥Ëhа!:uêb@«y¯ WòÃ=_´î°ö4ÖÜ~\½z §OŸôi;a'gðCD|‘îzºÎøyh¯D™Ž(ã‘ý•»ÆëIý:ƒ"ós5?Þ¹¿¯¹`34ΰ*¿Z|žÑâ\W볺ÑYJ;û<­glZëòó^ ¹¼ò¼¿™’‰wFìņ�×ìN<2<£Þ«‹æõ ‰�s_Šù¡ ®<%œWøaÚÓÿ*e$U»€®àǹ³g±ð×hÚ¤š5o®jˆÐFYPƒ‚ƒÑ¿ÿÓu)+Óĉ‚¾ýž@dDDÎy!îð!üõ矨ߠZ·ië°O Ò¤`Í¢E‹aȳCU�OI8%5,_ŽK—.JIh>”JÉŠ-†Š•*¡zõ꺒\¾|ìÇÙ³g‘”|·2nI¾ä £|…òRVW¹€êÕ«�6mÛ9¥{�ºšæÎ#쇑vÂFFÙWÛ {s2ñ#_¾üXõ÷Jœ<‘}=šš’—ì„«ù¡¤zxé,ûAÏÑ}û÷áÌ©S¸~ãZŽ�ˆ‰�‘2Ò��¨^­†WÙ‰ÿgï+À«¸¶¶_ â$x‚'w+Å5ÜÝÊmo…[oï½ß÷÷Ö)ÅÝݽ¸´8'¸»ÇHÊÿ¬ædΜ™33ç̱dïçáisfëZû�µöÞï¬-è}ü¸ß���`²jþ•œ•וvÂÙøP“™+ðñõèX³]†°Ú¸–üj~í«Zÿ³Âs¾žÖ®eWÌgí½3ÏéŒõ´­}³µœ;¾ïm‹#ËÙ3Oíé—=íªùC ×]ÇÏ3Îáeš|Ô=ê÷€èpŒRÞ^ÙT‡Áñ¡*¢L›Ážyj�PìiW öôK®,LJÑõœúì™§öŒÒžv9>ì‘|zYî_i“¡=óT[ ò¹ìi—ãÃÉs|葞žyzó^ >øß\¾‘$ÛDµ ÁûÏȬ~ƒ‚žv¥�q|èѰ|^n?´ÉОyª­n?ì‘“¸,ßO6J’¼ž¬"NXÍ*šæãT•Àos/ã_ã<‡°ÊÂã'&0²ªÑ_À[9EII‰ Ê£JN >ŠûöìYrçö±JV¥kX~ý ^¦½DíÚuвUkUÝ èË×iÓ¦ FõšhبÛ(y‘šŠ¿ÞüeS$XÍ ;1#ɟȪoðAAÁ²_ÉŸ;‹•+Ó¯¦§À  ´nÕþ /±RŸ?G\|îÞ¹ƒ+W¯°¿)¡¸V­ÚhÒ´9¼½½œ8:ãšÊ¬ø0NBÀј#ؾ}»^ÇZ C·î=@Wf¹{ãcÑÂ…é„ÕÈHtêäž„U!ÒE8Șh Ztäéø0ÒN(É+³ÛŠ>¼víš,m'¬é>3úWZÞ Ò<ÇŽ]Ù—™ì„xŒcÇŽaÑçÉNtè­ê_Ù"C{˸ÊNp|¤Kà›_Obõ¶ÛâhË «²S„¯§µ!ÞÑëim½Ð–+³ûCJëimÒÉܹ<}½`M;t¨ýÑŽâÚídÅleJ`Ì×ÕQ²¨ò�B™ÖF—™ña”V9>Œ’¤çÕÃñ¡®3ŽueÖêšåøP—QfÍ¡‹7ÜÀÏ3Ï!5õµ¬8†v/…�ú—CŽÚ>@säy·‘úâø0RšžU—|92¾e›4ù~²mr㥲®8a5ëêž�\"é[ÿèp|9ÂqQ2íQ]•’ÿ€@ÍW¸hi�œº‚E)1ç„H²AyTI²”—’P‘¨ß9sæ´Ú• γˆƒ”¢:D£J•*ZºÎòÄž>ƒÕkV"¢bEDGw]ÛCí9“Ы¹³6d¢¼zý ÁÁyeù4î)vnߎìÙ³ûgccYktµQ‹-e[¦¨¬—.žÇŸþ�G�Ò¯É+^¢zô襪3†âÐ"™F îôéSX»f5«Ž®…ªQ»6Š„…!{Žxòø1ŽÆÄàÁƒû¦æÜ™ô)tRŠ�É“&0ÂjåÊUСc´Q¢3´žÕ«W"öÌ+Vý 4´n¥Ê2>Œ²�;w•mdvûAWfe;‘™ñaÔ‹äÌ™3X³z¥…� è¼dN�<éqvB*›±¿ýÊìD¥J•ѰaC¨ùWFÉVO=®°øvÌI¬ÚjIXm÷n!,Í#¬Jç _Oî°žÖ󎱖7+øCj{FÉÒÓêÉ ë5™§¾ø ÿ�|+·ÜRÌš3gv|2¨<úw §m³Äñ¡&áÌû<+àÃ^íq|Ø+AÏ-Ïñ¡®;ŽueÖêšåøP—QfÍ¡Oã_âË_N`ïÑôóKi ðÆOŸWE£šØ#¾>wï£õ¼Û½GáøÞiŇޞp|蕘öü|?Y»¬xN.’'¬òyÀ%ðV¿Í»‚�=k’‡;VéŠb_?äÊ¥~��Q Ȫ�AVI­ríI#­ZëÓ¦MYŽÒÈ‘ï#o¾|š‡@<"âÕ¨QÍš·ô8¢¥µ�RDT" “,IZ׈ˆ:aÜo rR™2eÑ£g/«ò¤ú<€];w0‚qñáèÛ·Ÿj4]ÍJrBÆÌŒ£Ä7aü8ÄÇÇ!þüèß ||}ͪ&ÝŸ8~;vlCjjªéºd£Ú7º9|D¤jÕª£]û(£›4¤¾yóæàæ�š°iHƒ2>Œ²mÚ¶—«@V5Jæ®®GÍ~dE;¡¤“Ì€£æÛÄ ã÷ÔÂNøð4;!'ÁNDDTDãÆ�uùWFÉY­WØ Ž� üó·S²d&NX•Ÿ%|=mÑÎZO«½W´>Ïjþ�V¹d…|YÉÚqà>¾}IɯU[#2¿|Y óæ6åáøÈ H�cV‡­Zæø°Urž_ŽãC]‡ê2ʬ98>Ô5Ëñ¡.£ÌšC >vzÀnÁ‰O”¿-°R¹<÷Ïf>»5yñõ¹kg“Úy…k{ç^­kÁ‡Ñ=æø°O¢|?Ù>ùñÒYOœ°šõtÎG¬ �±ó®àŸvV‰èGÉÑÑ<â‘Ó;§ÁÌ‘Š%ç$1!žEVµ�Õˆ>̘>÷ïßgdÜO?ûB3Q’ˆcÆü‚”äÔ­[Í"‰ÑG=uÄÇǃ¢FTˆ@@` jÑç))8uú#úû§_?GÎ{JJ2^¿z?ÿÍdU¡±õë×âä‰È“'>øûGª}  /\ÀòåKi•dI2Õ’“’�ú<9½sÁÏÏÞ9½Y1OÂÇóÔT$%$ÂÇ'·&�9Zt –'>.&ŒcÙ¢;uFdd%Å"/^¼ÀÇP¨P(¼½½Ôª†’þU ªd +à㈰ý¹}|`*¡„�ˆd-²°½ý¢ò$£ÄÄDí:00Pó;òáǘ>m ÃXÅÈJèØ1šÛ� 1ÂN4hÐMš6³hÑ›£FØ %Ñiµî`'”ÆàŽöC¯�P›»Ú�ägȨ́’Ú 9|x‚�P’¿`'ªV­†–­Zëö¯4¾² ±d«ÉfK“;âC«\Ôò¹>þ=î4–oºiÑÕöM aÑ/<ªT0|=­<«Ýa>«aNüÜþ�žþéÍ«ÕÒ[¯3óó÷½ã¤ýàI*¾úù$ž|¬ØH€Ÿ¾ù[$:4 3ÝÄà¸9·fŽíòÎìû±Ú%¡œ“Û#¤hlÜ~+O{jãø°GzŽ)Ëñá¹ÚR+LJ-RslwÁGòó×øÏÄÓX»ãŽì€³g†u/�÷û”…——äZñõ¹cçŽZí|ý¡&¡Œç|ý¡.+w´ÿ{ +6[ÞæÂ÷“ÕõÉsdM pÂjÖÔ;µŒ¤l¢ÃñňM²"—’£ÉœII‰ŒÐäç—NdtFœwŠêI„,G&Zýôãw hot}¿~47wãæ ÌŸ;‡åoÖ¬êÕ¯o*K„°)“'¢HÑ¢ˆŠê¨¹N#2<Ñ-› IDATtÛ·nA@@úõˆ��Åj“““±`þ\{ö Æ�e�Ô«Z•`Mÿ¡EÂP¾|ETï;äüùs8|ønߺe"=SŸü|ý^²$4h?Y|D¤w¿‹wÞi¬u(šò=þGŽÆ©S'A`!Ñž"õ½ûnSøùû™ÕE¤®»wïàÁýû¸{ï.®\¾ÌHLJ‰ðÚµ[7”+WASŸÔ2Ùƒµº•žkÁ‡Þºi'&Oš€¢ÅŠyœ�P’¡ûáj;¡ôž�úWöÚ %YiÁ‡­vB >Èt•Ÿ"×?"QKíÙ½ïpqÝ®²äO[ “ð1qÂ8f4l„&Mšê}YÍï,;ѹKT¨PÑоK+Ó‚£;àûaKÿgÜi,ã„UÍ¢ãëiyQ¹Ë|ÖªH{ß÷ZÛqV>=þ�³ú¤·¾ß¤Wb¶å_´þ~™u©©éû{r©Y½øï?ª!Ðϱ{c¶�@)Ží2ËÊþ�V)qû¡URÎËÇí‡ód­ÖLJš„œÿœãÃù2Wj‘ãÃ}t!ôÄ]ðqü\>ûá8î>|.+¤Ð>óMuT*›G³ùú\³¨’‘¯?´‹•¯?Ôeå®öƒï'«ëŽçàK€Vù|àx+�qó¯àÛßΚ䡕°ê,ç=9ù#Ç9MgÔ^B|‹¬jIAk‡Ÿ<~ŒÉ“'²ìz¯ñÞºe3#¶QjÕª jÕ®mj–H”cÇŽa„ÍQÿøL‘xIÄB"iЉ¨hk´\"ÔeŸhðPYÒ)EV�GdÕ‡á啃‡ GÞ¼yI/ùY’ÍdUÂÕkW°hÁ&��>úDSÔPÊ+¾&ºm»ö¨^½†¬*/^¼€Ë—™ å2¡i“fˆ¬$ÑSˆèFÄ�OF}ŠÜ¹3®ÜS›CR|Qäùó‡¨Fé½{÷.Ö¬^‰§OŸ*6CÑb‰PL©]»(T«^�áQ >œ=ÿ”!ÌË´´WŒNs²D‰pôéÛOUFÖä¯Wÿ+ªb‹HÚk×®Á¹sïd¹>øúú¢w¯ÞÉ—ßWaµyó–¨[Ïz„`"ŽÞp¡…ÃT#Ééê÷ �œ’>äRPP Ì"® iÖ¬¸{GþK`¥z”¢€ªáAú<3ÙGÙ‰„øxŒ?ÖivB¬#±�È—/?Ñn' ( ;èý¤Ç~¸£��ó¯ì±RA v"gΜLVÖü+[í„V¥öÃ]ì„Ð_©�èÕ»�]eéµJ~‚Ø¿Òl'ü|1ò½÷Ín&ð1qüXûñÎ\ŒWœù‚sá»TAÃù]2e8>2ÄÎ÷c]2e5j^Ú;"£úÁí‡vMpû¡.+£æ¥zKÖsÕŽíšàøP—•QóR½%Ž­2rÿ*íÕü6ç<欺Š7oä{Þ©E|=2~>9´Móyžæ œ‘ãÃÁ¶¡zwÀ‡ ÝÖT„ï_i“E&9œòýdÛdÉKe] pÂjÖÕ=¹Dã\Á7cD„ÕNáøb¸õ«ÎrNèK"[úûg\ƒíh Î EVõöN¿ÖÝÑéæ�˜7/=JjÓ¦ÍQ¿AMM’C@ä4¡°}#¼ ‰®)÷Û¯ìÏž={¡t™²fõÒW8‡Ä‘˜Ãx–”Äžùûù£ió¨\¹²¦>,Z´wïÜF×n=P¢D ³2{÷ü‰Ý»w±ßˆ¬×¹sW³çDšY0<¸Ï~¢^Ò¸âí"«R}TïôiSYÝC‡ G¡B…5�‰2 DàŠ‘‘èÔ©‹E¹›7obÑ¢ùx•öŠLÛ´m�Ò¥K3‚sRRk›"IÆÆž1E“$21E�¥9-N4ÞŸú�E•íÖ½‹È*NW®\Æ®�;ðøÉcDTŒD‡·ÑrÅø âáÖ­›qúÔ)F@*P  zöîcv…¼¸N"!QT[ŠœG$ãªÕª£F�š A|B2$ÈñaïlÊ|å9>8>2߬6nDÆÍ¦ÌWLJ{áãê­gøä»c¸t=ýœVšè¦ƒï?«Š&u Ꚍ|}®K\¦Ìî…Û´¨^ŠãC]Fr9”ðÁ÷“m“'/•u%À «YW÷|ä LXx_ÿkúu`ç’ø|˜òUÌdÀiÉËqW�Q©©Ïáããk™ÌV%S»ñqOYdUg‘U©¯D \ºd1ë6‘•ÈÒq]¼pË–-1ýÜ¡c4*WÎ °!tô/?±çí$dVz¶dñB3"™¸~i´V9™Þ¹}³gÏd�Ú´mÇ�âDódñÂ…,Ò)%q$/"Ý-\8ßDÎ__N:ðõó—�ȪG·<ÀôiSXŠú()µÔsä6oþ�•¡²âDIg͜Έƒ¾~¾èÝ» *IJHñArÞ¾m èÚiJMš4Cƒ† -º@„e"¤I#Kž��ÅêÕ+æ„Ô>ªÊ”)cÂõƒˆ¿÷ïß3«—ÊDT–&ŠÔ7uÚ$¤$§0²m×®ÝQâ-yHÈK‡œ3gL7‘‰é÷¨Q$,ÌJó@mþ-]¼ˆ‘—ä’–ù§E�Ò<<ÄìÙ39˜RÁ‚Ñ´Ys”*UÚ¢:’%iÄakú—VB2زeΜ>mUÿôð÷�pìØQ–¯Q£w@×9Ëéî�?v!%%­Zµ–�,V£:D£ŠˆÐJsèÖÍ›8z4gÏÆšæ”¿¿?Ú·�² ´ m“ŽæÎžÅò,X]»u—½fšÆyäða†‰Q£>“Uáã�?vcÿ¾½ìy¿Q¼Xq[T©X&³ÚWÙ k8%~í:u¬êOÍN‰råòåºí„R£zí‡+ì„Ü{Âh;!õœe'è#€J•,?x!’ÿ¼¹³ÙÐÅþ‚§Û ¥yøøñcæ½�ñôèŸ>*¡H¸BÒj':À>>iѼ¥™�ð1yÒöq�;Ú +}ìDdv±�àëCM¥jeßMŽÅ‚u×-òuhZ ~6÷÷U+Ëøz:CÉ®ZO»jš)­ôöGú¾×[^š_¯?do{F–çï{#¥éÚº8>Œ—?LJñ2uU�ÆKžãÃx™ºªFŽã%Ïña¼L]U#LJñ’çø0^¦®ª‘ãÃxÉs|/SWÕè |ðýdWi—·ë©à„UOÕï·á�° ˆÇ#ä#¬:Ã9!òÊ›¿þBnÃÇj­Báp�"GŠÉÎè‘ÇV­\ÁšŠîÔ…E.Ô’æÏŸ‹×3“£¢:¢JÕª¦¢D0ûþ»ÿ°ˆ›b�uþ¼¹¸}û#ã5hØÕª×@¶7oðûï�–~:t ”¿v™¡È‰»ví`íѵ¹r¤?ºîwÊ”I,Ê(ÕÙ¯ÿFz[´`¾‰¬H$["×PŠ��ƒ¯¯Ÿ!:¸ÿ>fLO�°J׿‡‡—Ô"V–‡ˆwDÀ+Š!C†™Ê‘ìfÍœÁˆœ¹råBÿÙx(YÃE,Ý¿“ÁÈ¿}`AøÛ¶m+<€2eÊ¢Ç[’éÇ0sæ VwÛ6íX›‡B¾|ùðÞÈ÷Ùï¯^½ÆÂ…ó‘䨬Y \º| Ö¯eÏ)å§U«V€ˆ°^^9Чo-ZLV.Ç�ÃÆ ëMÏZ´hÉæ‰JóÀÚü#‚í­[7íšš•)ÉHÑeW¯\�¸ø8Ó“bÅŠ£a£F(Y²”U]ZÓ¿\hÞÓxð€!v"þñÞH ;A‘¥‰hì(;Ñ©sWTEôl#½:Èú#ö<ÙN(é’HGsfÏÙp©Ÿ`í]'µ¾¾¾fï[­vB >ÜÕN}ßµk§™�È›7ŸÃ?–ËÌöÃûÝ”X,XË «ZeÇ×Óé’råzZ«®ŒÌgÔÞˆàÕ7[ü!£Ú¶·£dj­ü}o¯–´•7J—ò6J¦Úæ°#s¥KŽŽGÎSWÕÍña¼ä�’)·ÆëFo�Fé’Ûn?ôÎ=OÈÏña¼–Œ’)·ÆëFo�FéRÍ~ðýd½šáù³º8a5«Ï>~“&.ºŠ¯FgDXÐ)_ ·$¬RˆoJŽŒ¬šúü9²çÈaYQ�Š…Ã5ÿ€@E2–žúôæ½pá<–/[ÊŠuíÖ åˈÅõŠ£• ¿ËE9¢-V­Z ™“’pÝ=‘'»të†re3® §ëfgÍšº2œˆ-�:wQΊËqþÜYöüï~Œ   Ù¼'Ždž ëØ³À  1²"¥â%ÂÑ»wdË– ‰ ñº#«WSèĽ{÷0sÆ4ö'‘@‰ ª5 Ò’¥J³þ ‰7Û¶naŠI7jø Rδ©SðèÑCv ú;ï46ëJLL 6oÚˆ<ÁÁøàƒÙ³9³f2Ro»vQ¨V½:0qÒx¼~õƒ AX‘"¦¨œD:%ò,ɑҔÉAÞš·l…ºuêšÚ“³Ô¢#ÆÇÅc„±¦²£;£R¥J"\½j%bcÏÈιùGò#9Ú;ÿ´êR.ß«´4ì?°÷ïgäN!…—,…-Z Ož`Ù÷�’þåÚ ˆ†Á–’šþ—/[† Î1ý¡9$$ĬJ­×zÒ‚áçŸ~`ei,4gž{í‘%ýû˜Aj'Èf 8Ø¡v‚"0—/Ÿ¥_ð¯vïÞ�s þ‚'Ú Šp-ý„ôKã¥�Ovî´þ1�Ü\Û‰ú ¢iÓffÙÔì„Òü’âÃÂN$&àÉcK;A~cáÂ…U_ÏFÙ qCb;ñ·÷?@``_¨jÂØ ?L=‹yk®YTÊ#¬ÊË™¯§3Ȫ®ZO‹õÚè}OÿìýÐUê©·¬œÃHi=mOô–U[Oë­O.f_/!##êàø0BŠæup|/SWÕÈña¼ä9>äeÑf£Åƒ¡ÝKaÔ Œ3ãµa_�öÉO®4LJñ2uU�ÆKžãÃx™ºªFŽã%Ïña¼L]U£3ñÁ÷“]¥eÞ®§J€V=Us¼ß†K@¦t8¾”DX%©¼½½ o_¨�Љ «DHqTÙÂÏ?ÀD.sT[Jõ^»v Ìg�…¨ˆÖú@¤ºjöî�;A\ÜS–½EËV¨#"'Òo³fÍ`ùJ—.ƒž½zãê•+X´h˯tíú…‹ç±|éÒtòÜû $ØœtÀ©çÐ�tG}T:`£Hš³fNgÝéÒ¥+*DTÔ¬ZŠÌJäÎÚµë e«Ö¬É}ÜØ1ì݈ˆtîÒ�ý®9oû¶­(V1ë E¿\³zÏ—_}ƒ çσ"¡RÌAƒ‡°µ„�E‹29™˜È´D&¤4xÈ0„††šê® ¦+áéÊ_!­[»§N�bQa‡nUg4®Ÿ~üÞT–¢~RôOiš1}šâ<�οë×®aÁ‚yvÏ?ÍŠTɘœœÌ®§�9ƒ×oIù4Ÿ½Ó˜E%'%ýË5Aø�F‰VÒ?ÍãŸþ¯Ò^1�Š ÒT7=׊")YYšJ”‘�Ê•¯oo/Íâô'&¼+^³fΜ>�&Mš¡AƦlR|DHÊð�O?‡�Ñ´³‚ýp¦�PÂ)ÍÅ´´4f+µØ Ò±ÜûA”ך�Pš'zð!ž»‚ý ÷¼3ì„n¤ø°ÇNmrtµ�ûW­WÉ_È,v‚ÆKúœ6u²…Ÿ õ¥k«�Pª_ZìDöìÙ¬úWâöŒ°Òþ‹íÄG}‚€À@­"Ô�/+ØÝBðã´³˜»Ú’°Ú±YaÌÿ©¦-Ufê2|=ýt½+×ÓΜ`bÈžv•ü![ê´×r5aUëzÚÙeøûÞéi/Ëñ¡]VZsr|h•”ûçãø0^GÊ2­Ôþw¼~ýÆ,Ã�®%ñ�!˜¯Ûkäø°]vZ÷›Œo¦óЬxžçyZÛÛöcíi—¯?2¤Çí‡=3ɽÊrûa¼>8>Œ—©«jt6>~œzse ðýdWÍÞ®»K€VÝ]C¼N“€ô€­_Çøê½ b9'”ô õvžÚ 2ž3J( Ðâž>�?‘U Mé·�Ÿ¢™ÒµÛ”Z·n‹šµjY­Š¢Rô)’]u?Þ\–Ÿv�ßmbVvÅòe8þ‹zدß½-!1%ÃK¡wß¾²í�\&Ošˆ§OŸ0â^ãÆïšå·É‘~ÄWÔ+uœ®Ÿ:u²‰Hfeâ$ÑÒV™R¹;·o3b/¥NÑ]P±R¤¦ê(âÞôiSX^qdVŠvJQO)�xïoÈŸ??#§hÅÇåK±dÉbâÃ�>1ë‹8zâàÁCAQ éÊúþý¢PáÂ&|lß¾`esxy1y†‡—dó@œbŽÁæÍ¿£t™²èÙ³{Dsþ×Ñ?³èˆr×6‹ËS^jòÄ ¦ŸÅeÅy­Íñü£È~S¦Lb×ÒÛ3ÿ4)Qg&ŠDJñˆ8,$" \Hrú—kFióGIÿbüKIç4¿ôàCLj¤¾…††¡s—®È“'�N‰ÏŸ?gó…ÞÝzô0‹Ä,­ìÈáÃØ²eü0räû¦HÕrøØ´i#ޯİ*>ÿâ+»mKV±βJ8ed¼/àãëËt§f'„9"}?XÛU²b2¾xîéŇœa'”À'‡[íD±âÅM͘ى^xýÚ1v‚¤÷ù„ñ‘¸ÉN�M’úW™ÅNÐUõ§OŸ²°>žÄ=µðô¼|ÏÆžÁªU+-ükvÂÚü’³îf'äúo´�°&£¬¼þ°67š~sV]µÈÂ7奯×Ó®_Oëy×Ú“WêÙZ—‘‡ÅFøC¶ŽÃˆrzÖÓ¶¶—UÖ ¶ÊǨrFI2£Žãeêª9>Œ—<LJu™Ví° /Óþ2Ë4¨KI|6Ôý«Z%àNçyZûlo>Ž{%hYžÛãeêª9>Œ—<LJñ2uU�®ÀßOv•¶y»ž*NXõTÍñ~.é[ߎ%ðõ[Â*9'D:È•+—áí Ò×�ŽŒÜ*×qv]^bèZp??ÇaƒT©˜úñã�ß3Y׫_ÍšµP,qãÆu�•Æ@R«×¨�ï¿ûË_µZ5´oßÁ¬,‘ȈLæçï�Ê•*ãÀ�ý,jÖ°á#P €ò•àûöîÅ®];,®÷~ž’ÂäE‘)Çüú k«Té2èÕ«·ÕQÒõÄ3¦Oa×ÔS"BKçÎ]�ô,yò„ØMZ“küÖ­[˜;g{$½¦ØZg—-]Š‹ÏÃÏÏ�K…¯„…(¨ôû'£>edU=ø¸té"–.YÌðôÙç_šuAxF?R{äLRtÕ¾ýú›á#66«W­0+Û­{w”+g¾á(ä“Y…ˆ³9½sbÔ§Ÿ)^¯+àã\l,v¼½Ö˜ìÛ·?J„‡›µ­6„ùçïï�5jâ�?vÛ5ÿ…Q’wjêsanùò¥HINaMõ0ÅŠcÿ/Õ¿\_|È=SÒÿÍ70oÞVDL ¦ºô⃈Tk׬6k¾|ù´iÛ–Íg=éêµ+X´ =3½—"#+!0 �ÍÇì9r°wÀ­[7qôèQõ—Ô}úô3ÉK 6¬c׿Súêëo튪�•ì‡3ì„N|�½'%;!䑾¢;F[µ·rvBJÆê¶®°J˜S‡-v‚¢p‹“3ì„ÐEU¦èÊBêݧBB‚Íü«Ìb'„1Ò{Ol'úö€üùó1R‹�Pš4§éÃ9?AÉNX«KÉ~¸“�PêÿºµkpêÔICì„RYÉ~è±ýBÞ_fžÃ¬–„Õèæ…1ïGaU*S¾žvýzÚ–y®·Œ’?¤·kë[êÒ»^ÐÛ†#óë]OÛÒþ¾·EjúËp|è—™Z Ž5 yÎsŽãuÅñ¡.Óê�6#5õµYÆ�ÂñÅðõÂNÌÁña¼°9>Œ—©«jäø0^òÆËÔU5r|/yŽãeêª]…¾Ÿì*�óv=Uœ°ê©šãý6\ã\Á7cΚêV½¹ÿêÕ+EÒœá}[¡õëeÚKæq9YU'EX¥ZrW‚ y(òç¼¹³YTÓÊU«¢CTGöè—ŸdQ3K•*Íoâ´çÏ?I�f‘•HOrÄV©¼ïÝ»‡™3¦±Ÿ?üx >\G¥«^£&Ú¶mgUebò��±cÇhvE¹£¢÷Þ¸yóç¦{öê�ҥ˨N+q¤Ó–-[£v�:¦2'OœÀúõkYTØ¡ÃF0²ª²µ…R."í•Ë—°xñ"³þEEuD•ªUÍ~‹‹‹ÃÄ ãL¿ùûùãÃ�?±ˆN|áÂ9,_¶ E‹ÀƒXþsçÎbåŠå(^"ýúõ—•…;vìĵ«WLùäd¨6„ùG$ÜlvÎ?Uå)d €DªŠ¬TI6Ò(9ïÏŸ§°HË”ˆ.D-cE¬ÿ÷F¾oÑšÚá³’þïÞ¹ºR™é…ôC„zêSpp^]øØ¿vîØŽ¼ùò¡DñâŒLJÉ×Ï­[µEDÅŒèÙjò”Ѭå'2l—.Ý Dy¤w»>Ö­]�S§Ò#~óí¿�Ù–”퇣í„N¥øëJÎNˆŸ‹ßUªTET‡t›¥”äìÄ ACV¤ˆY[ñ!×®#í„Ü{‚ú` zíDttgön'GÛ q[5œ¢Â ©]»ö(ZØÌ¿Ê vB:wÄv¢bd$:u겨٠¥¹/Ø=vB©.5|¸‹�Pê?ácÃúu¦ˆçöØ kmPdUg&w](É`ô¬ó˜¹<Ãòujй?Ôp¦è<¢-¾žN�¾ž™“5HϸÕÖ zêR{ßë©Ëy­ùCFõ'+®Œ’�žz8>ôHK[^Žmrò„\Æk‰ãC›LkvÚŒ7'¬r|hÓ¥ž\z¤åÞy9>Œ×LJñ2uU�ÆKžãÃx™ºªFWâƒï'»Jë¼]O•'¬zªæx¿ —€ô€­O‡øfd:©‰hDo o1½BWP»qOŸàÅË ‚¯Îˆƒ«–®o§k܉¼ùɨÏàím~�NQ·–,^º>�ˆ©tU=P)M›:>`DJ)AF }§(ˆ|ð!ÒÉyJ‰¢lþôãw ˆw�:wA‰%Xô0!�=‹U+Ó#}6hÐMš6S¬kïž?±{÷.öÜË˯^¥±ÿÏ—??† aW„EkcJ䢃JË>|ðóæÍfäßüÔ·áï™A…ktsçÎÍ"¬ ‘WµÎ ŠöJQ_‰\D$#q’VsQ�‚—··EõcFÿ‚ä”dö{­ÚµY¤]i«¡aa"B;ÑR:°];w`ß¾½(Š!C†™=Vº�®¸&¢+0û÷Èʈõÿég_˜ê!¬¹T}RÚ%ý'ãË´C IDAT&&bÜØ1,{ÇÑ(R´ˆP’O!šÊoݲ‡bw)ò.a`ㆠxúô «¿l¹òhݦ-# «¥'N`Ãúµ,[ùòðøñ#S„d¡l@` *Uª„zõÀÇLJýL2¥¤„�Õ«V"6ö Ëck„Õ¬j?e'”pêëë‹—/^(~Ø!¶r8U{?ˆç ™�ðöfWPÊ_ †Îæµ—g3>äæ¼#í„ø=!´­†=v‚lÑÇ2v‚ð1~ìo³ÂXè#šéÓ¦˜‰µiÓ¦¨Zµº™¥6ÜÝN(½+Ç�‹„mvB©©ýÐb'äHÊT¿V|¸ƒ�P’‡€"¯Ûk'”ÚȪöCÍæKŸ�™sÓ—rªV¹ñõ´VIyf>#®QÓº^Ð"!­ï{-u¹*�š?dD¿øûÞ)ª×Áñ¡.#½98>ôJÌ}ós|¯Ží2­Óu ’’_™Ž/F¸G„UŽíºÔš“ãC«¤Ü?LJñ:âø0^¦®ª‘ãÃxÉs|/SWÕèj|ðýdWiž·ë©à„UOÕï·á�°õŽ*ŽoÿÉÚ!²ªm±ï¬w“Œ¦^²Ÿ½§ÈFD, k¿UÉeö¶§·<]©=þ ÕªeÌKz¦6hþíÝ»ÇT�-ó¯n½zhÞ¼¥VQ[ä#²*‘V)yWÐ+áƒ2såÊeQF ¬Š£Ñ2ýÿú #Ò ú'¹¥¤$Ã××Ïj¤Pkú§:ÆŽùÏ’Ÿ¡BD6lhY•±rårœ;{uêÖC‹é2£1îÙó'ìßÇM4Þ¦M›�"#[‹nzåÊe,^´�ÕÝ©3"#+�d�’œÂHÿ¾>>ð0«ƒê§$�éå”FQ~)Ú/¥Ï¿øJWY*“•í‡#ìÉT§mÚ¶SćX¯‚��Ã)}„A$[JZíEîÛ§–-_Š{wïšÊÖ­WqqOض…Ì­ôqˆ��¼'„¶Õða„�ðá;!µsgϲ°Í[´@ݺõÍÄíÉvBiÞ�œ'M�„„³¨årvB©©ýÐj'ªW¯�¶íÚ›UKïy­øpµ�P’‡öÚ kzãëmîÔos.`ÚÒË™;· Åœïy„U©`øzZÛ¼òÄ\ÖÖ ZÇ£u½ ¥>=ï{-õ¹"�œ?DÆÜ�gÏž!$$­[·aöÕÖ”•× ¶ÊÌ–rFãƒÖö̃̊[tc­ŒV|�>þøcºuëaºIÅÖ¾¸û~¬­ãR“³Ò~“Öö¸ý0—”ÚzZ«\Õô–YÖ õºoEBRú‡ÀBêŽ/Ý€°j´ý°õæ&A.Ü~hC�Vû¡­6m¹²²ý8uò¤Í~·™Ç~X['ee|È�çi{«€Ý ¨å©Ìí‡6©sû¡MNöærÿŠï'Û«E^>«I€V³šÆùx%0nþ|û[:yˆ’£ «´Ád�Ìä(UYUˆ‚H„UwL3¦OÅýû÷‘ÛÇmÛ¶c]!"&•ããÀþý¦9CWÇžI�†I¤Q"¥‰“Ú<"¹=ÿôÌ1¸té2èÙ«· rW?}ú“'M`‹W) �ˆãGEúOINV�Ô¬Eÿ7¬ÇñãÇ@ý!‚qÞ¼ÚÈÐi/ÓÌÈëBt>";éYœ(‚ðï×›faaEж];©Y.Q¤á߯Aû5 .ÌHÎjW(“ÌÔ6Š—-]Š‹ϳ&G�ú ¾~Ú¯‘åö0ÒNz—â”Þ— PÕ7•·f'öí݃]»Ò#,kµÔ6èZûéS§˜ìEÉÎí“ yò„èŽÜÍN(ÉCŒ{ì„5½ñõ‡vïiìÜ ˜ºÄ’°Ú¥e(fsª… ùzZûÜò¤œÂzZÍÿU“–õ‚ZÂskï{­u¸:Ÿœ?4zôÏxž’bêšø£A½ý5r½@·£ÐúÎÝ»xòä1û¸•ú/$:(õñõE¾|ùÙ ­™hÏÁ]÷›ôÊÒZ~GàÃÞy�Yña´Þ´úCÂÞ‚Ò­>zúå û±zÆ£–×øPkSí9LJš„Òo¬ÐŠõÚ´çp>ô܆¸„—fqÂ*LJö¹¡'§–ýX=õIóf6|Ø# G–ãÿȑë=þq‰ðp”-S–íóº2y2>¬ÍGÙWêÊÙë½c•úÇÜ¿R— ·ê22"‡»øW|?Ùmò:²’8a5+i›�Õª¤l½¢ŠãŸްêl•$%%"9ù‹‚˜qÀïì~¨µwçömÌ›7Çt¥¶8•*UЦm{YQbB+GW’4˜ÆGP ÎP]… ÆÐaÃÕºaz¾{çNìÝ·AAAøû‡›•GÎkܤ)5ldöüêµ+X¼p!;СþtïÑ!ÁÁ ÊÃÈFÄö·‘WCCÃX¿�Þ¼xñ–-]Âú%GÔ%BÔŽíÛY”EV�ŠŠ¶¸ö^<0:H›9kâãâP¿~4~·‰b´`Š´FÑmìßËHt}úÀ�ƒ™<¥éÌ™ÓX³zû™"€R$Pk‰¢Ÿæ ÉkF:ç«Áy‚ñþß?d�è‹?ŠJ‘kć>råÊ�ƒâhÌ–Ÿú;|ø{ûÛhÖŠ¢KQÅImØ3ÿ„k¢åæŸæIL‘¢ß¼Á¤‰÷”#�5hÐPv¾%''cé’ÅŒ$Ndêï�DHH^Ssbý×®UÍZ´4DÿÒÕÚÓðæÍ_ “Ý»÷DÞ¼íŠÇK󊾲>|øàÛ>þÍôXˆ K¤\"çJÉâØ±cعc#PæjÕª�Fï4f¤riÚ´i#ޯİŸ‰lÕ±#ôˆß"/E&1%z¯ÈáÁ® .ìnöÃH;!ˆJŠÓÁC†j~+á”°kаªÅNм-Uª´Iƒb;AZ"MÛóµÜÔàvb´Ø Avô¥îÖ­[Lv‚"rGwîÄì==ËLv¢‘Bäø¤gIì£-vBÉO |ÁE�Ÿ@$ÙiS'3ÿNl'HîñqOMþéŠÛ ƒ ��Õ¹›ýÐ3Œñó/bò¢t[-Nœ°*/E¾žÖ3»<'¯+ÂûÞˆQ˽ï•ê=x`?»a�nU¨QÓü#6#úbt'NœÀŸì­ÅòäɃ&M›¢|y×]YLkßU+—ƒüD½©t™²lo$¬H½E=*¿#ðaÏ<Ѓ#�””„'OàÚ•+xüäRŸ§Â+‡Bò† xñ(U¦4ÂK”Tý¨ÓÈ>U×øq¿±Û*VŒD§Î]l®Ö‘þÐ�×±|ÙRÐ M›5·¹�Ft>ì飫ðaOŸ³JYGâ£Q¯íxÿÂL”ý:–ÀWïUt©x9>\*~�jÜh|x‚,Ƈ­~‘£ÖÙ²eçþ± ¤4ŒÆ‡‘Cs”ìöCìwèm±k¤m­Ë]ýc[ÇcK9wƇ-ãÑRÆðAýö“ß¼y�lÙr˜ºÎ÷“µh‘çÉŠà„Õ¬¨u>fY HØz¶/޽ÉòRìˆl.7Z¤%&% wnåqûÑ\¿v ;vlÃÃG�Ø•ÛEŠE�ê5A_$Ú’ÄD¤æ-[¡n�ºšªIKKÃÅ‹±zÕ ¶¹þÕ×ßš˜Nž8�õëײº(º*EÏEóš8i<ž%%±ŸZµnƒÒ¥JÁ? Ð�¨™3¦áÁƒéyZµa$J#“øz]ºÊ>²re¼xžŠ¸ø8\¸p·nÞ4EHÉŒ®]»1R¯8É}�ùôéÌ�3›¨‡ 22…CCáKä“´—ˆ�‹Çí[7qþüyF¡D_’öìÝ!Áò_”ž8~6¬cyÛµ�õמ$V¥dO"�‘N)UªT¥K—f×»'&$âLìFÄ¥DDšþý²È·S&OdÑäj×®ƒ–­Z›uËÚ< Œ¶Î?*{öl,V­”Ÿzesûö-,X0¯Ò^±¢µ§J•ªì@ôÍ_¯‘�˜„[7o°h²¤CšóQ¢Q¹re‹¦HÿsæÌ}Ai„þ ñq8vü8ìßÇÚ#"i… ,ºqPP räð³gI +ácÏžEêóç,Ÿ”Üüý÷ÿÅëW¯Xô="4)¥Ä¤$P´>ŠD‰ÈÉÑ£-®Þ¤ù»téÖ.%ŠÎ[1"ÅŠ•`²Ë™3'�-“Íq-dB:ü={6�$>|ÄHÉÓ]“»Úw±J8%ûAÑȈX­ÕN´iÓÖ‚Pá)vBnþf&;Q±"Ó'Ù똘#&;AÑàÛ·o�Â…C±xÑBn'DÁšþŸ?ŽÄÄDܹ}K—Ÿ@ÕSÄbŠ\,¶�=Á‚È•3—{Ú‰\¹X¥vÂZ„ O²JöË]í‡V{;qá%L\pÑ"{×Va˜õ�}>ªÖ>xR>¾žö$m9¯¯‚?¤vû€– ëñzZ©Ü«´4ü:ú¶¦‘[¿Yk�lÔ´iSØþCÃFæ¤jé§\GG4²µ_ÖÊ�;‹•+Ó×ÌâDÑÍ[·jÿ€ö1(­ÉèÃCŠ4E”¾HM5Ù<ú(°IÓæðöörD=¾NWáÃHÁÑ�BÛ¶n�ÅZ¢´»uï!ûá§;ãcìØ1,ª0ݺө“m„UGûC[¶lÝúS¤HQö|fI™FèÂ�ñaÄø��Æ}¶ãÑSsÂjߎ%𵋠«öÊŽã#]‚úf’»ùÇúz¯=·#ñ¡Ç?¦³·»wîàÊÕ+¦3 Z9Ë?æøÐ>gŒÎi„ltŸ„úŒÀ‡àGDF¢IãwÍλÕo½õªùÇz%š5ò�’í'O˜xý Ù¼2n:æûÉYcñQê—'¬ê—/‘I%0~Á|3&�I¤Xk‰~Õ«WGÓ&ÍÍ®n—–¡MvZLäôΉ�>¥‰øg­]º^xÞÜÙ(W®ºuïn–õСƒØ±}Ó³\¢šéP¸*~Ýúµ8uâ#Ñ™Vœ¬Íʧwþ‰ë¶6ÿl™($“õëÖš"­*ÕA$_"Y—-[Î"‹€Šœb„þ©>"« ø /Ò�–D‘_»vë† ²ìtÀ<ú—Ÿ)è‹/¿V½Î�Ú¦À»wí4Ed8h»ÆRœhSoûŽm8~ì˜lôg!oþ0bÄHÕ®ïܹû÷¥s?õøûù«–qE†¬d?ŒÂé?>ýœ‘˜…÷¦;ѤISY¼]8w+ÞÜÍN(ÍKÁ~õžÚq';áïïÏ"-2ÿŠÛ ËÙ`´Ÿ ´àévbذVý+§§Ø ¥w@f°S_¸y–„Õn­Ã0󿜰*Õ=_O»ÂSsß6Åëi#z)]/¨ÕIfRÄAJôÝÔ¢5Åž>ƒÕkV‚>Véܹ«Öb²ùÔÖÓvUîàÂOãžbçöíÈž=û8�ö(Õ©[-Z´4µ.~ßûáÒÅóøóÏ?Ø> ¥â%J G�^éùñÄ$àj|¥†3gÎ`Íꕬ:ZÏÖ¨]EÂÂ�=Gwñ�më½z)gàC«,î-ÝZàLÿ˜ãC}®82‡½þ±£úf$>ÿ¸|ù ˆîÔYõüÍQc²V¯’Ìñá m¸›FâƒF;iáEŒŸs Èáka•ï'»ÿ\à=t�8aÕ5rç­º¡¤az´+†P‰õÔ“#¬¦¦¦2Ò ‘­(ZdVM7oÜÀòËP¯n}ÔoÐ@U âÐñä¬PÔ\¹s£_¿fe)òâ”)“à“Û=zõF èšpjsÙ²%¨Y³ªV«º2XJV*¾ø¢È¦C‡ Wퟞ Ï’Ÿá÷ pïÞ]<{öŒŽ)5À? Fé2eaq€D×e¥çU�†rÿþ}œ>u7nÜ`‘|_¤¾`ó­@¾(Yª$‹êª…�Gä]º*½^½hа¡ža*æ¥H/ùòç‡�ÌUïÔ_:D¹yó:#:úúù!88˜]Ç]­ju3b3E�Y¸`>ê5hh¡×Ú< Žé�âÁX›¶ (-íˆP}þÜyª£u%µ[¤õ¬]³§OŸB�5Цm{›U¥g=ms#N*HíÆýÚ[(S¦,zôìÅZVzß“þ<À>Ü$ûL7{ôíÛÏ#¯„w„ˆ]�£Æ4qÂxö!,ÝHC7ÓH÷I÷t‹­ch®T¬É>ö¢ä)øäå>\V“£³ü¡yóæ°='16ÕúæÎÏ3 >쑱§àÞ1: -îÂí)f]íÓ¡¾Yў,LJçØ{&‰£ðáþ±=rQ+ël|(ùÇJýt†Ìí‡Ú,qüs{ücGöÎH|þq•ªÕÕÁ‘ݶ¹n9ÿ˜ãÃfqfú‚F⃄5ff ¦-¿kFV¥ß9a5ÓO%>@%À «6 ŽË|°8`k[ ÿþ{:aÕS‘dˆDåííí©CÈýNHˆ‡��¯GE¡«ý(i!«zª’8>ÜCsî¡i/8>ÜC/÷ÔLJ{ê%3Ù�©K.cìÜ ‚îÞ& 3þÃ#¬JÃ×Óî‰ÉÌÐ+[Þ÷3¦O},‘+W.vK í‹hID°3æ¤$§ Aƒ†hÒ´™–byŒ^OÓGs+¢B3®”Sê}Èqêô)F¤ˆðF¤õë×â䉦[a´¼ï/^¸€åË—2Òjó-Q·n=M]ILJBêóäôÎÅ> ôÎéy{ZÏSS‘”�ŸÜšt¦I02™lÁ‡­m‰ËQ} %úP42Ryÿ”>Ü¡»  …··Ôðá(ýÓ‡üñ øë¯×ÈíãköÁ¹’L„yida5jÁ‡¸’Qbb"Ûƒ T¼åHÚîÇÙ»„1Ò�ž�vÕÆ�ž» öÈN öÔí.eõâÞ~·¼ 7ï™V{GÇ·‹´§ÚLQ–ãÃ=ÕèH|¸Ú?6ZâŽô�µâCêk££ücO°öúǎćÝ©å±Ç?V«Û�üãß~ýÏ’“-nÞPƒÞçFúÇž€½ò‘æww|Ø;>O)Oöcáú»˜°ðšE—ù~²§h‘÷ÓÙà„UgKœ·ç¶�^aØÃà «iiiìPÆÝ‡ÂõëÙ³g×5l-§«dNLL`×ÛSEOI4w(ef¢3LJ{ÌFŽ÷Ѓ´î¡Ž÷ÐLJ{ê�ãÃ=õ’ÙìÇ´Å—0fîydËf¾náŒòó�¯§�ƒK[×Ŷ–sΨ”[±å}OcýéÇï@Q�è:zé-)ÖÆtãæ ÌŸ;‡eiÖ¬êÕ¯oÊN„°)“'¢HÑ¢ˆŠê¨X�#ÖÓÄö­[€~ý"$$D±ýääd,˜?�=BË–­Q»NCÔxòäI¬_·†í3 ˜nòѲߴoï^ìÚµƒí‹üý£�A‘Е‘r7oÞ„¤ÄD³,Áy‚Z$ tí$E‘´véŸôT©Re4~·‰¦±…:$Œ‰9‚ãG�".>ÎÔvžîÞ»‹+—/³HþJ‰ðÚµ[7”+WÁ4v¾«I�.Éäûá’�XiT+>Œêw»a»qív²Yur„U[퀭匟­õ¸Ò~ØÚgŽ[%—^ÎÿøúõëÌ·¤¤Ç?v4>åëÁ‡Ø?þêëoÍnܲ¦1£ýã%™¬tžGº˜4q¼.ÿؾ—QÚ(ÿXÎ~h]Ÿ5¹zÄó\�¬îæ>fÍœÁnòÔãkÕ�³ýc­ýr÷|Îö¯´ÊCë<—Ögk9­ýrT>Á~Ì_wc朷h†ï';Jò¼^O—'¬zºyÿ “À„…Wñõ¯±¦úº·)†ÿùÐ3#¬ºë×B¶:älц*ˆxRJN~ÆèªsOIYá+,Ž÷˜�î¡i/8>ÜC/÷ÔLJ{ê%3Ú�9«®aÌœKïѶ¦ÿ_5÷T„ {Å×ÓŽ>_Ok“ñ“Ç�1yòD–Yï5Þ[·lfÄ6J­ZµA­ÚµM�‰rìØ1Œ°9êŸÉ/i=M‰H£´@DE½ä0¹Q>yò„‘0©Nº~}Ðࡲ7¸PdÕyDV}ø^^90xÈp(P@›àTr]½v‹,`¹Þÿï¶BšW%¾.µm»ö¨^½†lK/^ÀŠåËÌ…rƒ‚дI3DV2߯ðñ<å9‹üIûGŸŒú¹sç¶:2kûMt`úüy ‚ƒCT£ôÞ½{kV¯ÄÓ§OÛ£h±47(µk…jÕµGë–Î?Š*·ßD¿Ña¹‘óOn@ii¯1œÚ!’DŸ¾ýTedm¿É^ýËõ‘"ª®]»çÎ�µ:|ý|1ò½÷áãëk‘O ¬6oÞuëY�LÄÑ;wï ´P(rûXŸwD>ø}Ã$§˜éÄ €�ƒYÄU!Íš5wïÜÑ…iŠ-�·õ¾�ø~¬.QÛ•™ïÇÚ%>ÅÂQ#þÀ•›ÏÌž÷Š*ŽŠ"¬rÿÊ1²7²VŽû¥i«LøØ¶u ûÀ‚’VÿXj?áŸ8Â?Ö»ß$ö�?úèÍQõ�ö�ƒÐ¬©¥,Ì!ò§VÿØÚŒs…¬´ß¤e}FcqÄü£z¥öC«¬Õ¿r7ÿXÀÇÌÓ‘””­þñý÷Z8ŒÝ´`-9Û?¶õ6ûßÈÆÖ�÷c=�2sùŒžeIXåûÉÆÎ}^[æ‘'¬f]ò‘Ø)é[·6Åð¿HX}ýú5“„»‘;mí¸äðò’=Œ±Så-Ný~ñòòä‘�ÒàÐÆm¬<55•¦åÌ™ÓÆÜ¿˜­óÐÑ#³µ_ŽÖLFýΓµ´%Ž×É^kËZ%e|>Žãejt�FKT{}öâcþºÛ=óœEƒ|ƒQ^|=­}nÚ’ÓÞùìik<{ÖÓ7oÜÀ¼yéQR›6mŽú h989ÍD(lůB¢kÇýö+û³gÏ^(]¦¬Y½ÉÏžáèÑ£8vü(ž%%±gþ~þhÚ¼*W®¬©‹-ÄÝ;·Ñ£go-ZÔ¬ÌÞ=b÷î]ì·ˆŠѹsW³çtx¼`þ<uŠD(P={÷Q¼BžÈªyŒ5´§RµZuÔ¨Q!Á!ˆOˆÇÎÛqéÒE³~´oßU«Éü 7Äó¯S§Î+RÄl¿‰*<ˆ#1‡mžšú6ãÂ… píêöWÅŠ‘èÝI‘ mͲWÿrýN{™†yóçàÞÝ»ìqÙ²åXÄdÒ%Í3ŠjºoßP¿(žWÒ$ViNÖ¨!O¶¦hÆöïEìÙ³xýêêÖ«�æÍ[(ŠóÔ©S,Z1‘'¼¼½P³fmDFF"oH>F�>~â8ïôœˆÙÑÑ�MuQD¶;"Âê“'�@„JåªHÑ"íÌ_�Ýú¤wŸ˜ï7éE„íùùzÁvÙ©•ì8òO\ºžn“…Ô³}qüëýHö'÷¯Ô$èúçÆèÀÿ˜ðA~ET×ã‹í‡þ‰³üc[Ö®ö�Ï�;Š$ÿòm´u±,ž9zü㈊‘è s›„«ücá=½té‹u’Úú̈ù§„@%û¡ækõ¯ÜÍ?ãÓüã ¡x‰âj,\(ÔêÍƼy_‹­~Œ£{fk¿´âÃÑý×[¿Ô~Ì\q•ï'ë"ÏŸ¥%À «YZý|ðb L\t_�Έ°*&¬f£¯°<@\´ð  M½›�Žš°¸Õ{ż§nHP¿S’Ÿ!$o>G‹Ö°ú=ÕÔ#Ž=Òr\^ŽÇÉÖžš9>쑞qe9>Œ“¥‘5q|)MÛëâø°]vŽ,™™ñ1{åUü<Ã’°Ú³mLãV-¦_O;i|=­O¶D \ºd1+d�(­õâ… X¶l‰éç£Q¹rÓßDýËOìïv2ëÓ§O°võ*ÜyKŽ“Ö-�F%7¢;·ocöì™ìQ›¶íáQœh¯gñÂ… HN”ÄmÈF.\8ßDÎsÄõŒ÷îÝÃÌÓXÛõQJ¨µ¦¥˜#G°yóï¬ •'ŠH:kætF¤H—½{÷C¡B…d«#lß¶tý*¥&M𱍗d‹ÄûMDX&bE–GÎ9‹Õ«W²}3!IõLý âïýû÷Ìú@e"*KE¬š:mR’SÙ¶k×î(n–�úG‘ˆ21=$rg¥J–Df¥y žï¾Û ½c67—.^„ÛwnËÊMËü³¦?¥g<ÄìÙ39˜RÁ‚Ñ´Ys”*UÚ¬ˆµý&{õß aCÙîý¾qŽ;Êž5jôŽ)¨83éîСŒTÜ¢yKÙ¨hÂ�|T‡hT©’ñ> 9tëæM=ƒ³gcMsÊßßíÛGYÚ…vIGsgÏbù ,„®Ýº#8ØòC÷-[6áÈáà £F}¦¨"±¹•R¿Q¼˜ù�<·¶Ìlç–áû±Ž•wç÷÷àüÕD³FÂ*LJceoDíFH1½½þ±€�kW¯êò�+Tˆ0D!ßÅ^ÿÄYþ±­ûM<ÀôiS˜Œ�í ø ]Iýc9ÿÈýca¿éþ½{²ë$kë3#柭Ùkþ±Öónwó�¥øðtÿظ7«kkÊÌû±®•¬¾ÖåìßOÖ'Cž›K€Vùàx+é[×ÖEñÿ>ÒÃ]„HŠÞë�ÝwúŠ�ú¥7¢ }±G‘2ô–sôxÔê§~'%&0²ª»éB©ï)ÉÉðòöö8Y«éBúœãC¯ÄŒÏÏña¼L�ª‘ãÃ(IÚ^LJí²stIŽGKX½~Žu¹*GfÆÇœÕ×ðÓ4Ëk„{µ+‚©ÿO>*ž«ôàíòõ´c´À×ÓúåJä±U+W°‚Ñ�º°È…ZÒüùsqãúuSÖ¨¨Ž¨Rµªéo"˜}ÿÝØþ†˜GWQ®X¹t N{Å¥ZõÈöæ ~ÿ}##ÐïC‡Ž@�‚»B‘wíÚÁž÷êÝÇ‚ôG¿S[S¦LbQF©Î~ý0ÒÛ¢óMdE"Ù ÓèDQD‰XJ‰®/©¹ "Þ¯ph(† f*G‡½³fÎ`DÎ\¹r¡ÿ€�l|øgcÏà̙ӈ��7Õ†Zµê BD„bïÔ)“@$"÷ö0ˆÍ{¹tõê,Z¸9½sâó/¿Rìÿ®];±oïö|øˆ÷XY!qûa³Ú�V�ïÇ:^ÔÝ>Ü‹ØK f õhW ß¼W�ŸW8^üvµÀña—ø, ëñ�ÅöC�\¿~öA �çåŸ8Ã?¶g¿éþýû˜1=ýgúÇrøûÇrþ‘šܶM;æ“>|Èmüca¿I‹,^Ÿ5ÿäP¨Å¿’ó�‹)Šzõ l¹rVÁínþ±>´ûÇEP«Vm§ûÇÛ¶nÁ¡Ceýcc߬®­-3ïǺV²Ú[W²|?Y» yN.’'¬òyÀ%ðV“]Å—¢«]ZÅÿ}ìY„UwS&9ïä`+mÀ*õ—¢3Ð5Zte•«9{”ô�N©ßññOœ—]]ç éÙ³$äÌ™+Ó“UÝQî¨ó>q|¸NG®“½Ö–9>´JÊø|ÆËÔè9>Œ–¨öúŒÄǼÕ×ð'¬j>_Ok•æŒFÎgÍ�”Ñ•ëé Îcù²¥l$]»uCùòª£¢+çÍ�m–O.Ê©M¦jÕjhÕô¾ß·gŽÄa{]ºuC¹²WÐÓµä³fM]NW¦wêÜE±/«W­dWÞSúû‡#((H6ï‰ãDZaÃ:ö,0(A�AŒ¬H©x‰pôîÝÇ!·îˆ#¬ ”È Z“p@^²TiÖ?!ÑA"(RR"éʵAäÍiS'3¹ÊE“�‰‰ÁæM‘'8|ð!«bά™ŒÔÛºu[FbΞ#~ý#©4aEŠ@ˆÊI¤S"ÏÒGÔ”¦LžˆÇ�£yËV¨[§®©Kb’BË–­Q»NE‘ÄÇÅc„±¦ç�»tCD„åÜTš´ß$\É+Ì?ªL8�µwþiÕ¥\¾WiiØ`?îßÏÈ�B*V¼8Z´h…Â… ËVoŸþ§àÑ£‡²ú_¾l.\8ÇôG„���›†G�?ÿô+^²ðäñcS]Q·bd%T¯^ƒPÕE^¿n #7>yóæU,Bý§qP´a"e+¥�;·cÿ¾}ìñ‡~ÌÞ ”¸ýPÓ†ëŸóõ‚stÐóã}8u!ƒ\N­vk]_¿WŽŸW8G6µÂña“جÒê‹í‡^ÿ˜"ÇSy#ýGûÇöžç¹Â?VÂGº¬ìYó�Ûµ‹BµêÕñòåK—úÇy¾|ù sÙÚ<�®ÏŒœÒŽèñ¯”ücò)[µjmñœÐ–Ãüã¥Kqáây]þ±>ÜÝ?&|8°‡¦VÅþ±ñoV^£Xzð!.—ù |?™cƒK@Ÿ8aUŸ¼xîL,~Àf¬rÉ9¡´�«'Á5%%�zŠš×–Ã5ëÓ§�‘'Oˆ!äOêm® $†`×�%%%ÂÇÇ×ìê<£ÛáõÉK€ãþ™ÁñaŸüܽ4LJ}âø°O~î^šãÃ> q|Ø'?w/m4>¬½Žï¦ÄZ »wû"˜ò¿<ªT0|=m,BŒžÏÆöÎzm®^O_»v Ìg�¢"Zë1­�gÏž‰»wî 88qqOYö-[¡ŽˆœH¿Íš5ƒå+]ª4Ú¶o�‡aÉâ…,¿Òµët0¸|éÒôÃÁ÷?@H°�&MšAîZ_¡œ8‚Ô?>ýœáŸÛ½š6Ïï(|­ðýXûô£·tŸQûqü\Fh*ß¹eþóIFu-uòóŠt)q|h™-î™G‹,¶ºüã™ÓA~¢½þ‰œä´úÇ47Éÿ¿q#㶪ϚlÄyžØ?îܹ ó�µžçéõ�µØ%ÿˆd¡ä‡…Á ‘/í)þ±0_Lë3;ýc5äÚê_%&%bÏàÔéS.ó�‰8š>ÔÓá+áÃVÿXÉ~å‹ñ±{×NS„UÁ?VÓ/nŸlÅGfõ¯æ¯¹Žï§òýdûf/�•$À «YIÛ|¬V%0yñ5|ñKz4 ¶yѪ(þÃ#¬Ú4kÈ9I{ù>¾¾ºÊ“Óúüy #Qê‰lª«•ÌÔwZTæÈ‘CsµäTYÕß/@÷˜å!çZëÂVs'%♜銞œ+ŽûäÍñaŸüܽ4LJ}âø°O~î^šãÃ> q|Ø'?w/í|,\wÿ�l¹ÁØ'ª(&ÿ�¾Cnw—Ÿýãëi#¤˜^‡#æ³q½³^“;¬§éÊnоI‰¢iÖ¬UËj§):!E)¤=ºÊsþ¼¹,¿øZI¡‚Ë—áüùsÈŸ??úõÀ®³§kÁK†—Bï¾}eÛ!û3yÒD<}ú„÷7~W6Er¤ˆ5tå<]=o-Ñ•âS§N6zÒþÅ€�ƒÍH–FëüÎíÛŒØK©StT¬©©‰`ú´),¯82+E;¥¨§”F¼÷7&S-IÀÇ�;·±dÉbâÃ�>1+*Ž"6xðPPT&º²¾[÷,2¬°ß´}ûVlŠLc&ò7‘À…d«þ…ò—/]”Õ?EÝ�:eË&G:×2Ç„¬¤¹Ëü¼"]Tš§Œ[fÛG9ÿXºþÐê>–/]‚K—/ÙåŸØã ë�„„Íþ±QçyÎô�µœç)ùG4)•üãþý‚¢â Éüc1È„õ™=þ±ÒüÚ1b}þ,) »víÄéÓ§LÝw†L}òä1¦O›ÊÚÕâ[Ç-þ±’ý0Ò?ãCêó3pÇš%#ð‘Ùø |?Ù±sŽ×žù$À «™O§|D6JÀ‭eüç“*6Ö–u‹‘sòòÅ øúùéÂó”äöñqøæ¹RÇl9\£EùÓ'�‘+wn—F…Õ*lêobB<|ýüu“U�±1¥užš�ãý5ÇñáZýp|¸Vþj­s|¨IȱÏ9>+_{kçø°W‚ö•w>¯¿�ÿ›”ñA£ÐKNX•×_OÛ7�Ňa|=mŸ,éúÅüž+êÕ¯�fÍZ(VHQ˜(½Ç)Bjõ5ðýwÿaù«V«†öí;˜•%Ò"‘ýüýQ³FMüñÇn¶1lø( |%ø¾½{±k×Åë½)2å˜_am•*]½zõ¶*ºÆ~Æô)ìšzJr$Kû¤hYúÖ­[˜;g{ t]§\›Ë–.ÅÅ‹çáççLj¥ÂÇÁB”'úý“QŸjê®ø}éÒE,]²˜‘ù>ûüK³òÂ3ú‘Ú£C×Â…C1xÈP³ý¦ØØX¬^µÂ¬l·îÝQ®œùU¤B>±œ…ˆZ9½sbÔ§ŸÁËËz¤Í“'N`ýúµ¦¶úöí�ááfmKçA�=Íö›ˆÄHdFÔ0pþi¾†LRèÖ­›X¾|)R’SXéþ¡X±bìÿ¥ú׻ߤ¤ÿ›7n`Þ¼9¬ %R°†¡°,D(X»fµYöòå#Цm[6Ÿõ¤«×®`Ñ‚¬½—"#+!0 �Ýx”=G�îI^G�eÑ“‰@ݧO?“¼”ÚÚ°aN?ΈtÍ÷cõhÆyyùzÁy²·4à‹ƒ8rê‰ù{¾M1ü¯Â*?¯p¼î8>/ckþ±t=­Ç?&|üñçˆ9b¼¢Å?Ÿçiõ��<Ïs†¬RÿHì_ÉùÇÒèª4�éS4yŠ*/$-þ±t�ähÿØèý&=þ±Þ7ƒTÿ>ˆX­Õ?VÇ»ùÇrøûÇ_}ý­bp*½ë½úÈ ù�Ƈ3eæH>ßOv¦&y[™Aœ°š´ÈÇ`ˆ¦,¹†ÏEXå„U“\µ:n¶:'—Ê~~þ†èÒ–Jèz6:ÈÐY5>î)+“GáZ?[úâ¨2$ç„ø8ø¿Ý×Ó•uÕWNzú銼Fác÷¡øûÿÅë×o,†ñÏ¿•E¯¨2®k“ãúè9>”åc>”ZàöÃ9¯w°ßüz«·Ý–p�¶Åðï¿k��â©©·Âñ!/#"•pÿJ}þdöî€�%oâÿM8m!꾊bÒ¿y„U©`øzšûCî´ž¦‹IÊÚ•àùsÞÜÙ,ªiåªUÑ!ª#Sâ/?ÿÈ¢f–*UšÞ„DþÐöm[pøða¶�-{vÐ῱U:îÞ¹ºî�Ò‡�B`@€Yqt¦ê5j¢mÛvV_óëÖ®Á©S'Íò 4aEŠ8Ì<ܸyóç¦é:zºöU-‰#9µlÙµëÔ1œZ"ÊR!é~“…R®ü•Ë—°xñ"³îEGwFd%s1..'Œ3åó÷óLJb±÷qáÂ9,_¶ E‹ÀƒXþsçÎbåŠå(^"ýúõ·* ZO¯\¹Ô/!ÉÉP<ªU¯�ºuê˜í7íùóF’Ö;ÿîÝ»‡™3¦)Î?5=ŠŸS¤X"�,Å‘F•Ö Dz¢‹±"Öÿð#uï7)é_Œ5Ò éÇÖ´ÿ>ìܱyóåC‰âÅ™”’¯Ÿ/Z·j‹•¨ºâv¥„ k}"2l—.ÝX´35hÝÚÕ8u*=R×'Ÿüƒ‘éõ$¾žÖ#-ÛóºÃzÚöÞ»oI5|PÏyO¦Ü!¤®­‹âÿ}TYu`ª"2$LJ!b´¨Drþ±Ô¿Òê‹ñá(ÿDÍ?–žWhñ��Þor´¬bÿHê_¹›L“–nK ¨°Zýc¹u’-ó�ðqÿþ}UÿXëy·Ô?V³Zücµ7äÞbý2ÌtÞ­Õ?Ö‚wð�…±+áCìóí¿ddñó–mº‰ÿÇ «Z§_OËKÊ]æ³V=Ú’Ï× B$TZû~2ê3x{›G¿¤ëÈ—,^„ÔçÏ1•®ª>М6u >|1Rð‡NŸ>ƒ={þ0‰‰¢ ~ðÁ‡�PÅr¤²…õ§¿E~¢+Å#"̯�?{6«V¦GúlР!š4m¦¨Š½{þÄîÝ»Øs/ooFš¥”¿@ :ÜakwñÁª\ô#i‡>xˆyóf3òoþüù1lø{f¤Dá:ÉܹsãÓϾ°:õäö›(Ú+Eµ"â$‘QÅIz Om|üñ(&/i3ú$§$³ŸkÕ®Í"íJ“@X ÃàÁCÙãcÇŽâ÷��Î]º)öŸðñøñÌž5Ý,O§Î]QQBxÏ"w6iÒÔl¿iïž=ؽ{§®ùG™é=dmþéÁý®�;°oß^ Å�!ÃXQµõ„ñcAùDÀ¤kg)éÑ¿\ÿ”ôŸ˜˜ˆqcǰ"r$e=cݺe3>Ä"îRä]ÂÀÆ ðôiz´Æ²åÊ£u›¶t¹6Nœ8� o#ì–/_�?2EHò¢R¥J¨W¯|||4íÇ®^µ±±éÁ¬E�’ë_Oë™ ¶çUǵšù~“²t´úWC¿9„ýÇôV9>lŸózJr|è‘–ö¼Jø�úÇtÞ >ÏÓê6Âì<ÏQþ‰5ÿXºþÐâ;b¿É‘þ1Ý@ ÷hígÍ?ÖsÞ-ö�éã6-çÝŽô�+T¬ˆŽ¢MçÝZüc­øpµ,LköCÍ?æþ•ýþ•|ˆ[Ë*þßOÖî³ðœ\$NXåó€Kà­¦.½†Ï~ʈ°Ú©EüwT•,-rÞÉy£+ª¬%[�ª›œwóè"Î:žQUYõÙ³$¶qLývTÔQ#¿ð"ýÐâ60(�ª.¥²çλuçÝø ‚IPš¼½²aöuQ½bˆÓ Âña]ÔÎLJxS‚Ûyùg6û±ô÷›øßñ–„1}­Êy1ë;Š<•ÍiïE#âþ•¼¹eÄìòü:Ü Ë7ÝÄ¿e«ý:ÅDaÕb²ñõ´%þÜi>;êíà®ë� Gãn×. Õªg|ÜBÑ7ý¾iii,úbϽà�3cÏcÙ²¥¸xá<»’ûË/¿6‘ñh=½oïìÝ»Ç$ΪU«¡}TEñŠ× t K³uëÕCóæ-ÍÊÄÄÄ`ó¦�ì·wßm‚†�Þ‘­óСƒØ¶u {FQûöé‡eË—âÞÝ»ªeí�b™8E‹¦_í.—?~Œ… ç#)1^Þ^èßo ˆì)N4w~ó+^½JE"‚°\’Ûo:þV,_ƲË]û~ùò%FHRÍZµÐºu[Ùú}ÓãhÑ¢ùÂjÁÿÏÞu€IU,ëÙØ]r Šd‰f@ADÉ *#ŠŠŠ9§ç5\¯Å€A@$£HQADrZò.°9¾¯Î2»Ιî“ffgê¼�ï>wªÓßõŸªî®S]£&n7^ùý·ß6aÑ y*§öÐéã߯¾øâüô¾áF´mëúÑ•³\uÕÕ¸âÊ«\ʬZ¹B—þ9vÖ¿nÝ®1¼—EÁªt(OïV¯QC¸ßä8�wÎFKYmÞøÏëÂùWÃÕÛüSF ·ß|™h×î\ßûê?{ö,ü½};:uî‚k¯-á,éãêÕ?cÝÚ5ʾ`tt4ºuëÊøE�éZÏîÝ»ðõô¯”Ÿûõ€-Z*7Ùdef!7/q±±H¨X±´Yûñí¬رc‡RïÃ�L†ì꼫­Á¶ž6L€.(Ëâë�OoĚͧ]F3°g=<¿v†Uæó#€Õ_Ø5oüØ¿o/¾øâs¥úà⢋.*ý0F�|Ï=÷º$Ÿ±Ê?‘õ�Ý×2þ1}dÇyž³LåÐÇ9Z�Œ¬øGo¼®|�6dÈ-ÊZEt6ëh¯¼øÇÔ_òצ}ú‰nÿXm�¤GÿÜù¡µ>Ó{ÞíìËÞD¡éŸŸoë#‘wî,bcã¤7�uvI·rs”á(X5)¹’ôâÖÙñ—ÅÆÈ8eË„"?>ÿn/^ù°dQåüÄdžcú—ႆöy3?¼k(½û˜ê±ýðÄ…Þcl?dßúer WÁ¤W·¨l–’ˆ¯ß¸11ᚇ¢ý`ÿJ[ÏØ¿rņù!~'Íþñ ž|»äš]çgXßúx÷©Ðþ°Q =^O»¢Âþ�ÿý¡©MQ®z¤=‡ë¯ï­thýºu8rä°òÿ««Òß�34M¸o"òrsJ×ÓŽŒ2ŽÑQ†©š5kª¾PÜ× sçÎQ®ROiÔ·Ý6Ô¥ŒãúFúã5×\‹Î].õ¨Ó‘Ñ“~ Œ¡tÍcåÊ•A×Ú4åäåç){JÔ'Êhêx¬zßïÙ³Ó¿úR©–Ú®]»¶ê¸wþóæÍû”¥‡øº ”QÒùqðcé’•kÖÕ²¤’¼Ú~Ó�0ã›éJý�RãÖ¡®XR¹íoÜoK2ÖÒCÙ]kÔP¿­äŸ�;0kÆ ¯�§Ž€U笻Ž,UØLÙ[)#¦óãXOÓ•ò”¥“ʼ'Ã7 IDATvµí¯’å)(ƒ‚—�牂¡þiÕùß=õ@�þ¹ON™þ5Âm· S�;™?:7nÔ×öèáu¿éôéÓxÿ½ÿ){žÎÁÚ4·¢ùWë�Ìü/\0[¶lVöÀî¼ón$&%iÍ™ùyù.ÁëŽ,eìLAÏÎeþaáüÒ@‹:uêâúÞ½AAÍjOI€6è¢V­ZJ�³Ö~‚û1kæ Ða?=<0 qñqÂiäõ‚6D¼^pÅÆ*û!TJzøA™#ù¿X±á˜K zÖà «Ì懬:–W~”úÇ11¥uèõ�|èa¿ÇÿDÎ?v?¯�ñ�+TÇÈQ£5}WÙ9W“³Ò?vÔ¿pÁ÷زe š_ܸfIÕ꫌´cÇv|;kVivûÇ÷Þ{T»ì¬3Þüc*,Z'ÉꟚýP[Ÿ9ïvö�›4¹´êíÑò�© }Xém}$ò�6l„¡Ã<}}5ÿXæ¼Â ÿ¸ZµêªËéñ�ã–9ïž9cvî,ù ËÙ?æóœ¹½Z–Á«ß5uðÒƒmlG‹ 5ý³2ðÉìWBTžú$úz�œ˜œœlCRiqå· Ýì¬,¥}YÜéëFÇUveU%e³rs”ú|æL’“+ çÒ]ÑÉñÍ¿íä8�G¨òãýoö㣙žW`WIŽÆÌ·/C­êö{3?¼k7óC¶žØ°ý0f-Öl>�ñOþŠ¢"Ïò ëÄ+ÁûɉÚàÙ¿Òä56#r¥Ø~°ý�ÓO©@´³—“ozf½ç€UõYæõt.�¨ÏF¹©U®<¼ï:„Ï?ÿLÉ�êþ´nݽ®¿Au?àì™3J¹¸¸8Üpã�¨T©JéÚØq€HõÕ¬Y co§ ‘ÚzÁq]eRRî�p¿K¹M7‚®i¥çª®ÝpÅåW¸ü¾gïn|ýÕWJÐ�Ò!hãÆMJeÖoX�eç3¯Ö®]G9”§} +ý¡�;ÿÁÌß(mªêRàìòeË@‡áôPfÕoìçqí½3?H�>þd*ÒÓÒp饗᪫»–î¹ï7‘O½nÝZ¬[û‹ôG×§�9„§û³eóoX¸p�ògÊìJ™@½=”ý´Jå*A§Ž2Ž€ÕJÉ•p÷½”?Sÿ(3RFF:t숞={•6A㪎+–ã·M•¿SÇ�»o¿õ¥ÿ”E—²DÑãX/üóÏN,Y¼HSdõOm¬ÞôOÏû�tð½wÿ‡´´’Œ…Îãp¯'333¾ùZ §`êñw܉ʕ«(Ù�i¿ÉÛü»×¥gþ)ƒÙ‡SÞWôŸ2ß|óT©RÅc˜ô{Nn¶ÿµ ¿þºþ|ï*•sd¾ÒÊ”EXlÞ¼+–/U¨‰s—´ïÊŽKAåîÏ¢E ñÛ¦MÊŸ)Øúƾ}Q±¢ëÇÈzíÇ‚ùóAAôÐ{E�îýàýXu�çýXW\¬´Žšýq^1áùß°líQ—Áy Xe~0?dlbyæÇ�ýûñåW_ È€�¼ž.C$õÙ ?ÝË–§÷ý¾½{±|ùR?qB¹r»n½z¸¤]{4LIñ ‰–?ä| zM�žèÜ©³G=Zë…íÛ·aÎìo•uöäÇžp9Üúûï˜?žReW¥,«Ž‡²Ú¼ûÞ;È8wNùS¯^×+AqÎéÜÇS?ıc%Yä(x²Ý%—Xºßä|Í(]eߢU+äfç -= ÿü³PjéI®T ƒݤõº?îü8}ú¦}ö)èð¶R¥ÊhÑ¢…rÍ|Dx8Â##”ÃúC(מ¶ôPfÙ!·Þ†Ê•*{ÔO‡aÛÿގάö¾áFPÍ<Ž€U÷`ãmÛ¶á»9%™\[¶l…æ_¬\qŸ––ÊøE�¸ôÄÆÅ�®‰¥Ì·¼ÿ.èÀ¸cÇNèÑó:8ï7yÓªGFÿ´Æ¹mÛ_ønÎlUýÓ‹ÍÞ={0cÆt%ð–ÊVܺu$''£¸¨gΞÃÁû•l²”ù—tþÆ>ýЪU+e�÷›Ôæ¿VíÚJÀ8•Õ;ÿޱ¬\¹k~Y­ü'Â_tQs%»qRR"ÂÃ#pöììÛ»;þù¤3ô¸o¼üò‹(¤+Åï¼[ |ÕzΞ;ÊZEYwé¡àä~}û)¸8?4ö3¾]ÉLe罸ysÔ¯ßPÁ.*:Záõ—t\k¯ØÙš3{¶o/ 7þNT¯^Ýëtúû°¸<Ù½¼pÈÂzÚhßå‚i==ñ¥ß°xµ[Àj�ºxa¢§/ÏüP׿VVç˜êHùú<ï䉓ºýcoü0ãŸÈúÇäû^{m�Òó<‘LþUAa�òጳLYù� &[L�ÿ˜Ê;óƒnér÷�ÍúG¿oÙ‚ ¾Wúj—Löƒcç_²®qøÇ”4ˆæaÓ¦�Rþ±ó9ˆæ¾N"9ýÓz�9ëßC“A~~ž¡3`âÇñãÇ1ýë/Q�_rs©ÿØ]' ùÇ•*aÈmCU×GŽúEþqFÆ9ÅOݶ}»5þñüïKo0ãSÿ òóQ!< 5jÔ&Zr÷�ÉÏæóní7ŸŒ�÷õ~¬•ïi¬?x?ÙÊäºBX …Yæ1J!àí€ ´çNQ«>ä¼ççå)×ÓYõøê+!j‡2«Ò×Wz*K™ìÌRê­OätÇÄÄJ«’3iiP±ZÿÌ~eî\§™Ìª�ŒÇü(™Õ‡^Ù‚~:â¡65NÄ—¯_ŠX/×aëå'óÃ;b̽å)ÏöÃ<†î5›ýصÿn™¸™ÙžÙÐã#ðÍÛ—ƒ2¬j=ì_U°^É$jdûÁöCBML‰øÃ~Ì[~“_ÿݣ߰ª>•¼ž–Wqè³|ï¼K†úû~åŠå lMá˜0á�ë·½­Nœ8�)¼W²Æ›ôˆK†ºÒûëé_)¿uï~-º\ziéD8_ßyÙåW k×nª“tèÐA|öé'ÊoIÉɸ}ì8K÷›þüc+æÍ›ëUA(kÎå—_�ö:)É>™™ ì“ëí¡¿víÚ¡[×k\®nw”qì7QËÅ‹!*2 ÷M|Àô~]³úù´OѬÙE¸éæ›]º¸aÃz,_¶TÉæ©öPMÊÐé¸*þûùóðÇï¿+A Wwíê²ßäM¨n‘þyó�éêQ-ý“�'’sì7�;—‰E?,,Í´ªUùö¼®š6mæ¬ê(cÕü»÷aé’Å ù‘y(óë ›nBõê5ñììlüçõ×”`ÛG}L¸‡H¸Pƪ•+JoN9jŒÇõÃtؾlùRlÙ¼Y5û³£¯ÕªWÇøñwztÝÝ~¬X± k׬QäîàA$Ä«_½K¿ó~¬º&ÛzZFß½ÉÛzZmOµ�ºxÑ-`•ùÁü�áN°ñCfÌ2öèBuËúÇ]»vÇe—_^Úeoþ±óyž³LAk÷Ü{Ÿì°…r¤ÿìØ�9ç?^Ò* ã«�çIûGáhÛ®ºwS÷�ýÚøë¯¶úÇÎü0ãS0­ã¡wó�û5×Ifücwý»ãÎ;Qµª÷ÔæØÙ~К�‚u7ÈøÇZ2zæ¿MÛ6¸¦{Õõ‘{ýôQ}X'ó˜ñ�I(€nȰÊ?®Z­ì6­18ûÇwßs/’“+Dr&>ï–Ñ:keüµÅûÉÖÎ#×üpÀjðÏ1�P�©³öá�Wþ,•îÓ­^™T’aÕê«ôÕd^n.ââµ.$»]*F‹š¨¨(½ÅtË›9\£qS°ª¿2wÒ—‰±±qÂ�f(¾ø²š²'¦VÍaœ–v ÉÉ•…_š¹O~NNŽr�ã¯ùqô‡ùáOç^÷<· «6”dËq~:µ®Š_èˆÈóõÌï¯Cæ‡nsáQ€í‡y �kFûq05K V=}¦${–óU_ü_´lš¬ $Ûó¶Àˆ–²ý`ûaDoô”ñ—ýø~Åa<úž«#ú×Ç;Op†U÷9äõ´œVûKŸåzç]Šß÷]£:ëÛ™èÒùR\zÙe.€‰Ö ä»QÔè˜ 6Â¥,íç|ðÁ{ˆ�‰Åà[nE¢Ó5áÔæÌ™ß }û¸Z#XÕQiÒa4Ý�‡Ó®ÔAý£l—?,X€ÔÔ#ÈÈÈP2ARPjÅ„DÔ¨Y M.¸Í›77µ·qèÐ!üñûIMÅÙsg�›“«d'­^µ:5n¤duÕ ÈsÞo¢àº ²K—Ë\‚ÌrðàAÐ!i¬ÊUï©©©øå—Ÿqäðadee){}•*UBãÆMжM;—ÀæãÇ�á«/¿@‡Ž�Х˥Ê™ãñ¦$ãMÿÔÆæ¼^𦲸¸ï7åç€Fvü½ÇŽEVF&ŠP¤Ìe×mrAS%c.eÕñƒúpôèQP`ôþýûuÏ¿ÖöìÙ�ß6ý†C‡(s£d0 W2.'&&¡^½zHIIA£ÆM\>¬§,g}øêÖ­‡~ýx…Èy?–²‡-_¾ GŽVx^£FI¬û“žžŽ¿·oÇþýûpòä %@–Ú¤ý¸øøx´iÓÖƒïjö#-- _OÿR N=z¬×uïǺÂŒëiY.kÉãzš|yòé�÷€U>¯ðÔæ‡'&ÁÈ™w† ?ôú'ÎíŠüã÷Þûâbã”Ìú2þ±ÚyžÃ?&ßdìíãd†íUÆ™™¦ýcÑyž7ÿ¨^ƒzhÓ¶*&TŽËNÿ82"Âã¼›üã ë×)¾Ž¬Üå²ËKo°pøWVûÇîú7õ£)Ê9*}h¤÷Qã‡ÿX¦=oó_§nm´nÛÉIÚ{åÎm8øAsâk�¬f?¬ð�i}ÕVÅ?VÃÐáÓY÷è1·óy·Œ¢iÈðþ•1ðx?Ùn\*tà€ÕÐ�{¹îl7v«ƒW«fX5“:]kÒhSSëª(+'šúž��¥lêê}è‹*ÚxõWfUºî+..^>X5'G9h±³¿ä¼Ó‚˪¹#ŒÓNŸBRr%ýÁªÙÙÊõcvŽWFg˜ê™ñò Š1öñ ØøÇ)»uª�wžn�0qJÌïÚI‹yæ‡ ƒµeØ~˜ÃϽt0Ú�Óéy4a5ŽžÈñ«B`ÊóqY»jš@²ýðOfU¶l?¬}»yÖæOû±`å<üÚ�N�Ðÿ}¼•ÝC/wõózZÛ¶ƵG®¤7ûñøײ:?ý¯­‹(ùøŒÏ+<1fûÁöÃ�óƒù!óæýXÞ�uè Û¶l?JàýdëÁ2Œ@°ÊÚÀœGàão÷câË”âaGÀªc¥bÅDK¾ê!0—²bÆÄXRŸ7e ¯Å²²2a¤ïŽ«Ñü I�9“®lHSV™G&óƒL=Þd¬þR™0¦`ÕĤdÝÁªÙYYŠùc~œ1b~x_ÜfçbÌä ø}Gš‡j î]OßÓR·Z2?Ä�1?ĉ$Ø~ˆÒ÷{0Ú�³™öÐZü»ïœ*¯=Ü7t­­ Ûßo޲ýó–í‡#‘„¿íÇÂUG0éUXÍ“ãw^O{GÊßú,;�îrü¾#Çï{1F" æ‡!}¿ãzAžÒ¼^àõ‚C+˜¡Å�'ßú³tt¿kêà¥Û€Ï+°ûgzœ0¢îÒDX!óC˜bŒDl?Déÿ=ØìGVv!†?¼N3XuÌM�ñàè 5�bû¡_‡Ì–`û!F�í‡#‘D Ø�Å«S1ñ%XÍ—ãw^O«#(ú,;�9~ß‹ã÷½#‘óC„�þ߃m½ ×¼^0‹ þòl?ʱýc$’�µÏ¿÷¾ž¿ß¥:¬2?D3 Þ�C$”�凰" 0?Ä€³ýc$’`~ˆÒÿ;¯?xý¡_k¬-höƒ÷“­�_®-øà€ÕàŸc¡$v°ÑõòŽ`U«²vž;wV Vµ3Ð� |^n.rórËe°*e­˜˜$�‘ÕNµ–ÚYÝΙ3鈋‹×¬ê ’¡óC%O™c's0âáu8�šåñã£ãšcxÿÍŠy™ÚØ3?Œé¥£Ûsø…Šý `Õ1�mÀÖiªCîߣ.^œØZL¶öè™·ZÙ~ˆ1gû!ÆH¤c�´þXòK*îÑ3`uôÀxë±Væ„¥y=í:©ì٣伞vÅ•ý!{ôLd«x¿É;îì™ÓK¶æð •õ´Y”BÅ~¼üÁ6|1oŸ \þ Xåõ´XkÙ~ˆ1ù(�´žÖ3æ‡-æ‡#æGV¯›Ù¿’Ó¿Pñ¯äÐð�T ÚÇ~rqqÂÂ"J�àýdßè·Rþà€Õò7gÜc›øtÎ~Ü÷bY†Õ믪�×=ŸaÕ`›9ÙÙÊ• •*W±,ª/®| ŸžvÂÑœ\ÉàèýS¬°°Pɬª'¯  @:°Ǫ̃¬^$Ð"•2¤FFFêêVÀ,n™ºæÍ]ødZ.†>¸V5hõ•ImЧ[�ú™bÈ™bŒD›?l?Ìa¨V:ØìGn^‘¬ºyÛiU°ºu©‰wž¼aaêX²e½Ž‰jdû!B`û!ƨ¼Ù�ek�bÂó¿yt{Ì xs2¬ºÃëé2Dx=mî} U:Øü!³(±?dAýåÙcÆþ�£òæÉŽˆù!FŠù!ÆÈj~¼öÑßølΗjý°ÊüÏ=óCŒ‘Õü0×¢u¥™b,™bŒ˜eðy·9}1Zš×çF‘3^.Píí'ßûÜ—`U%ï'Ÿk.ÜpÀjpÏ/�Nîl½®ª…ÿ<ÚNG ®¢ÙYYJ°jå*U- V¥:£cb,«Ompt¸–vú”ÒFr¥Ê°*+¬a u$Gœ2]$%W’@%‡†Æj÷8óòò¥c4ÞEI·¢£c¤Çé¨-P® a~X£ ZA«äõú#í@ï1ÇÃücÎüc$ÚüaûaCµÒÁf?(Xõާ6bÃÖ“ª`]Ù¡:Þ}º=ÂÃÕ£UÙ~X¯c¢Ù~ˆ œk ™â¹Ò#±|m0rÀª,f¼ž.AŠ×Ó²£O.Øü!}£÷”æ÷½Yõ—gHŒ¯§Åñzº Þ�5§/FK‡šýøÏÇãão]Vû_[/> }›‹QlµÊ±ý#ÊöCŒÛ¶vÞ¶)£�¡f?d0±[†í‡a¶bŒØ~øÞ~,þù&¾ü§ô°jN_¹tð"À«Á;·<2�|6g?&8eX5°š•™‰Ì¬ T®\ááá:{¢.N4´(¡àJ;ŸÓ§N*Á›”¶<=”m…2«ê Vµj~¼aeõá}©¡;³*é%<ûbÌÞð`~XË,­ UzU¼ýÄ%èÞ¥&˜bÌ™bŒDl?Déÿ=ØìG~A1Æ=ñ«f°j—6UñÁó¡¬ÊöC¿™-ÁöCŒ Û1F"‰@µ+ÖÃ=ÏnòèþØ›â�G[Іr¿ózºdÊUŸE Éï{B¿ïʼn$˜"„ôÿlëý¸–àõ‚Yõ—gû!ÆŒí‡#‘„QûñÖgÿàû\ª÷eÀ*óC4³ì_‰K凸f{%˜b|Ù~ˆ1I0?Déÿ�×¼þЯ5Ö–tûñËæ4ÞO¶vʹ¶ G€Vƒ|‚yxòx=`£¸‰b¹º(óeVV¦¥ÁªôÕ9‘Ú¬J™ñè)�ÁªçÎ"1)Y:“2ߨ�'aiµóž››«ô;22RN!ÏKÑ�‘QQº3²êjDB˜ù!’­ UÊPøÞ3— E£æ‡\™”έÛóº×lö£  XɬºvË U°.iQS_ì„è(õsØ~X¯c¢ió‡ý+ï(±ýi‘ø÷@¶«6Ã]Ïx¬Þ~sCüçXuŸ]^OC¹©„×ÓbÞë‘6HÏØÕdÙ2‹ þòì‰1cHŒ‘H‚í‡!ý¿³ýpÅ,TíÇ;_ìÄûÓÿu£�ºxq¢ýVÙ~ˆyËöCŒ‘H‚í‡!ý¿³ý`û¡_k¬-ÁöCŒ'Û1F" ¶"„ôÿî°¼Ÿ¬;.ÚpÀjhÏ?�Þ �ißÀ½/l-ýËuWÖ“ÛéÂèܹ³ÈÏËCr¥Ê–CR`%=vWãLzšr}!«RplyyÈÈÊÌP‚ñd1¢ñúbŒV/ni¡BýÖ{ýGNNŽàêï̪Ì{Y¥´Yï?Û]ÚV“êóC &Ë…˜–C*¬�í‡"Xe?òò‹p×Ó›4ƒU[_X Ÿ¾Ü 11êYé™â¹²Z‚ù!FÔ*~ˆ[ò.Áü0‹ vùŸ~=Ž;ŸÞè!À«ê˜ñzš×ÓV³‘×Ó®ˆòûÞj ×Çþ�#ö‡Äy“àýXsøi•fûÁöÃ�«RЪóã‹€U¶bn³ýcÄö£ >¯0§/FKóúÃ(rÆË±ýcÇöCŒÛÿÚÞO6§£\:ôà€ÕЛs±ŸÏ=€{ž7°zöìÐÂ)))Ù2Œ}¬J�M§`ÕÂÂr¬JÙFsss�˜˜dæVUD µ*0¶  @©KoÐ)õƒÊè-gŽz˜V#ª^ŸfÐjTLy¶:µ©ê›ŽZa~¸Äüð½Z²ýcn•ý `ÕÛŸøÿ(É:çþ\|A¦½Úq±êÁªÌñ\Y-Áü#j?Ä-y—`~˜EÐ{ùÕ›Žcü“ž«ãnnˆ×9êx¼žæõ´•Œäõ¯¬Ô'#u±?$F�xzðh¦Î܃yËkh\?·n‚>Ýêˆ+5 Áþ�ÐLa~ˆäõ‚#‘„ç~³ oMûÇ¥)»V™¢™-¹‘ŽÏ+Ä8y“°‚æz`¬t(òcÕ†xÿë]ؾ댴êUbpûM)x]}ÄDGåí`ÿÊNtÕëE~è=·fûa^/Ù~˜Çн÷ý+ÞO¶c®1¸à€Õàž_�¾˜ww?W°ÚãòZxëq¹ «gΤ+Y/ããt´è]´°°P P”Íj´aê{aA�¥Ya�öEO9úŠª°°ÀRÌõ´ïM–‚KõfAõVé=z�w£Y­ÂÁQóÃjD½×w*-Ã&­Å¾ÃY.‚QQðÉK�Ðîâʾí�[kÌW@˜¾WG¶bÌ­²9¹Eÿ”v°j£z øúÍËP1^}–ù!ž+«%˜bD­â‡¸%ï̳ŠËÿòÛ Œ{âWÁñƒSð·Wb¼ž¶î–_¨¿ïÅ(óû^Œ‘H‚÷›Déÿ=P×Óû�d⿟ÿƒE?¥jª^Í8Œ½¹1ú][‘ÖÜìÄþ�~2[‚í‡A¶bŒDVÙ��¿Ýƒÿ|ü·KszÔÅ [‹º`èwæ‡6æ‡#‘„Uüµcõï¡Ä�üüB,ùå(>œ¹ÿî;'„²RR”òq“?O IDATÏ µnéÙ¢°qö¯Œ f®L(ñƒÏ»=u…ãA¼ó§¼ñƒ÷“ͽ¹tè!À«¡7çúæ_Hu½õN­×ä÷ ë_¨J·N1?˜|Þí�ß�ÌÍçæ¹ þ•c?Ù-ÞO6¯?\Cp"À«Á9¯<*|½ðÆ?µ¥´äÕ�jà½gÚ«ÖDÙÙ22Î)Áªzƒ½u��QÑѶ�Rútrð(HÔîÀXÑTè Ð%|Â#"¤ƒ[Em«ýž››« ë�×@ V%»VòC&p5"" ½¯ª�qƒ›€Öôð~“ˆ�ò¿³ý�ÇJFÒJ~ˆÚãý&Bž¿ÏY|O¼õ‡Ë{ÖÃó÷·R­Œù¡co%˜æñdÿJCìÇÒ‡ú”¹ùó¹{q*=W8Áã#0¬_ Fôoúÿ�æ‡>¡ó#°ø!œ0Ì`iˆ2?üÇ�M�ÆðIë<:ÀûÉæõškN8`58ç•Ge�Y?ƘÇ7—–ìÒ¦*>~¹SéÓ¦eÒ” °ÔÓϓɤH(ÚÞO6©4\<äà€Õ�›r°ß.>ŒÑ�•¬vl]Ÿ½ÒY/..V¾æ·:ØSÏ3ffŽm)XÕÎ ¥²ýÓãœØ�½”æ”*VLÔ=·4™€[Y\ŒÊù2¥¿Öf5óÃèìy–ó?žzû|ûãA—ÆcbÂñÁ3@ï=ÇÃüÐ7¯Ì}x‘ö?dûÅü(C*õx6F<¼‡Že©ÂGÁª¿Ø5«Uôø�퇬Ɖå˜bŒôH°¥-uÙ`Xlù; ·=°Öc€°ª>缞6Ï™ø}/ƒ’¼ ¿ïå±Ò’ †÷½y`•ö@Åëi|é*yÊv!]ƈ müÒ™U•ÍŸ¢"©@Oê·�}¦/ð²²2‘�PQw;�’Y•‚f#£¢tÛêÕ#rpssrïy�³Þºdå™Þ‘²ŠÍØ�7?ÛáÑØ [âšÎIÌ …e~H€d�Û @tªÂ*û±ÿH¦’yðô™<Õ6M©ˆ)Ï´F�êIÖÀKml?|c?´ZaÿJ^ÕÙ~ÈceFÒ¬ýøóŸt ¾�G& kŒîç€Uw`x=mF[ÅeÍ곸y ~ßËcÅï{y¬ÌH2?Ì çYÖªõ‚¨WjüصÿÞ›þ/¯NE±—}Øj•£1¼# éÝñ±á¢¦Jçõ¯¤•ECПü0ÛwQù`äÇÒ5©¸ïí€U¶"­Ð÷;óC^jÒ|ž§Ž¡¯ÖîLÇ”ov ? qô2©b$†÷KÁm}S�ïý¬—ùÁü0�€ùaWÿ©^æ‡ytÙ~?x?Ù¼>s ¡…¬†Ö|óh½ 0wY*†?²©T‚®›šþ楖cŒ›?Þ@"')#ã¢"£¤‚U-Ü­BºÖª ?±qqºš¢Ì°T6**JW9;„³³²m{°*mäææ >>ÁŽa¨ÖÉüðÔJCÓçïÇ ïýåÑèS÷´Ä�Þõ¥;Ãü�†Ê” óÃ|¦ ³ý(ƒpçÞ³ùèz¤ŸÍWŵy“D¼÷TKT¯–lwÙ ˜²HÙ#Çü�Ç•ý+y¬ŒJZµþøëß3¸yÂ/ݸoxc<¬ºÃëi£뽜UúlUïø}/�$¿ïå±2*Éü0Šœv¹@Ùo¢�ãÞÿê_,Xuç¿ÅWí4e4Ü»Föo„ÊÉÞ÷ëx½`½¾è©‘í‡Ë·ª-Éï{yù}/�•QIæ‡Qä´Ëâ~ÓÁÔ,|4sæ.;„‚픫Q‘Ч{Œ½¹ ê×òü@�× Ö닞Ù~È£ÅöC+ÉŸ7ÇOmtÔ«>&­Íç2JÊ¢ý�ìºPŒí‡"[ì´”É}ÙÚT|4sþÚ™.5ŽêUb0z`#Ü|}ÄDW�*Ãü�‚©\ñúÃúib~X�©¿jd~”!ÏûÉþÒBn·¼"À«åuæ¸ß–#0åQÜöPÙÆÅ$aÖ/·¬Z܆……DУeƒT”žž†¸¸ø€ÈJJW�þ*È-$�‡F ãððpCe­ÄštˆúAÿì|¨ VMLôí5ÎÌ;gÕ{Ý3Ø�gÞñÌ´zC×Úxå¡¶ðFæ‡ýóÆöÃ~Œ½µÀö£ �5›Oàžç6!7·H²¶Í“ñÖ俍æã`U¶þãóC{ö¯ä±2#iåúcÇž³p÷j�îÜ?¼1žã «¸ðzڌ檗µRŸÍöŽß÷òòû^+3’Ì3èy– ôý¦£'r0uÖ.|»ø òòÔ×"4ª°0 kçš=0í.®¬ ”×ÓÖêŠÞÚØ~È#ÆöC+YIÚøýñ_]Äûv¯�g'´âó Yr�n?Ì “í‡ôÌ—µË~äãûe‡ðÉœ=Ø{0Cª£ujÄbÌMM0°g=DF„I•qø |ž' WÀ òúÃÚ)bûa-žþ®�ùQ6¼Ÿìomäö˰ZÞfŒûk WÅ-–¬^Ô8³ÿw…%íQ@}]×É[2 ‰J22Î!&&Ò�+(ÁxÔ ¶µ;X•¾hËÍÍAR’ï®qf~†þÏ[~“_ÿÝ£3]ÚTÅ{Ïv@t”g°7óÃþ¹c~Ø�±]-?–­=Љ/mFa¡zf£Ž-+ãõ‡›¡jÕ’ƒa_<Ì_ lOÁÆJì_‰²æw«×;÷žE¿»TVG4Ás.²¦ÓAT ¯§­�L«õÙÚÞÉׯï{y¬ŒJ²?d9ÿ—c~蟃“i¹øtö|³`?²sÕo|pÔJ7? ë[Ý»Ô@LL”þÆÊi ¶ÖNïÇZ‹§¯kûuë)Œ|t½K³ƒ®«‡çîkåë®XÚÛKáT­Œý+û1¶«-~œË,ÀŒ…ûñż½8q:Wªùµã1vpôë^ááò�ªT9Û)ˆË�ûWÖNóÃZ<ý]óÃux?ÙßÉí—78`µ¼Í÷×6~øé(†[×;ùšø}/�•QI^/EÎÿå˜ææ ýl>¦}·Óçï x{êֈð~)  µØÏ‹x?ÖÜ\ØQšùaª®u†Šýøí¯Ó6i�ËàoîUÏLhi?È6µÀü° X§jC…ÎHóúƒ‚S?›³³@F–wŸÁ�I“1np\Um¯7Ïii£¯‚ñx¿Éþ÷¯Ï­Ç˜ùðúÃz½2[£•þï'›� .jpÀj¨Í8�W�~>†!Ë®ˆ¡EÉ÷\i 1JiOÁ111¦ê)O… ”L ô¯›6æ‡Ï ÖÕÐâÕ©xèÕ-YëÕŠÃç¯uA�ª1Ê•zÌ]°êf~è†,` ?>üfÞšö�&¾Ý»TÅó.Drr’Ïæ€ùá3¨-o(Øø!ˆý+BÖün×úc÷� Ü8þ'�N>0ª ž¹‡VÝ�áõt`ë³5½“¯…ß÷òX•dÈ(rþ/Çü°nÎf`ú÷{ñùܽ  VoOb|nº¾†÷KAµÊÞ“ X×CßÕd—?ä»”´Äü°ñP²¿ïHí׺€:øúúxúÞò°Êü`~Ø�@°Ú�½30uÖn,Xyùê·E¹ãI·nŽÒ×^V aúª–VÅçyvh©ÿê V~ø Q懿�·§]æ‡:®¼Ÿl�¾q­Á‹¬ïÜòÈt"ðãêc¸ùþ²€Õ”z XøáU:k)§ „°°0DF–e$4\ô)¡¸ùáÓÀjæ‡OUZwc«7ǽÏý†¼ü"—²U+EcÊsíЬQrHs3?t«PÈ6ûñÂ{aúüýšóÙ§kM<3áb¶!«ñúlü�ž‚UÙ~ˆP ìß逫÷8X•�%^OË"ürü¾·Žy=m?ÆvµÀü°Ù¬ìB|³p?>�½§Ò½_ó†ÞWÕÆ˜›ƒ’ð80?쟋P³îLÇàûÖ¸[^V™Ìû(¿-8ócÓ_§ñÉ·{°jÃ1éµ¾°ÆiŒ«;Õ�.£&èË`<Þo25U!U˜í‡ýÓjþ•ýˆú®;øÁûɾ›?n)8à€Õà˜G…,þå8nºoCiM ëÄ㇩WªÙW C�ãB^°2í»¨éË$ x÷¼®ÌL½Îe‹‹‹‘••‰èè%[¦¯懯�6×]›5ö‰ ÈÍu Z�� ÇG/uB› +™kÀDiæ‡ ð¸¨m“ý(.ãwÌ]vX¯[z×Åä;.fûa›FWÅÁÄÑ̰%B¨üü¾ïp&®»Ê£Ã޾Oß}aùˆ�zÊëiàÍðûÞþ âõ´ýÛÕóÃ.dËêÍÈÈżåGðÙw{qøX¶°Á.mªbÔ F¸ü’jBY°懽øRí¡h?vì9‹w¯vwpïúxúžò•a•ùÁü°�òÛBÉ»-+7Çdzö`ëŽ4éÁ�0vpcÐÿš}ø¼Â,‚\ÞØ~Ø�ªk�¡è_Ù�ªoZ°‹¼Ÿì›ùãV‚X ž¹ä‘˜D`éÚãxoYÀ*]½ø“®ºkµãk Ý�à†”ôõä$Q°ªÝA¤ÙYYˆŽ‰ñi¦Læ‡!Õô[¡­§áö'~EFV�K¢"+à�ÇÚ¢[çš>ïóÃç�sƒ“ý(((Æ„~óš‰`ÜÍ 1aÄEl?$tƒE€`â‡Ì|²%ƒRù�ÙŸš…^£Wztö¡Ñà)XõÀ…×ÓåC¯íì%¿ïíD·¤n^OÛ�±]-0?ìB¶¬^g~㇟Ž(Wÿ»ïœ°qÊ´:b@#ôéV‘ï¶ÂZ0?ì×�PµÄÿ¾wþìpy Xe~0?ìG ü¶�•�‡+èC•} !™', èÞ¥& š7I’)"”áó !D,àØ~Øz¨úWö#k vòƒ÷“íŸ?n!¸à€ÕàšO� –­;�÷¬/­¡N�X,ý¬›®É9‰ŠŠÒU†…�ÂÂB[³™ÊŽ’·ôDFFÊÑ-WTT¯�m¨uŠù¡{ª¢Àνg1lÒ:œËt Z¥Î=uOK é]ßgýd~ø jnHÁd?rr 1î©�Øôç)M&�m†Q›è@ȼ(Ûóú«†`â‡Cö¯D•¿ß¦f¡§JÀê¤1àÉ»8êûŒòzºü鸕=æ÷½•hª×Åþ�ýÛÕóÃ.dËêõÆ�•Žáã™»±y»8ãZÕJѸ­OC îÝÉíÛ—³‘òÓóÃþ¹ eû¡v%ky Xe~0?ìG |¶@çӿ߃¯æÀÉ´\©ADD„áÆ®u0ö¦ÆH©— UFFˆÏ+dPb_#ÀöÃ~ÄCÙ¿²]{[°›¼ŸlïüqíÁ‡¬ßœòˆ "°|Ý ôw X­U=˧ɬÚmà ‹‹I @sW¡B%«©?_,ni|PAãõåÃüð%ÚÖ¶Es·÷PF>²§ÏäyT>¼_ ×vÓ‡ùaí¼rmÖ Lö#íLÆ<¶težÖóÜý-1¨§ï‚Ô©l?¬ÑUÔLü�Á�ý+”Ê— ]%|íÈ�~xlS9@›à÷½ýÃþ�ýÛÕóÃ.dËê•åǦ¿NcêÌÝøyãqa§bbÂÑ·{ ï›biP‹°á`~Ø?á²ü°¿'þiá@j®sûmÈ ðÔÝ-üÓ!­2?t€eP4Ôùa6¿£5ú´ïö`ÎâƒÈÊ)”ê ÙôA=ëaôÀƨY-FªŒ¬ŸWÈ"År¾D€í‡ýh³ý°c»Zð?x?Ù®ÙãzƒX Ö™åqéF`å†è{WY†ÕêUb°êËîRõÈ:'þ8È–@ ùÂ9‘�—·ÅÅÅA™¡—ù!£�)ãÌ�CG³pÛƒkqâ´çWË];×Ä“Û":Êž@hæ‡ÍS+§WÁd?ŽÏÆðIë@ÿ«ö„‡‡áõGÚ¢çµ|:l?| ·¥�?,ÆÂʘ‚©QUêñltÁ«²HózZ©à’ã÷½ýóÉï{û1¶«æ‡]È–Õk„t‹Ì‡3vãÇÕGPT$îãí«cX¿†¸ü’jba–�F€ù! •aA#ü0ÜX€TóçËCÀ*óÃ~…b~Ø�±•-ü¹3SgîÁòu©R¶›ÚNLˆÄ­76%ÛHN´>k:ŸWðy…•:nU]l?¬BR»¶öclW ¾âï'Û5ƒ\o°"À«Á:³<.ݬúõ$úܹ®´]õóôk„õÈ:'¾2„³@)�2'´¸¥`æèèè ›æGù�R5~�£=âáõ8t,Ëc`m.¬„÷žë`ùµyÌ�’ “��ºüj³õ=”9±‚”Q•2«R†Uµ'*²ÞyêÐA­/¶¾DÛÚ¶‚‰Ö"c]mÌë°ôVÓ±“9è:l¹‡È#·7Åãwp†Uw`x=í½ ¤Vø}oÿlðûÞ~Œíj�ùa²eõšå]ÕøÉ·»ñݲCÈËG®6®Ÿ€aýRЧkP¶6~Œ#Àü0Ž�lI³ü�m'Ð原ÎÅÕ·-séæ-76À“wn†Uæ‡ýZÅü°c+Z �J–®IÅ´9{ñûŽ4é*«UŽÆˆþ�0¤wÄÅÚc¯­Ø�•��™>ÜÂæØ~X¦FU¡þø IDATÌû1¶«_òƒ÷“íšE®7Xà€Õ`�Y—n~Þx7ÜQ°Z)) k¾¹Ök=²ÎIAA�läëkØuƒB|éœxƒ•tƒúÊÁªÌ�À#ž7~œNÏÈGÖa÷� �Ž×«‡�^ì„úµâ,ó`~X¢J–VLöcÓŸ§0î©�ÈѸF+>6S^è„vÍ+YŠ¡¨2ö¯DîïÁÄ�@E™ùá»™Q;à¦Ö×��ç€U÷™àõ´ït3Zâ÷½ý³Àï{û1¶«æ‡]È–Õk%?N¦åbÚw{1cá~dd;ŸT17___ÉÚV£ŠµW æ‡ý“h%?ìï­½-Ї¹— YêÒÈm}âñ;/¶·aƒµ3? §£óCX~ÍÎ)ĬEðå¼}ªI3´ºEç£ojŒ¾ÝëÚv µÍç|^á'jxm–í‡ý³ÂöÃ~ŒíjÁ×üàýd»f’ë V8`5Xg–Ç¥�Õ›N¡÷øµ¥å蚈µ3zhÖC “ˆˆa;”93,,LùÇ��ââbÐ?;ƒ{}íœh�:˜·Ì±®‘~œÍ,Àø'~ÅV•¯›éð†‚V[\�ddˆ¥e˜%×ê°ý�W£@á‡|��KZÁ�Å«S1éµ-(((VíùAŸ½ÒMS*ï¨�’l? €&Q„ù!R9a~Ø3IZü –+ouÍÈD=˜<¾&�kjOgÊq­¼žŒÉã÷}`̃Ù^ðûÞ,‚êå™öàêëZíâís|3>Ÿ»§5nŸpkxxz^^ #¤ eÓd_Ã`y{ÌË!õK…vñÃ/ƒ± QâuçA‹]jÚ·!»C_À*óÂÉ€*˜öL‚Uü8v*_ÌÝ‹oqWöi–’ˆ±77F¯+k£BÙRÆä¬Ø�5Ö²ý¥˜ö`l?¼õŽÏ»í™;çZ™ö`¬üàýd{ô…k ^8`5xç–G¦�_~;…ëÇ•¬&ÆG`ý·=Uk¡ ";*uv]Uœ }y ’õ…s(`äàÒ¿˜˜àËÆÀü°‚Ážu?rr‹p×Ó±~ëI�ÎFEUÀ“Û¢[皆À`~‚ͲBl?Ô¡ &ûñÍÂxîjêLÍj1øôÕ.h`Q¶dYådû!‹”>¹@³úz¯Oší‡>¼¬–6ûAYå/¿Å5#aÆ«êšÃëi«¥¿>~ßëÇ,K°?dϬ0?ìÁÕ×µú‚¹yE˜»ì>›½û�dJ ±Í…•0¬_ z\^S –áýXOØ‚i=-¥~ò?ÌË×ë…¬ìB´ð£K·‡÷KÁ£ã›K…í‡4T-Èü°gz¬àÇνgñÑÌÝXüKªæGõj½ïÔº*FJÁí«Û38·Zy¿É'0k6âkûaÅh­à‡¨ì_‰2ÿ;ÛóªÕÌüàýd{t†k ^8`5xç–G¦�µ[N㺱kJKÑ5¸ç\çQKypNå‹*=S@¸Òcg p 8ï4?ùyyˆ‰�Õ‘ª,9uôÊf8óÃô”ªV¨ü ÌŒ÷½¸+×Uí÷S÷´Ä�Þõu�ÂüЗåÂl?Ô! &ûñê‡Û•+/µž”z øì•ΨV9ÚrýòV!Û{àTûaÇhÙ~Ø�ª|�Áh?ÒÏäáR·+D ‘ÇÆ7ãœaÕC9x=-Ï;$ù}o U^OëÇ-ß÷úQð,LëÇèB�´Ý¶lm*>žµü“.¥&5«ÆàÖ> póõ A‰ÊÃÃöÃØ,…:?Œ æû‘—_„6}¹twD¿<"°Êü02ÓPnÏ£‡Ï+äñó?ä{§½WJ¿9Ï#Y¹á(¦}·ÿ8%Ýú(¤çµ0~p4MI”.gV�÷›Ì"h®|¨ñC-^È"e\ŽÏ+Œcç­d°ûW¼Ÿl�Þp­Á‹¬ïÜòÈt"°nËiôt X��Ços=VuVësqúÒ�‰FŠ>ïìùÉ9¡�ŒððpÛº(Ž%-®òrsgÛX¹bm˜ÚLFß´Áôä[[1gÉ!ÕʇõmˆGÆ],u%óÿìe~XÏ+gÔ,?è æ‘ÿÛ‚Å«ÕÌ©¯-›%ã£;•›ÃU+ñÕÅün~ˆæŸ÷Ž@°ò#ý\>.½y‰Çà¿£¹½)«…¼žöŸJðzÚ؇ZËÁú¾7;�¼ßdÁÀ/¿é¯ÓøäÛ=Xµá˜TgcbÂÑ·{ ï›ú 0P¶�:3Á×/Ú�潺:r@#<|ûEB�™BˆXÀ"üÉ£C0Ê�œœBÌ]~Ÿ·ûËe1§>’]ím]ŒØuj˜O£gÜf÷cõ´Å²ž„?ôÌ?¯?ô ¼²Ì�À<¯pì'",¬,î…÷“ƒ—‹<2spÀª9ü¸t!°~kzŒþ¥tDt¥õïóz•«æçç+AŸFÏü1XZðÑ*Áªz2«Ê¢ÃzaG›Ì{�÷W¦lÇçsÕ³6^vI5¼óÄ%Êæ’Ö£÷Ke懵,a~ØË³³e–ç2 0þ‰_ñûŽ4Í®\Ú®þ÷T{ÄDW0ÛÝ +Ïün~�Âúx@ÁÌ�³™è¯½]õýn7?ôõFNZ¯ýø{÷YÐyÁ’5©(�üЃzB6sdÿFг¢£üóa=ï7ñ~“+ʤôòCoýy_Ùpoýc~0?ôêo(ñã̹\t¾éG„…¹®ùx?Y¯Ö°|¨ À«¡2Óà€Õò1OÜK ðÛ¶tt¾Ú¥¥í‹Œ¬BÚqÀf¨ :à!|¢¢¢ •/O…È£ÀSÊv'ó6vfœ¥ú©?ëχù¡�~0ðcÙÚ£xàåͪ_NÇÄ„ã�GÛâêN5”Í懧.0?‚›²ï^³üØôç)ÜùôFdfj69axSÜq‹\–@¶²3ç?¹`°²è™å‡l;²rÌY¤ü'g„99…h×ß3`õ©»/ÄC£åÞ�þ±ï[æõ´ï07¢Ï¾ë�µ-ñû^O^/ðz�`~?ò Š1Åa|:{7vÈ�~viS·õmˆ«;ÖðI`ÛïïÞ�•VÝ€NJˆ”.§G�í‡6Z¼^УI�#kWÀjÿkëâÅZÎ@-î Û�ÀµOµeÕ‰ìÇ�Ô,|6gæ-=„ì\í�æÝ;†ÞWÕÆ¸ÁMü’q\ æóC/qDüÐ[_ Ë3?˜zõ3Tù‘›W„¶}y?Y¯¾°|è"À«¡;÷ÙŒšU�aCŽ111A3&­�èuÞsssm.´ùJÁªkÕCY]¨Nú'û0?´‘ F~ìÜKב¯Çé3yª§«ÈŸ¹·•f&ºBè�/vbËß§qy»êÖ/1ÑrÙŠeu’ä˜zÐò�l0òCÖ~¼üÁ6|1o_©ø´W;£C«*¥ÿín?¦|³ oOûGs¢¢¢*à�'/e/�y˜2(ùW&”ù!Bžý+BÁÿ»~£Õ�?x€ôÌ=á�QM‚<�#äõ´NÀ ˆ›ÑgÍùµ¯§Õáçõth­§e× "²²?$BÈžßÿÜ™ŽOgïÁ’_RQT$×ÝHÓ§kŒèŸbiðÛmü™rº¨Ro|ºSgî¶´{޹c5²´Î@©Œý+ö¯ôê¢7ûñËo'ðå¼}øyãq]ÕVŒ�Àͽêch¿Ô¨8ç„Ìæ‡.EÀþûW¼>çõ9!àn?x?YïÛ”åCX u àñ—"ð׿gqé�Ÿ\Ù<·WIpÅã‹Á¢ Ê^ÉÁªžX)Î{Abb=3É‘-_äœèÉbš““ck/éeqq±­±23Äü8ïAÊ�ÃDz1ò‘u ÿU{:¶®‚÷žî€¸Øp�ŸiÓ™6ŸO› +aú›—ʨ›´ óC*¿ †²ý  ï~w¹~LS³Z ~øðjÐa¦³ý CÐÇßøó–Öœ«¤Š‘øèÅNhqA’Ô|2?¤`ò«P(óC<ûW"„‚ÿw³ü ÷j‹Þ =€zöÞ‹0q$¬ºÃëi{9eVŸíí�µµózZO^O‡æzÚ}ÔÌ�òÇ�£'r”Ìs³@f¶|æ9Ú+Ö§!ºv®©ù‘¯ÌÛ—í‡6J¼^�Ñ À—¹ï…ÍXº&Õ¥£•’¢ðñK�@ÂßõôF?•ƒbJ¸\Ù¾jV�ÅæmiØsðœK¹‘aü-MlËtìO4Ù~”?ûáO}¡¶Õìe�›·ü�¨ºk¿+Dý¥£†õOÁ žõ¯r *oçïÌæ‡^ýbÿŠý+^ŸóúœP³¼Ÿ¬÷�Êò¡Ž¬†ºðøKؾë:^å‚Èoß]‡Ø˜paÀ*ešÌÊÊDllœîëÑCa BÉy§ ²”aWöÉÉζ5ˆ—œfÒOfµe~x׆PàÇéô<Œš¼ÿîSßÈJ©—€Ÿïˆ:5\Úûܱ »ögº8õ¥Ž¸´m5YŠy•c~X£­•„?ªÙ�CG³ÐcÔJŒ)ãÎ}ÃRJíGNN!îxf#~ÝzJs>jT�Á´×º ~­8©9c~HÁäW¡Pç‡7ðÙ¿ò«jDãVñ£y/X•�P^OË"¥_Î*}Öß²ïKðzÚs^OózÚÛz�ý¡ò³{.³3À—óöâØÉé,øÜrC êU_wÛm˜y½ ­‚/ø÷î³xÏj�~Ròo·‚Η†ÅF‡cý·=KnÛ ²‡ý+ö¯ôª´»ý8q:_}¿3íGúÙ|]Õµhš ïyyM„‡¿˜Ì] ­Ì­·Žò"Ïü`~èÕU^” ÆûÉz5‡åCX åÙç±» °cÏ9t¼É5`õ×Ù=‘á5`•6?Τ§¡bb’®@Å@†ŸD¬ÊÈ×"X9N#ó™�•…Ø8¹À!#õÓµVE……¶¶!êóÃ;B¡ÄÊ$2þ‰ ؼ=M”Ä„H¼ÿ\´½¨’òûÚM©ÿÌ%‚ó3ó¿—Kg‡ô†>óCÄ^c¿[ù^ %~h¡ýÚG+ÙxÔN¥åbÌã¿bçÞ³š“Ö¤AE|òr'T­-5±Ì)˜t 1?tCf¨ûW†`ó{¡@å‡Úãs.Âý#8ê»Òðzº ‘@Õg«‰nå8�ô�ß÷FPó+õ†× ÚóÉüð¿®kõ€®ˆ\ôóe�G�v²OTTô¾º6†öIÁE�…ŘÌ�P:¯p÷jìØãÊ'÷€Tg� ßè:=ç€Ö+ÚWÇ”ç;¹e·€•vÒH_Ù~AÍÿe¬ÔgûAûø_}¿K×Ù/=O·N50rP#´oQYO1¯²VŽÓH§˜FPó+õ†ý+ö¯BÉ¿ÒË^æGb¼Ÿ¬W{X>”à€ÕPž}» ;÷e ý@×,fëfõ(ùz�>üÓX��9“Žøø]WÀ»Co¥ÃlvZõ^á­=ª‹Æe¶[–—÷7æY™™ˆ‹�·|\Ž )ب  _ÑM>ÌmôC‘yùE¸ÿÅÍXµá˜*0ô•õ³Z¡e“Œxl ÒÏäyÈѵxŸ¾ÜÙ% ‚^g~èELNží‡N²RtÍV§A‹A¼Q{š¥$âÕIm0îÉ_•ëí´ž6VÂG/u’¾n‹ù!;Cúä˜úð2*Íþ•[©Šþ~‡ðû^~6ý=Wåå}/�¨XÒߘ3?Äsä�ð÷\­ÿý$>›³?o<.ßi-›%㖢וµUÁ£l(î7ÉÈü�E Êž¾U -ä[U—ùW›·¥aèCk= k­ªýý‘ñÍ1¢_ŠÙ®š*ïoÌ™òÓçï¹²Ó¿ÊÉ-À²u§”@Õmÿž‘@ttôíV£5BƒÚÖž}ùs懼*ø{®ìäŸw«ëóƒùÁëWàýdyN°$#À«¬ŒÀyþÝŸ‰K¬pÁcíŒHNÔX¥ ŽˆˆS™UÉy§¯_"##-Ñ º*€ÆfU}–tê|%z¯1°²mÊ8J×NÙ�Y5‚U™ÚšÊü MáÇßøs—VˆbBb#�™]  ऱaÔÀF†¨(ÁxÌæ‡H�§|³ oOûÇ«XDx ܲ;èÚ¹&Þ|¬-¢"=1Õ*f~ˆfÅØïì_ÃMO)ö¯ô X‡Ï�Î�–7üà‘íýùûšã>XõP:^O�®ÏúÞÞ}µððp«ªÓU¿ïuÁPÁFÌ}sgDšù¡µ@Ú�ýwo:>ŸwóWÖü`QmtÉIQØ£†ôn€:5b‘PÞoò¦Ì�òËYûÑuØ2;™ë2PÚct¿€œt�çìªôßóÞ¿4¬¨( ¥ù¼ÂB0½Tlû±k~;†]³ÐûªÚÒ·*iÁsìD¦/Ø�Ù‹á´J o3T9) ·ÞØ·ÞÐd›¬~˜V#ª^_°ñCÖ~È Ëþ•:Jì_ÉhO™L ­?˜úæN¯4í'¹ø›¼Ÿ¬E–8`5TfšÇ)D`÷ÁL´íç°úË××¢rr”’ÉÏ=³ŽYcNŽ =�ò¥2-F¢£å® �Ic£ÌH9ÏÔ/®åæä &¶dÙŽ‡æ1?? þÛ`£q1?´g—ùQ‚ âQ@žóS²i&Ìž†Ùï\¡{#™ùaÇ[`ûa®,ö¸íh•xã~ÐB¿ èQ/Ll-Ý9æ‡4Tº™ºà2$L`ÿJ:^Èáä,Õê†E((tÍtýÂýÍ1agXuG“×Ó¼žÖÏ0}%ø}/�¿ïå±²J’÷›¬BR\O0ï7�NÏÃWó÷áë…ûUoœÑB‡ö­¯êXƒ{×Ã¥mª 2Rß~lú¹|<õÖØ´í4úv­ƒ~=ê‚nô°êa~X…¤¸ž`æ‡hô_Î݇—¦lósϦªÄZ½J V}Ù]Ô„-¿3?l�UµÒ`ãÇëoÇ'ßîUÆZ»z,(ÁCÏ+jétó¶Óøòû}Xºæ¨ÇÇš¢ÊRê%`dÿôé^W5ã·¨¼èwæ‡!ë~6~ð~¬uº¡U¯Ïå1æõ¹-ú¬ V'-ÂòòrQ±¢u›ÊFÅüðŽó£ ŸÙKáÉ7·*PòS†WüÔIÀ©ô\ddæ»üpQãDÌ|ûr„‡»çJPÇŸùa„Íâ2l?Ä‘˜öÝ^¼úáv�¢OÜݯMÙŽ¼‚²à)5îÜ?¢Æ i"Ý4óC*]‚Ì]pfÿJ6^Ècå,ÙºÏ"äçsÀª z¼žæõ´Œž•á÷½S¡Â-�(0µu (É êxœVÏ'ï‘uuÈ ðÔÝ-Láo¤0óÃjÆÊ?Îedcà½ëqèhV) q1áXùå5¨/þh!/¿ VÁôùû°}×Ý vhU#¤àêŽ5„‰'tW~¾óÃ(rúË?x?V¿è-ÁësyÄx}.�•U’�`?ÚôY€‚B×›‰8`Õªæz‚ X ¶åñFà@j6Z̥ܰüÊ/º£FÕTŠ\÷: ·c•sbvá@ ;ïVŒ“ê ¯iü•YÕª9÷¦tl”››ƒÄÄ$ú­ÂÊ ½!<˜ökÅòµ©˜øòäçS–H×öŠŠŠ^…´£¬’ErâÈ qû`q†3æ‡;®E–| Àü°�.AF–k�6Ñ 91”ýÆóJ»’{î"#ÂðÆäv¸æÒšÒ�c~0?¤•ÅM�ý+£Èù¾ûWú0wö#Ûö]„Ü<×€Õ'6ǽCÅþ‡¾VË¿4¯§+X2‰VÜfźˆß÷–L­O*á÷½>˜™rxñzÁëZ®ÜpŸÎÞ‹ßþ:-7a祢£+(WDßÖ'ôÁ¯ÖCm\6d ÒϺ®?¿~óR´¾°’®6Ý…Ù~˜‚ϧ…ƒÅ~L|q3ÿR|M :ŽthÅ=Ûªäžë€+;T—Æœí‡Tl?ì³�¿õ7ýtÄc"Þyêt'xât.¾ú~fýxigòä&ò¼%�èyy-ŒÔÍ›hŸA1?ä`e~ØÇ�@NÎÄü`~È!Àü0‚• ”õGÇ�Ë�ë–�÷“�Î*— v8`5Øg˜Ç'�À¡£ÙhÞÛ5`uù´n¨U=Ö²€U«6è‹®ÿ­PÁÜ¡XNv6"£¢, ä´úp­  â/B½Mr |Icw°,-nsr²‘””,­ï�(ÈüÐ7+ÁÂ�Ìì ºw ¦–}®l(+Éè‹�Me Λ÷ÁUhX'^<æ‡+4l?äyæ/ûñé·{ðÿíÑQÇÁŠ’„âSÝ¢V£"ÃðÉË�ÑîâÊÒƒd~0?¤•ÅMÐ_üptÛOÌæ!Юß�ÈÉ-tã¥.Æ=·52JŸ -ÇëióSËëiO ù}/¯W¼ž–ÇŠ$ƒe=ÍûMró ü  xŸÍÙƒW§zd�¡@�§·ÜØ×]Q Q‘ž{Éw?½ +=æR eê{ýѶ¸ºS Qõª¿ózÁl~) üpwâT.®ºLõ#_eE%b•ö7ιN•jÂöCNMy=mßzúù÷w⻥‡T'‚ÞõOÞå™-˜>zøjþ>,]s……ú2ó$ÆG`P¯úÚ'5«ÅxUæóCûøÁçÝFf@¾ ¯ÏõaeÅM»|ž§sÒQ³q%ò-ºJ:óƒ÷“�¢ÈåBX ÅYç1«"päx.ìµÔå·%ŸvEÝšq¯º&ÖÑ�"m"“caÖPRô˜Íje°ªUcs5??_Á4SòÛ IDATŠs�>„õÍ,æFÛ/ ¸+6Xì­}ÚüÉÎÎR‚UÍ`etŒV•³J‡˜ò3ü /¹Ç?µÛþu½zˆ¶Í”`U'ú—\{NYX]ß ­š%ãë7/S½~ˆùá¹ùÃöCŽ#þâmwºi ²² \:ê¤ZD\ ÿs¢e:˜õßËqa#íì9Ε2?˜rlð”ò?=aÿJ~æØ¿’ÇŠ$ÕÖíûÿˆ¬×€Õ—¼wßÊ«îèòzZŸ¾9K[ÅU^OëŸö‡ØÒ¯5%%Ø2ŠœïËYõŽ ”ý&Gv¼™‹ö{dE¡[)) ƒ®«‡!×7P4Ðs6³× _ŽŒ,×5¨£®F]ˆ±7ëË,ÏüÍDàülü d{ßþöÊPÙS¡�E×}êÚ±Þ}¶½Ô¤ðy…L`ÿÊ>ÿjÊÌý˜òÍn͉ ¤?L½Zù�n Y°ê¦¿ï>+7yNR jÇch߆Уbc\¯5V«Œù!1óÃ>~X¬j•mäõ¹'œ¥˜ÌýZ˜ësÞO6:“\.à€ÕPœu³*GOæ¢iÏ%.¿-ú¤+ÔŠ3�aÕª¯Êé EzÌ`Z¬Jc£Åhtt´ešENidd¤©@OoŽZ†—ŠÎ{r²¹+º|ÑWom0?ôÍ@°ðãÐÑ,Œ}l¸eV¥l9yEJ žçµçž«„Þ£ãšcxÿ ™®zÅöCžgþ´ÿý|'>øú_�κ'¡ÿ.9jqÍ´Z¯ff¿{â¼g'g~0?äá¹QæÏ��Œö[O9æóÃ�ƒ²Á;?¯lWI®ªLƳZâ¦^õ…,û±Â�š`ûaŸýøjáa¼þñ?ûåîS6ý�K±|íQÌ^zégòtÏh§ÖU1¬_CtíTC5A„Z…Ì9˜™öñê`U^ŸËé²RÌæ‡Q½ Äõï'�M.ŠpÀj(Î:�YúB½ñµ®«ô5"}•HYþŠôÝ”QÚêçåå™è¤`#ª‹9Í<999Jf3´RÈyÏÍÉAl\œ™.¹”%§”rÍôϪÀ,çŽö�”Á”æ1‡2«&W ¨~éUæ‡>Ä‚…ÿì=‹Q“7xlš]а"&ßÙc'¯G‘ÊK·$ˤ'£¢*`þW¡^­’wóÃsqËöCŽkþ´9¹Eè4h1ò \Sº»gWuŒ„þ^§f,ŽËv\·N5p×РШnbT2 0?˜rlð”ò'?ŒöYo9æóÃ]g: Z‚ÌÌ|—?¿úP Üy‹ë‡2zu-åy=­Vy=­3«Jðûžß÷Fu‰ý!£Èù¾\(í7­ÞtÓ¾Û‡µ›OèZÏ^g‹¦Éxç©KP£ŠöuÐÌ]ðûU8˜ù‘›WˆŽ´·’/w˜³òËî^õš&*XöcíV:ö¯ìó¯¾[–Šçþ·]:€Tï\S‰ÞWׯˆþ)hš"ws“£ æ‡ÚÌûøÁçÝr:è,¥ÇÔ_»þÌæ‡~­))¨ëÞO6:£\.à€ÕPœu³*§Òó�Ò}±Ëo >¼ �ê%˜ XÍÎÊ2ÐILÉ�ŒŠŠ25{VfV¥/Vrr²Ÿ`ªOÎ…É)¥`U3d­ ìuwÞé¿%`•pÊÎÊDr¥ÊÓ'£JÀü�G.Xø±íß3ñð:�ëu+'EáÉ»[àÍOÿÁ�ÔLM`Y%ݺv®‰wŸ¾D Ve~”¡ÃöCžcþ¶¯MÝ�O¿Ý­’Dûƒ ºž« °‡Ý‚ViÔ_�„oÞ¼ ááe¹Š™®úÀü(?ü�ï©qIæóCM{èC‚s™®V_›Ôw á€Uw¼þŸ½ë€“¤*Þ5y6‡KDáÈ9çœEA’ "QDQDà�‚ "¢‚¨¨dAÉIÉé¸# äp\ܼ;¹ÿ¿êžÔ;=Ó¯_‡é™ùZ—½�yñ{U¯«ª¿®ÚÚþÚ^N–Æ~�ý^Vžêí/ÈŽÛJ=èGcëÇü£tí�н�J©”þEH#90Н°ùƼ!CRÇmþò‹­iãu{+šƒ~XÑ´ú—möxì~�îyìSSrßöÓ�¿Ý¾æ‚4K<Öm©ÃýýûÇíN^ù–á®4½�VY±�澺¬ø½"ïë‡ï¿¹ÿêÔßkýÙ#ôCL³ îé‡S™U់ɲ¥ ÐY¹ò³ÿ�x²ìª¢^+"Âj+®:ælˆÀò¡4­¾ÇƒºïîùË.Äÿd3¬Ž��Q{G‡-Ä™LÁÆr<^ý v‘œ$«²P «:Eâäñ…Âa[dÝ0N[+N¾ÈZØ)ÃÆûøØ(õõOix²*ôC\šI?ö;n}ôY Bê¤|T]ùÅúÈ¡OþœË\sá–´ÎÂÐ�<`¸ˆëX½ïË’´ûÑ�Q&«W€jí½‰uaÆÔ8-^–0œì%gm®fHà ÷�Êàì+1©·~ˆ�Ò^)èô£šm÷õ‡ixTŸaõ’37¢“au2fð§Å÷!øÓâX9]û=ö{Y™‚=$‹\}êµz¼‰�€¾ù��é_ÿþ�8ºÑet‚Mát>Ù¦ZÜ%Ð/¸)}e�•‹ÍB?ê#ç²½¶‚~üïƒúÚwç˜Vuú¦tÐÞ«T…²™â±²ò"Rö•{öÕ=�/¢Ÿ_ñ&M �«öqÞ±ƒ“åü�Qì¼0R΢úÍV§ý÷X™8»ªÌýC úáž~8EV….&Ën”‚~@?dåÊïþâɲ+‹z­ˆ«­¸ê˜³!ƒ#iúÂnzÂê]Þ™Ö�Ù-EXåàO¼­�‚A9‡�Éd£L:m;C«o:@ã11Yµ«ËÚÑ µÄŽßê†B‹Å¤¥“ÇÅÿЬWÁxç̪väÊø@?ÄW¡ÙôãàSçÐÛï  Ò÷òÿ)ä«‘ø6\«“n¹lgèîÂòU¸×Öûþñ“ß¿Jw>üIEzò …`ta‚f/�|ÿ˜uéäÃ×*’UqÿÐ�ƒ}%®"°¯Ä±òCIØWâ« j_mèÃ44¢'¬þö¬�éÄCWï¬EJŸ[høÓb8¹Q þ´UØCâR{H+?”„=TZ…tF¡ûŸüŒn¸ëƒŠ8Ìd2ÿÍþg�³6ä_Þ¯FZåï¿õµ5èŒãÖ§lñX?ȽèZI?¾øíY5Opj‹…è™[÷¡XÔøÙ�¨¿P {Ü?D%Óåü¦÷>±ˆ~~ù†àäó9¨qÄÂËåÕj XvÛv}àê´ýfSm�ýƒþü1I©,…û‡,rõ©ç·û‡Ý“l ("~%/Oˆ'Ëc‡š­‡«­·æ˜q†G3´Ê®è¾½ãŠ�iý5­VùíÂh,f‹4ņ@*•¤ŽŽNé5Ëår”L$ˆß4cÅîÅ™È&&Æ©³³ËnSÅúìÜ2á†É½²W*•RÛhv²êØèˆš9²ÑɪÐqIoFýøÎÏ^ 'ç.¡¬d‰¬àç&†o—ÿñÜ-iÏV�jß• â«Ð,úñÉçã´÷±O�U+±¨•aréiý1ºòümhæÊQÂý£„ì+qƒ}%Ž•Jâþ!¾ Vî;ö §t�_zÖÆt«€ÃŸ6—AøÓæ¹U‚Â=$#_°‡dP«_ØCÕ±ñõetÝ]ÒÏ}N¹—St'7U#<Õ"­î¹ý ºøÇ›P{›õc¤ë'%ÖzÆýC�W#ùÓ×ß=Ÿ.¾òͪi&ûÒègßÛØP ¬ø Õ$ ÷kºVïÒ~»Üþð"ºèÊ· ƒß“3dïß%Ñgrö{¯BÇ4“V[ÉÞi�¼NÐ1iÅý£qïb+l\ ú!†ôú!&)•¥žBÏ{`Î ýâŠ7 ÷]#r*�$Dz'½å¾Â´8¶ß*täWפ®ûÉl¸ØWbúýpO?ð¼[LÝ,ûªµí+YÙjµûÇNG‘-X�U( Òý”ª‰*iãu{éÚ‹¶£ö¶êñOÄckë9îrû Ùýãp~Aø�ÁЯיÙMwÿyçŠÏa_‰­žWèqr2ÞtËKè׿k‰¬ªnÑ/|ïèµè;G®+¶¨¥  qÒ<ÏÓå¤~àyw¥ ¾‚}Å€b,õÔÄ“Åî™(V!@ �¨¦mŸ�›~·m¾~Ÿa•߉Åã¶H…l¼���RooŸ­ut6³j"AñxÜÖ˜Ê+³Ó–L&¨§§WºMnƒ‰ VȪnÿŒ&Âëie|“Ûà ÀèèõõO±Ez9“ɨ™üìl«õý]-¨ÑÊúñâËéš;> ¹¯.¥±ñ¬‘/ Ð�—nO›­go/-_5臸 OÞïqÿ0Ænt6Fœ-Åαï*™bt„zûúm­Šß�'H#ìø…ÂaKdP¯�wÎV‹Å¤Ö’ÇšJ&idt˜úû§ºB �<0^¾ìl«Mú!.Ð=VoÌ¢ëïšOOÎ]D#㙚=ŒP~æ–}¨·;"¾UJB?ä túás³éÇÙ¿}…î}ìSËàòÅ÷^…¾yÐô…Ûuõqÿ¨„ö•¸ˆÁ¾ÇJ´$î¢HéËùéþ±Û7£Å˺^ö“MèØ¯�°ZáOÀŸ6x?Ésa€Øïåö¦Zµ°ßËa ý�à ñ¦nˆ7‰ËïS¯¾µˆ¾yö«ºJ'¾–zdúÕ·½§½I™?==@ŠúÏ@�(•ÿÿ]í�KNðwè~_ _œ¶q±Äck¯îâ2\^RôþÁ/oqà”JëOsúæ�3éì“6(6Ùlñ¦j¨âþáÏûÇoþö*]{çuÇ5|¡]QH Ô]¸Öű»ùDWäö?îD¬eï$Gè‡ù>…x,â±v’PÁ?7×1«%`_YEL+/j_‰¶ÞÊ÷Ä“E¥å€«� PD ›U¨o=aõ†ßlG[m<…Â!¢L餤bN'>>>Fmmí¶Éª#ÃC*YÕ镳 „#GH‡<·d"¡f�嬛N\|\ϳ§·OºM6ÞyŽápXhH<þ±ƒ«PGùBvq¦H8â)Y5•J©Él«áý°"9DÐ�êxñC�—Þ\N·=ð=ö¬–y•/³­éæßïH›¬'ŸÉ™û€~X“c.mw4ê±ÙôƒmŽ��|”‡S¯0-NG8“Þ÷ ÔÝQyÄýÃ88 ûJLÄ`_‰ád¥îVÐÒÊúñþ±ûÑ�Ñ狇(,½ˆvùO6¡o�°Z±Àð§õ�øQžy„Øï­ïMf5°ß›!Tù=ôÃ:fNÜ'á/À_øÁ¯ß¡¹¯-—@ µ¶ßl*]uá6ˆÇš`†û‡¡Ê•¹üáºwhÙ@ŠyösIÑzktÓõ¿Ùžºòq•f‹7¡*ƒ[y;¸¸wÿx÷ƒeôÕSžUƒÜÕžÀq\¼&[5ÿ}_w´"θÿî+Ñ9'o$�Ðúa¾OA?ÜÓ<ï6ö£ð¼»¶^¾2ß·&—°k'õØê÷Ž'/ZªO€€x²uÙD�Ö@  ð.„ bMèÙêß:$®½h[Úv³©U3¬:uì”d ¾ù³:‹9Í–ÜηÕ#ÃÃCÔÕÕ-Mµú¦™×dUž7ËD[»>ã�Ö…ïGGGhbb\]GάêÔZÖêŸ×YÉåÔ ÁN_­¢cYzûý! q`) p( þ;È¿ƒ …ˆøˆzíßùßÁÒ÷ü]0H”NŽB?jaA?ÒéÍ[@ôМEôðÓŸÓx"Ë — üFëôÒ-ØÑ”ÔZKî‡Æ)�ÉQ8¥lF¡t6GLÆàì#ü;£þäÔßü}6§��ËåòßsýŒú�ö»ÐÆøDŠ� e³üB„V7—SHáß ©«ÿÎ)”Uø7¿WË*D™LV%Ô†ÂR”€®—×ê~ªÏT;VªCù=!§f†fB1Ë·ú›49ç?‚�åßA¢`žu¬êA€?Ö>çßj=µ¼B©t†b±‚Aµ^ø>�/¯~Îý©Í¨üól&C¡p�"á°~\ÜÿŸë)\_kƒSÉp}m\Z›…¹ƦÖáÏ }••)Œ¯|jWy<æ¼°„æ¼´„>YX:ªËïx,D»l3�öÚ~m»ÉTŠÆxAâ,«åîòÁÑ«n{ŸÉÒ[I§µŽ®1ØWõŽÂ¾Ò¯A«ØWò÷ RM¶©íú»y?-Zž¦@ ô¢Àº)sМbSµZ¿œð§åÄþt 7ì÷â2äÄ~�x“8Þ¢%oEÊ›ûÇ‹oNÐ÷.ø¯Ü $jÝvùŽ´áÚö^ ¶Ò-îÆ÷Ž™iñ«œ¥¸V"™¢±Ñ1ŠÆ;ÕX“Q\+­ÆÂ´XWµ¸ûÓj¬‹†q­BÌJ��MŠ…ŵrœ”ÂìíõI‚Ãqºp8¨Æ½&’9joÓÇS2Ù …BaP—2‰kq\]�û†B5âZ¥8�§ -ŵ ñ²b<¬0®*q-56–/“M§)�Jŵøøt:©âÃÏuÂ-®¦ŽG÷[ë�ÇáøxD‹_E#ÿH8@Ñp°øùä¸Vù²µÒýã¤ó^¤gþ»ÔÊvg¹ìô)qºûÏ»X&­Â¾2‡ñXùx¬ºˆÇ"k&#Fß·Òý|½ø�²'@˜DXEuއúFs@%«—Æ…³|1±•|ÁU b2¶@|-�ûÔÀ`ˆœŠF˜-�õ8@Èáà@P#í1Y0 ¨ßç‡Å,»üçùáåª4y*ùÿð1p¬Mž“Ö‚Èɱì·B”SrÚç9ísÆ�U‘ÿ�ÍeUÒ"©µ6 Ì)eå‹m«Ájíº,@ÕlÉÚèµ¶™ÀI”Ngi|"«ºP—ÉÁxDzء‚‡²#íÅWÉòg/š=‹i‹Õ½‚Ä¢ü0 Dá�öP€DŠ¿ƒêçü�@û<ÿwþ{~pÀ¤Þh$HÑpþ�?`à:ù êÃõAOFÝ›:;Û´6 }äë…ùADH{Á$þÎv±¬è¼^ß?6Øï>ÝÊ¿õÀ—‹þªT ØWæË0ì+sœ&—ð«ÿ±ç7§…K&týâÜM雂°j´Êð§5Tü*ÏV4û½9ZØïÍ12*ý�à ñ¦n^û µV¬‘ü…3/y•xr¡œJÔâøS¸øâ¶ q­I�cD¹¬o–ˆkq¼)›Í¨A°P8\ŒCŵÔ8“§²×â—Žµêù—ŠóaCÕÿ/¼¤Ì±2õ¥cޝ)”LMz!±¨&¯rlI#¹’Jx�DŽǵ8`�F( ‘·2ˆ�qÌŒã^ÕâZN>Ïûã?Þ¥+ÿõž­d ¢ëû·_nC;m9M´¸ZÏójÃ…çy•ø8©N>×…ÿaIõ‹…áÀÿ�“Ü?7Ä“e¥õZV[qÕ1çªônýo5(T¸ ŽÜdÂ*g´ãì—vŒf6Þ‡T²ª�Lš�eç-‹Ûš§±å·ïø²C.ï�ƒ‰üÖp­‹çØÖÖ.%lø� ©}0Y•‰žn_‰DB%SÈlk�¯Õôã¥w–ÑÑ?x.‰þŒMvø«<9Sa’¨V† ¡* ´ð�ú¯|Ð[m-_ÖŒ­æ¶°4@û*y5ÏòS“c*ùlž 0v ±u˜œÙV#YçIå2L÷�’IµZv �<«‘k ¤[R ·Rm¡?(ÐÊ3�–$2©V{€P ê21–ÿÍ{l6“ ®®NŠÅÂ*a¶@´UÛ )™ÊÒ[ï© ÿòÏw‹ÈñC’ïú¢ú7ì«J�‚}e®d°¯Ì12*áÆÃ§ü�½¾õ8}¶HOXýÓy›ÒÑ€°j´–ð§Ý!«:%Ï¢ŠýÞ)ì÷æ5Ú~/:#è‡9RÐsŒê¡g]ò ýûñOå'PK Éh/—ÜYĵ C  �Zq­ÂËã…8–Q\K}<¤‰‰ ½>o�>[¬÷7Ý€ã�kv§ÕV?þGíUÀó¼J|ð¼Û ÍÕÚ„ÿaŽ-üsŒêáÈ�ÊZ-¿êâÉÖÖ¥[V[{ý1ûIôoûõ›Âuåù[Ó.[O×eXÍd2*)Ñ.Yupp9õööÛ"'ºA¦àãaÌÈ™V‡ E&ŽzAÂäq1&üc‡\>?³õf‚;ðœ=VF&øØ¹Á¡Ïɪœ= ££ÓÊR •5ÃK¤vnI?|}�~æk…¼¤"SD €€Š@1›ªö—£÷_@\�Þî( §* Lí�Ñì›ör…¬ ûJ·™½ûÊ^"úÞhö•Èœª•qÒÿØû[OЧ‹Æu]ýég›ÑÑ_]ÕΛ¶.üé¤zÜ*üé’ˆc¿·¦îfx‰´†ý^%¹2ˆ7™ãÆ÷`Ä›Ìqš\‚_Þqûþ1Á(ôÝ9”Jk™ d*Í/Uh"aœÍSË'ª½„­½d­ù®Å”€åÿÌgUOîiâ—0­¯0j *P_\çÓ§ð|8D´éz}4ïÃÏÐŒ©q:ûÄ hß�WîÅIZ¤SØWæ(Á¾2ÇȨ„ö•ÜÈÄkA?̱‚~˜cýÃÈ,cåyâÉb˜£`@X…�2¦nw_1pÇÿéç[ÑîÛÎ(V9ðÏäKbb¡›ÂÞž>5é—ˉ#µ&Ï…çÊ7pž'¿åâTÆÓj˜±1Á—SdU‘7sì�†43ù�f_ß×å��›ññ1£ÎÎ.ÇE¯UõãéwÓ/›K™¢Äbþuù%Þ‘õ90iÒõFòç©‚¶z Dò$Á€BÜ”& æñd‰?T´ðwD 䃉ü›»V�¡ËgÒ ²‡¨Õ´,¹j[ÚßjVݲ§6jÞü4Ô4$#äÇAü[=.C”ËR Ó>ãÂü»ÀvÌ©Ÿ?+|¬-§•S�¬ã¿¹l!»o. îÑêWülJm$ÿ™àSß=¸AöaŒ“—Êý¨)Цåùs<˜Ê.” )J†Á¸íîW_¹ƒî¿j7Ûí”7ûªNØWÖD¬Uí+k(•J;íìûí'hÁB=aõÏ?ÛŒŽaÕp‰àOGlÅ &ƒê´<›éüéÚÁŸ6“ êßÂ=$/=ZMØCÖ¬vÿxý�Aúã?æÑ«vÒÇ­¯’Vù’‰kiä(öë„´ IDATíâp{†9>Uˆã#ü?'X–¦Ýº~;âZˆk™«JëꇟãZ…}Täe·â–› k‡´åßÈoǼïâZœµõþYŸÑWö\™fL�—Áÿ¨­MxžW‰žw›ïÀ²%àŸÃ?—•³zðÏÝ÷Ï÷9öqúäs}uÄ“Í$ß·* ¬¶êÊcÞ†Lßá>J$Ko”_ñ³-i�íVP «‰¤3dÕ��eÔÝÝKñ¸¸£èör±£Å¤R;DÜÉcd2ÿp»n?“ûcLj�{§Èª"˜©™UeúdLX¼$«._¶”ÚÚÛ]ɬêÔÃFÔ�Ál’~øÑ#4ô6Ñÿ®˜‘o€€ G¤³@$Ïíd§Jþ$ „ø?ÌyÓ‚Ëü·úpƒ¿ç§ü;Tú þÌQ ¤P Ö¾+Äßiåƒ9þ�F>U˜)È¿CD9&žU §ö¥HHÕÆ¢’B ‘@.0‰TÊûƒF-íñ4¿Þüoµ�¾Œî³B™Bù²å7J€rÙ )écÚ±Mjêø´qëþÎLÉ�Y$O‹}X±ùúyâkáhz­A­pù\&ÏW;äO#òøp?êƒ)þ,O|U °ê•'À2Q¶@ Uɸy¹�ÉdÝœöA‰œ›o*OÌU±Î÷_¨\š£¶œåÛâŠ<.ŸB§ù©¨Xhã-¥=eÂ0“2yŒbti�K`å Æ…œ*î O€ß +aU~8ba€…uÏ÷ÏsVW¬|Žeß•Ë\ÕûT�}ÌÂîÚU˜€çO!õ3R²¤ä’‰kV ’�Öî¡[/ßÉ1Ô`_ÉA ûª„[+ÛW2Òã†ÿñÅo?Aƒ°*¼ð§í½HU´ò\k!áO×s&«ÂŸÞ taÉá{ö�œähÇÆZ�Ç"®%†6âZ“b]ˆkiñ#ĵò1¬|, q-± %_JÉeµø¡¥.5 „Ô²ÏD^°×’¹Xšì¤Âð?àØ‘ŸZuáÈ! ÿþ‡œäÈù²}q½F¸ žlg…Q·ÕaµÕVó­‰À ;ÞOã fßh×åçnI{í°e3) ö�|UÉx]=okóÍJ°ñ‰DÍ~Êsøí/&«ò¿�$—JiÇúz™±vhhP%~Ê�Uy¼, Lã̪±XÌuyX¾ŒÚÚÚ]‘=žã`g�Y?Æri:õÇhd>Ñ[¿­3y˪$q Í@ˆBmLú P�‰ŸL,�äÿ% E‰‚±²ßq¢P,@Aþ.®P0 `L¡pœ( P8¦¨åù'ìÂV§ä4æc ¤'ã)¹<±4§¨ÙBùo�·Çˆ²ù82Ÿ-”Õ2‹ªå ¿9¾šÑ2’ªß©„L}™B•‹ÈíHšÅ>Jíimä š\.«8‹m¨ãÔ2­æŠãä1r½åRI „Û´9Ǫ‘jÕ2<Ÿ"q”ÛÏÿ]ìW#„r²ØAËê©ÄW\ÕÈëGÝ3ˆÖZ£²DjàZÉ©G5…4úl~‰5z¶&g7OÏ·­æÀÉ“kÕ ¼ÅÏ5™Qk«•U 2‘,ÑoZ�j�›«Zß!"¸–~Xcä‹\\6ÀÄüRÿÕDi÷í¦ÓŸ~¶µH«UËÀ¾’ƒöU 7ØWÖeÈMÿcÿ9À¨'¬þõüÍéˆ/ƒ°j´Rð§­ËïänÊóä¾àO›¯üisŒŒJÀ’à öì!9ÉÑjÙ½ ®e}±ºˆkUÇ q-1-…¸VéD­ŠSµ 'S½ìÞ¢q-»÷Q¹ärð?ÌÑ‚ÿaŽü9ŒŒjÁÿ€ÿaGšpÿ¨ŽÞ—�œÞÿp!#½ÅBˆ'Û‘6Ômf@XmæÕÅÜ,#°úÒò¡t±Þ%gnN_Þ}%iÂ*“U—SOOŸ+Ù--O0_Á‰áF}3‘’3mÚɶ):'Æ–Éknd 5÷ÅošÅãmRÄc&©ŽŽŽP*•$δo“;+ÝÊÛJN%[m=œh»™ôãÄù÷Ó‚Y9úèÖ!ªwc…Ö=YT¢Q®ZP?GA‰¬Æ�†,Ï•/Ñ,²¹t†!Δëp`êx8Óoeâm´5·;ÞFÓ�\ºðà@Ë\«\s]vÞb¶ÜI„Û\Z˲LÊgæ-Ë@ÂmMÊœËd( pY&ÒH´ �} eÏW"¿ß.+Ñ¥ÿ·¹ô’À¾²ì+=f°¯¬Ë�ÛþÇþ'=I|¬'¬þí‚Íéð/�°j´Zð§­Ëpy ·å¹¼/øÓækåÄž ÚgÑÐ�êH!ÞT‰M3Å›DtÄ ý@\Kiù2�æ·ËÏ”O§A\Ë~­X·Ñô£™âZNÜ?Deþ‡9Rð?Ì12*�x¬uÜ�E<ÖºÔèkàþQÛ?ßÿ„iþǃ:Â*âÉv¥õ›V›ue1/)ÖØë!Z:Àç"kׯ¼}u�•¥«ì€ POoŸãYL¥&—¯d…ðh§7ëzíÜò\øM³x,.E4å‡ããcj&Ò` HmíbG|OÆ�/ÑÌ®n‹Œ?gçµ›Yµ™ôã´�¡7ïIÒg”HƒS·QhÍcÄ4Áî±Wb½4f)&dòYóÁ˜`6ÅÆœ¦:j«äÐ\:í*‰W%ÃòKœf¼Žô£:øÐ�ZØT×��׈æýµ’ä}àÞ«Ò…§o"%í°¯¤`ƒ}Uì+9r»ÖWNz’ÞŸDXýû›Óa ¬BÚm‰t¦}øÓæ8Ÿ6ÇȨì!9Üo*á{HN†œ¨…¸–(·¿]ÎowbE×rEwÛ€~Èé‡q-7Wþ‡9ºð?Ì1‚ÿ!‡‘Q-øð?œ“&w[jÔûÇa?x†æ2N�`¬âÉîÊ Zo\@XmܵÃÈ]@`­}¦ÅË’Å–uú¦tÐÞ«X&¬ò txh�zûúUbŸ.~cŠÇåUFR·æìµq¢¾i68@±X\ŠhÊŽæØØ(µ·wP:•’"¼ò dU/²×ÖZ;Nñ¯omd[lFý8ããÇèÅ'hñœjú. Í<Ì\4’¢Ž[7ªç%˜�©dsŠ—ŒzÏáQ‡–ɪÉ"×2«æR)õõ`$ì }á€Ú«À�¹@(ìéÐið²=5h™ÉR¨­þ²ïö¼ÕŒ!&-…ºÊ&’®’x™ìG¢`Ô¹¬¶JN=ÇÝ’¬C?j®¡UÁÑ�j�ýo¼�yüúBzÈ…`_ CUQöU ØWòräEÍN~œæÍ¦@0Rìîê_mA_ÿ"«FøÃŸöB*åû€?-��5±ß;�¢{m@?ÜÃV¤eè‡Jî–A\Ëy|×ªŽ©ˆßngEײƒž7u¡öô鸖۫ ûÊm„k·ûª¾ø›õý0CÈÝï¡îâk·õF×�¯�úÍ›?¢ƒñd»R�úÍŠ«Íº²˜—|ùQúäó‰bÝó¿¿ ²ßªÂVù:6:BÝ=½¶H}Rƒ¯R‰‰’ü²ªuT™L ‡©««Ûze"5³ª ѵ¼³BfU©8Xɉ#IšY?Îûd6=tñ�¼W}•¯(´ò«/‚–�ɪb$E—Ó÷MqvO&q†;Ú}?V»äyZÉbšŸ P{›Ýn«Ög¹d^½³ÚB?jìÐ�ªàˆêÇÀëDó 2¬žräÚtêÑëéì+!˜ Á¾*ÁûJ^޼¨É¶ë!ß›Mï~Tz¡‘û½æÂ-è�}AX5ZøÓ^H¦\õ ößÖÖ û½œÜzU úáÒÆý@?ê‹¡wĵœ]ĵªã)ê·Ë®âZ²ÈyWúa_?œˆk¹½â°¯ÜF¸vû°¯ê‹¿YïÐ3„Üýúá.¾v[oý8è»sè�†uP žlW2P¿YaµYWó’B`ã¯b±˜›ÓеÍd ¨··OªÏ‰ñqjk·G¶k6²j³ëÇ¥ Ÿ§ë¾¿”²£%‘™y”Bӷ׋‹žZ¶œ¢}½»K$—^‰JL0t*K¬Ÿ�ƒâµ ÝÝOkÁŸ£p§=|­ö9¨¯d²u% C?j+ ô£FPߢ~T ìŸuÒtÌ�3MwBØW¦€}%‡[µZð?ܳ£Êý�CN}ŠÞzH· ×]´%} „UCÑ„?m]ÏáOWbZ� ö{oö{ëÚ+Wö�n°‡*púþ�¸–3Þá·;ç·[Ý-×²Š˜XyÄ}Åp²[ÊjÜ×N\ËéûÇä¹ãyž]i¨}øð?Ê¥þ9üó¸ˆÇ¯O®ÿ½ #h@XmœµÂH=@`‹ƒ§÷>+öô“ïlHßøêê5 «l¼§S)ÛÙ4�žžd v>Ãá°ÓC/¶ÇÆcosïøëɃ燌]_ÿ©y%&&l�·ÙȪ­ —-|�þúíEDT"4®u¼BS6׋QréEzº,?YëMœ,�Õãìk)“%9ãh0•Ò=7+9œ•gzdTÍÈëÖ•�H¯e¤Û½>DÆý¨Žô£:62ú1ð&Ѽ?WÐ /*ÕÜ«w<ϳ# þ¨ ÿþü�ö ø ®mTÍvÿ@<Ù5QAÃMˆ«M¸¨˜’<[üÍû°”"ñì7 o4“"!¢t¶²]6Þù&�Çå;u¸&“-ù'tæÍp£áqûîzfÕ\2¥©ëyA?ª£ý0ÆÆŽ~ ¼E4ïO•„Õ NÛ„þ⪆¾’Û!`_ÉáV«V+ÙWå8ÔËÿ8ì´§èõyú «7\¼¸×ŠÎ/n´Zlë%Ïb£“+…ý^7ì÷•@?Œ¥ñ&=.°‡œ'S ®eo‡ßî¼ß.º"œYq-Q´ÄË!î+Ž•lI/ãZ°¯`_‰È)ì+çí«îüÜÏ»E¤Ð¿e Ð�ré4óÏýþSôÆ»ˆ'ûW£12?!ªŸVc©;Û:‹Þ~¤8ŽŸ°>ûµ5 «ü6b.—£¨C„-'&çq‘XƸNLŒSG‡7Ùþ ×x^LV•!û¦R);dÕfʬÚjúqñ«/Òõgs†ÕÒµþ�ê^CûÛn��XD|$½{Dt+{“ CmÎõÕ¹år¶ˆ¼VÆ.ZV—’«/Yub‚Âí¢C¶\Ž×1›LR´·Çr]'+@?ª£ ý0ÆF êÛÐ�j„Õ‹ÎØŒØsåŠNa_Éi<ì+9ÜjÕj5ûª€ËR½ü�Ã~ð4½þΠnYþñ›­è€=AX5’UøÓæz_Oy6�\ ì÷r¸a¿¯Dúa,ˆ7éq�=ä΋¾ˆkÉïåðÛÝñÛEVq-”¬—AÜ×:fVkxׂ}ûJD>a_¹c_1öxÞ-"�þ.ý€~”K¨ˆŽx²¿u£ó ¬úk=0š:#°ÃáOÒï–Ž|<ã¸õéÛ‡¬A‘0Q:S'ìè¹IÚ´ …d 6¬ù-"Î"êÖÅ}Œ��Qg§7Ùþ ×Ò™4M™2MЬÊoÇ1ÉÕYµ™2«¶¢~ürÎ\úç…Ktj±ñ99j_9 fµC4õ[–†ìøãq +³Êì õÌ`Zm¼õ~ØÀ2ÃÙ!œ"ÍS ê'’í«/YúQ[k Dôcð-¢w 2¬^zö´ß®zì+™��T;™3×þ’ÃϨV+ÚW…À~=ý�Ãð½öŽþ�ø/ÙŠ¾º«Fr º¶Îß6Æþ´ì÷ˆ7•Kôúá•=tÁì¹ô¯‹×’±Þ᷻㷛­âZfÉ}�¸¯nVj9÷�kÁÿ€ÿ!"›ð?àÀÿ¨®)Ð臌~ ž,r÷A  !Â*$”!°ó7fÓ«ÿ+=�<ýØõèøC×ÔV9XÌW¨NGD×kÁšÑ¹e,–«dŠþþ©RkÊò`W˜¬Ê™ze2»ÖKªõÛªúñó^ [/_¬ƒe“Ÿ+Ô6ÍÞ q‹ßA›�í’ ³Pƒ–±¨cYG�ê;1O?�U�XóZ’§õ'íïµ' u® ý°¶Ð�^ÕûAÑ)}u˜¡s]B?¬a©@?t€ ¾MôΕY¢¯<kÚeëéÖÀµQö•1x°¯ô¸´²}åÿãÈ=C¯¼5 [”þvkÚ„UC†?m¼¯a¿Ç~/b.`¿G¼©\N`Áb¼¼\øÀÛt×Õú±ת½{;NV…ß.r»T_ÀF\«â¾Bb£ÒÈ¢Í÷5‹kyyÿÀó�cLV Èce¹c‡+8%CLâ„~ˆ-N³éGµÀþ5mKÛm6U ›¥`_Ù°FuØWîaëUË~Ò�oüèzyaõ_—nM_Þ V�äþt%*~’g'uþ´}4áO“kB¼É¾,µ{È\½lÕkýøñ?æ"®%¸ÀNÅ$×¼¬âZzÌ×—¡VŠkmµQ/ì+qѰTö•%¸|YØkûÊ+àŸÛGþ9üsûRTjñd'ÑD[ÍŽ«Í¾Â˜Ÿ%ö>ö)zþµR�ïµ}÷­KXeBj–ɪm•¬»T*¥cïÄ•˜˜0ìɶ�Ú`ã�/&«Öëbü8«j£fVe²/_õ"ûÖkÝÊû-×�Óþö<=r×Rݰ¶¾\¡ DÂO-ð�µMœÌ¥3ÚÙÌê,Y5G¹dŠBmν�—M$)e²ª<ѳîAKZ ê�ŽQlÚzs¯ è‡5l¡ÆxU;:í†K¶§­6rß6€}eMŽ­”†}e-–õ›~uƳôß75ß¡pÝü»­éK»‚°j$Að§õ¨øMž�ÒzøÓö‘„?ͧ!Þd_’Œ[€=ä²Þµ[ý@\Kl}9C#âZbX9] q-=¢ˆûŠKX3Æ}«Åµ®½hkÚtÝ.<Ïá’°¯„¡òmÁzØW^€ÿÜ>ÊðÏáŸÛ—"} ˆ';�(Úkf@XmæÕÅÜ,#°ïñOÓ³/—Hž|ÄÚôýo®ãj†U¿Bl¼gÒijko·Œ£• ‰DÂ0{«•6¬”eã�‰m==½Vª9Z–±e¢g£’UùH¾¼£èÇw.{Žž|pYIN m{…u±a2g ÅcÖ+—ÕÈ¥ÓÄ;ƒ6I厒U³YõØ®p§s™”¹½`$b+ƒ,g#P>Ê™lѼ ¼Žv²½ÚZ|ƒÊŒSzx”âÓ§4|fU臸t@?ªcU-°ã¥;Ðô‰ƒ,Qö•h‚U`_ E¤ž2À—ß^<ò£~|óÇÏÒ‹oL"¬þ~úÒ.3Äo¡’ð§K‹íGyvBáOÛGþ´ö0 ñ&û²dÔì!q\aé㱈k™Ë“Þ×2ÇÉ�ˆkéQEÜW\Êš5î[-®uõ¯¶ í·XQ ‰’xž'Z�«Àÿ€ÿá¦ÂÿGþGëðAO× ” ¬B€@_:ñzê¥éìÄÃÖ¢|k]W «~\~[�3«6#Y5SWWwÝ`otã��Ìà+× Ãzwl¤'üúYzúÉ™!“cœ_ IDAT'ÚúRÅòP3£ãî´Gç ¥’ÍÙ&½:JVÍdÕ£è#=]–1©V�ƒÕ�pØVY5“Um{ËǨ’Uäb¨Ô¡øô©¾“¬@?Ä‘ƒ~ÔÆªZ`ÿ_¿Û�6]ß=Â*ì+q¶Zö•UÄüWÞ¯úqÌ™ÏÒ ¯ƒ°**1ð§5¤ü*Ï¢ëX­“UáOÛCþ4ôÞÕ® {ÈMt½i»ž÷ĵj¯1“Þ×òF&÷‚¸–Ä}Åå°™ã¾õŠkÕƒ¬ ÿC\æ�JÂÿ€ÿaO‚ฉŸÚ®§ÿáæüë¿âxòÜ×S PâRÜŒn.9Ún`@XmàÅÃÐ�G`ÿ“Ÿ¥Ù/”Žõ>þÐ5éôc×ó=a•ßÊq*CR2™¤\6ë>YubÂðhçW•M*448@ÑhŒÚ;œËîhu¬üð€³’:µVVû·[ž�[–µ¨ƒä>»c©ï…~ý³§é¥¹ƒÅá„»ˆ¶üµ5Âjzd”"]�"SªZ†³OªdÕ¶¸­vT²j4j+siaÌŒ�Q´§Û1Â$�/Ù"šªÙ8»œƒ™UÕűyÚZD"5óGzh˜bÓ§ù*ã«Ì¼ â¨A?̱x‹è�?&)Ào”]·\¶#m¼N)»÷óÑZ+‘€}e 0”†}Eägÿã[gq€QOX½åÛÐ~;#ê‘úÀŸö·<Ënyð§e‘Ó×Ã~ýpF’Œ[A¼ÉMt«·ÝLþâZ5Öq­ú(âZ¸#î+.ŠÍ÷�k‰#f^ñ&sŒüVþü7eþ‡›è¶†ÿá‚~‰_}óÇsè…×)§‰x²+Ž6›V›a1Ç8à”çè‰ç—Ûûö!kÐÇ­ïkÂ*;Ne»ä7$•\Î}²jÂã´ïƒ‹Æ\ŸW-Al†L,kñ¸="¤cÊ*Ø�WúqÈ�gÓ[oŒG›B´Ùùâ„U&ã…;Ú),¯‚S,ã e.•±�¡ÕQ²j*E™± ŠöõX�NÕòœe3 Ú"å2VœÕq²ªc³´ß¯cjh„â3šƒ¬ ý“ è‡NK_š w¯¥`tº®ÂWìL믩ea÷êþ!6b±Ržgº€}%¶05J±œÁ¾ò·ÿñ­³ž£¹¯•Nààå¼í²miß�ôû‡mah’àOû[žeÅlû½,tÅzØï‰o²-FU@¼É=lkµÜlþâZÆ«Íñ#ĵê£cˆkéqGÜW\[!î+×G̼$âMæù­üønÊ$ü7Ñ­Þv³ùn è—øÕñçÌ¥Þ(%¹B<Ù�ÕF›Í‚«Í²’˜‡#|íÔçèÑgK„ÕcšIg�¸�!a•ßÒà7é9cf½.ÎFÄÙ.êùÓö.~C’çÔÖnï8òZ£àö“‰ÅâqGÆl6cõMš¡AŠÇÛêJ´l†7ÍÒ©”%Ùh5ýØÿÔYôÁûcE‘Œ¯H´éOÅ«*A4³MVÍ&Ré–ÏÐÊGÙgÇÇ)‹Q0R:¦ÀLϪ}¯d³”£H¯Fþrâb2H%÷Ê^¹$“UÉVvVÙ¾½ªW êOµ%W^�·V?ÐñU€~ˆaÅ2µô…úð–iDeo¸rí»ÿ¼3­3³[Íöûª:ž°¯Ädͬa_ùßÿ8öìçèùWõ„ÕÛ/ß–öÙ„U#‡? Úlï“ùþ´ jöëÀª�!ì!û2Æ-À"òK<q­J™F\Ë=—iq-=jLÀDÜWL’Z%îk×C˼žçÉ'1G×½°¯üc_9¹Êð?œAúýpF’Œ[)įŽ;g.âÉn�¶› V›j91»|ý´çé¡§›9ê€Õ霓74$¬rð>‹ÙíRº>4�"~Ž�iD»öŽéñˆTôòØ“UÛÚÚëz„}*•RIÍõ$6‹¬Mµ2l¼'“ êè°F„l5ýØóØÇháç‰"Œ_Ph£³Ì‘wŠŒ—Ÿ h¯|S&«¦–P¤§Û²ªúàilܱt2zLÆS”Eº¬Éby;Ùð5Y•ׂÇ({©AýÁaНÀ™U3¨V˜;ôC\  bXôc|É4zïo•/Ý{å.´Êô0ì+8a_‰É[­R°¯ˆÅÿøöÿ=OϽ²T·œwüq[Ú{V�dþ4üiû;¤¾øÓN#*ÖâMæ8Á2ÇȬì!ÙCˆkUJ,âZfZlü=âZ%\×—!ĵ݉k­µZ—Xc¥ðvgEÄZÅ~O„x“˜¬È”B¼I5ûuš9‹¸–^>'«ÂoR@ĵô0!î+$6j¡V‹ûV‹kÝ÷·]iæªòÉ ˆÃÿ€ÿ!®}öK6³}e­Äcí# ÿþ¹})ªÞÂdÿü¸sž§g_Ö'@@<ÙÍ@Û�Œ«�¼z»ãñ£è¾YŸÛ=ä‹«Òù§mBÑQ*M”ËåÔ#í½$^Nž$ïÑXÌ‘Œ�££# †\�cÆdU·³·–ã422¬’UÃaûÇšË gåþE2«f³Y¡rVÆÂA…@@>K#ïããcÔÝ-žµ³•õcÃ/ÝGJ‰ÓNÝë*´þ÷«¯¿5j·OVM�Rlj¿Ѩ(›\Ê™U;)è¹›ƒË¡ö6[c*¯ÌíeÆ›*OÊå6˜ŒF…Çå5Y•ƒÐVÆ7y"Å >gV ¹TË¥3j&X7ú‚~‹)A?İš¬Ë_!z÷ï•÷Èûþ¾ Í\Å~& ØWbë"S ö• jöë´²ÿqÂOæÒÓ“«w]±í ª¡`ÁŸ¶¯o“[€?mnןvNîZy¿Eñ&"Ä›Ì÷%3yò£¿€¸ViÕ×2“`ãï×*Ⴘ–¸ !®%†•h\ë�kv§ÕVlk´J)øæ÷yø¶DLWþ‡9–ð?àˆð Ì$É�þ‡Ù˜E¾÷«~ ž,²z(4@X…$�2Žúñ‹tïã ‹Ÿ´÷*ô«Ó7U «‰¬J೚mÒI€ùèLάê„qÂodE‘¦#«²ÑÅdU'0’];+d &†r¦\'²åÆËA¾dÛä11޽½âAvÒ[U?’©m~À:qéÝH¡u¿c,A™Ñ1•Ðiç¸v§G(6}Ь˜ªõRË(Üí Yu"¡f�uêRç94B±iòól²*g�Å�³œæI-³êŒi¶2´Š®¯‹ºÇX ‹¶ ýEŠúaŽU5ý¨FX}èšÝiU›�}ØWæë"[ö•,rö굺ÿqÂOçÒÓ/é3¬Þý§íh�í�aÕH²àOÛӷɵëñ°þ´ö¢2üi{² {È~µjÃrÛZ-7»=„¸ViõíÄgŒd~»¹Î"®U‰â¾ærS(Ѫq_·âZð?Ìɪxž'®Ÿf%›Ý¾2›¿È÷ðÏáŸ;Áu€.¢mreªùçˆ'Ëá‰Z­‰«­¹î˜uŽ9û%ºë‘ÏŠßî¿ûJô›37§HX¡‘‘ÅÛœËhuø(µx¼Í6“3!°q‹Æ\�;·|Üi{{‡­LŸ¢8ñ¼˜0ÉdUY¢¦h_µÊ% ŠD"Bë”N§ÕrNŽ×‰‡k#ÃCÔÓÛ'<.Æž3·ª~,HÒÎG>ª‹¾ÍˆÖ9¡,å*«(”£pg‡š™Röâ ejù ŦOµEzeb`0u&³ª¢¨G/©¤K™}Ë1Q2YmžÓú¥Ûä#܂шð9«*_vÖÇÒº* eÆ'(Ìi%pc’*Ï�·­0ݲj2¥fÔ Åc–¦jZúa ôÃDª^TÓ�e/½wUå>üÈu{ÐÊ3äl=ØWÖÖÇjiØWVs¦<ü¢“Î}�漸Xè=ÞŽvß„U#)ƒ?íŒîq+ð§ÍßvNÞ°ßׯñ& Ä›Ì÷¥Z’ägq--f‡¸–Ä}q­hˆkY Ä}Íáò:®ÿÃü>ÿÃ\nEKÀÿ€ÿ!"+ð?Ì÷¥Fõ?DÖ¿Z™FðÏO¶³Â¨Ûj€°Új+ŽùÖDàÛçü—nèÓb™ýv]‘.={ ³”ÍÙ3 ì@ÏÆ{,wäˆûÁÁ•¬ÚÖnïh�Zóál›LVíì´¬®(n‰‰‰º&yœVÈ©TJ%«:ñvT#Æ�/Ù6ùíÐá¡A•¬j¥ 7Ž@]w.WoýøðÓ1úÒñ³tCž²•Bk«Ÿ…vgVµGVM.¤ø {dU…eE!ÇŽNg `â(“U£ý½ÒxÉ‘U[$`+rËeY&Â�r{qjpˆ²cÄ™(â+L§`$lµ{Ë峉$±ì„;äÆ\«Cè‡ør@?̱2Ó�e/½wMå^üØõ{ЊÓå«°¯Ì×E¶ì+YäìÕ«·}euônù'Ÿ÷Í~AOX½÷/ÛÓnÛLµ:Ä–(Ú™evKžk�þ4üiûþì!gö£V`¹‡m­–[ÅB\‹JdU‡D ~»9�f~»y ÖK ®e3®�¸¯nnÆ}�ŽkÁÿ0ö‹çyrz`T«Uì+;ˆÁ?‡Ã?¯¦C� 'Ÿ;—f¿¨?± ñd;»"ê63 ¬6óêbn–8áÜ—é–û?)ÖÛk‡èòs·¤h„(•¶Üœ#8å?“U9k§�‹ß8X®f u3¦×έšÝ3™¤X,æI&תR"AÑhT(+);·œUÕ ƒ³0Æ�±�m“ɪCƒÔÛ×o‰¬jG&�¨ëýxãÝ!:ôûOé¦3m{…Ö8ªôö‚,£vɪK(ΙUÃæA”jørÐÜÎ8&·ëtÐ’Ûç7È#Ý�ÉÏÓŠ|1铳ixÕ�-=2J‘®N+Ã,–M�ª„Þ@0Hñ§ g�•ê,_‰×Y%«vvØiư.ôäÐ�Úx‰èÇÒ‰Þ¿¶’°úÄ?ö¤Sã–ö•%¸,frì+˰ٮàûÊÊ$Üô?NùÙ 4k®ž°úï+·§]·aÕh�àO[‘\ã²nʳQ�ð§5TàO#Þý¨¾A?š_?×ÊŸdÿ6^l~»}¿ÝÁåÐîõˆkIAЏ¯l®Ç}�ŒkÁÿš.2žç™B$\ñ¦ÚPÁ?‡>Hui$ý@ƒÉªò9‹¨�qTèßD‚BñQ ’ô%;W„BAOH˜ˆ­‰«­¹î˜uN½àUºáî�‹ßn¿ÙTºú¢m=%¬¦Ói£x¼Mš„X 2yDVeC�Ç�;ûFºß•çÌÙRCÇ–óÃ5¾œÄÈ.®®n¡ì°~X?êÇ#O/¤Ó~ù_<+î£Ð*_rˆ¬ºh)Å9³jÌyÝÉõÓŽp�J‘.«>ÌI¥ˆRÛ嬧LôuóR2Yµù@Ø™~DÚ³s$œŽŒ7cšëòÀdÞôðˆŠQ´·Çñ¥p,¨ýp|m¸Ay¶Ò±H{^êÇ’çôÁ?*gðôÍ{S_�ù^ëÕÃg»÷y+kä§²°¯¼_ ?ÚWf(x¥§žÿ"=þ¬ž°zÿßv �¶aÕh�àO›I®ñ÷^ɳÜèÜ«…ýÞ=l«µŒýÞ{Ìe{„~È"'_¯•õq-y¹)¯É/œ#®UKĵ*±Q“ ®åŒNjE$e¥c‘ö)®ÿÃüyžçYÑ�êe[Ù¾rAïZ�ÿáÖ…ž Þc.Û£Uýøá…/Ñ“/ êºCIZå+a[„N5hùùRŠMë§P›Èà*Y5q”PÊA?>rž3¶jdؘšEÔ­K}ˆ:–YUdœ©eéé–"ÈfIJ,Z¢vÓ¶ÂtOȪ‰…‹)ÜÕéNfÕTŠa臈ÜpèGm¤dôcñ³Dóo¬Ücž¹eêí®�Éö•¨äÊ•ƒ}%‡›•Z�b_Õš“—þÇ÷Ή{ösÝp¼jGÚaó~+°·LYøÓÖ—ÚKy¶>:÷j`¿wÛBËØïÝÇØ­ n![jú¡Çq-û2¿Ýy¿ÝΪpq-9÷•ÃÍ븯ݸoð<¯úZ3YÏó¬ëì+ë˜ù¥ü÷Wúá>Ænõ £gþömÄ“ÝZ´Ût€°ÚtKŠ ÙAàô_¿NWÝöa±‰Í×~·E£|ô»�–Íëòƒ*&«vuõØÎÂÉ7Ï��eÔÕÙí:Y•û ‡ÃBÄMs£„Uã$›ÍPG‡sÇi;AVM&¶Ç¤(ŠJÚõâò³~ÜþÀ:ïò×Êž|¤h•¯†håý‚ÒÐȪÑ)½îpŽè,= |E5h‰H‘.«õ­äR8[1gVÍål‘|Eæ—Kj›¹—k“K™¬Ú©bgõâñN|¾XÍÒŸ1Õò2“c#]�jo³:\Óò<Ÿ@IJ*ôÃnËZE??C4ÿ¦Êû׳·íC=�Õõö•e‘²Tö•ì«ÚbS8žØ+ÿãû¿|‰}ZOX}èªi{V  þ´¥m¯xܶWòlmtî•Æ~�ý^Dº¼ÞïEÆäEèôCDΜÖĵDP¯^q­Úø!®U‰â¾öt®Vmĵjǵœ¾¸·’ζ û ö•ˆDA?Ä2ãy·ˆ4™Ç6Á±�£-ÈÞ?OöbuÐG³ Âj³¬$æág\ü:ýíÖauãu{é–?ìHñh€)Å‘>Œq2[¿948@Ý=½ê[’n]ü6ߨ9èH–Q·Æáu»V�“t:E]]ÝŽ S%«¦RÒDd&�–®Ïa"¯¿Wëîwý¸ñžéÂ+ß,[c…V=�h¥½å–½´ìï¥p§�ȪãˆDÏJÊ�D¯È£õ Z.W³”%öcM–?ü°CVåú¢kUrmW‡+kÂÇ¿ãqá±iôCn_©ÕJú±øi¢ùÿ¬$¬>û¾ÔÕ6„ ö•ˆÉ—�}ûJDzêáœö«—è‘§ô„Õ‡¯Þ‘¶Û V�Ö þ´ˆ$keê!Ïâ£s¯$ö{ì÷"Òý{XŒx“ˆ4Õ.ã÷x“¡OìB<q-{²„¸VuüתÄq-{úV«6âZDµâZ°¯`_áy^�û• ö•{»�s-Ã?‡."M¸X¿ ž,"Y(4@X…$�2Îúíô—Í/~²þšÝtÇ;S,J”OÊç8^|£X¾ŒÚÛ;l_ SôôöQD"“Ÿ•É¥R) ƒjvÕV¹8�Í—ˆcÇdžpÓžž^Çà±KV-¼!‹Å¤ÇÄòÊ„U ¤;)«ØúqÕ­ïÓï®ýŸnº«¬ÐJ{XG@ Z.ZJ±©ýždÒ! 9+¦L†Ðš�ÄtÆqlµþ8h©Ên\^þEñ*”K.]NáΩ>sé q¦S>V.>}Št¶S+YkÓ#£ŠÇ]Y'Žƒ~X•@ñò­¦‹ž"úð_•„Õ¹wìK�í•v ì+qY’) ûJ#®Á¾2—žzø?¸ð¿ô𜅺Á=|ÍN´Ý¦}ænÁð§Å½ò,>:wJb¿Ç~/*YÐ�ÚH!Þ$*IµË5B¼ÉhnèâZò2ű›`Ä›Øx«ùí…UA\K^>Ek"î+Š”¾\=ã¾VãZÓ ð‘kw¢m7qÎÎ7Ÿ}㔀?-¶Võ’g±Ñ¹S û=ö{QÉ‚~ÔF ñ&QIª]®QâM“gá–~ ®%'WˆkUÇ q­Jl×’Ó3‘Zˆk•Pªö"¶[÷‘õ©Wøð?DeúÿCTV씃ÿa=oë:qÿ@<ÙÛ5Co��«�½~½ÃœwÙ[ô‡J„Õ™«vÒ}Û•âQ¢DÊáΈ(11AÑXLˆY«w6¨ÇÇFU²ª¡ÒÎL88΄E¯H‹vÆêT]6N˜X§’ëL.Ægb|Œúú§˜þžÉª©dR:¯Y»¼&S08�¢—^ý6]}ûºõ\ýp¢;+ÂkÌ�µä’å›>Åñ,¦Âƒ0(h…ðh§7ë2¶JÎã̪K–Q¨­�Â�í–§¦d³”UÉ�~1@¢ Æ!A²,ãÃW h¾ÇY�ãÛ#ÂB?¬¢.^¾Uõã³G´àî¶  &öa_‰Ë’LIØWÞ?ˆûŠÆµÔžçÕ\hØWrz`T ö•sXºÙüsøç¢ò…û‡¼Žx²¨”¡ aRÊøÅŸþG—^SÊ”¸êŠíôÐ5»»BXå}gV]²œBíq wvXžgçH�P¤»“8hj¯$Ô™6ª(%²ªÉÞ´=øh¼@(h;³*ôÃÆ"Ô¨ÚÊú±ø¹8}|GeÆôrÂ*ì+wä®ÐªÕà(ì+gÖþ‡uO¿èezp¶ž°úØu;ÑÖ ¬‚ Ú$˜ º&@ð§­ïQUc7 äOæ€x“Éþ�x“c {¨Jĵ/Çje¿]} q-ÇeJmq_9\}÷‰kñ$a_Á¾’vëµ`_YǬ5�­Yþy=ÄÝrŸNêâÉ–áG…F„Õ^|L½�_þåúÍUóŠ_¬8½�»~Ç «œ±+�Ú"Ît&M]]Ý®/'Þ¤1wnÇFGÔ̪Ne¹e㈃ íÖ‰oN D=Ȫ�¦çþá5ºã¡:Èg­ÐôíÌŒu•] IDATW�Ï©�!ŠMíW³iúáâl›J6ã«L¯2¸äÒiR²9 Åc2Õ¥ê$/SI¾‘ž.Ëõ÷ÌðEz»I=V.XI¦iÔJ ‘ödËp¦X~° ;îú!‹¾y½V×�Ï'ZpGeFáa•ï½°¯ÌåH¶„Õàì+Y¤õõ;R}d‚9ãâWèþYŸêÀ|üú�i«�z�Y˜&kþtõõƒ<{-nØïëó0 û½×’.×ôú!*9^Ü?×] o˵ºßî-Ú•½!®Uï¨Ý«ë‡Y\Ë/þ´×Rû ö•¨Ìya_‰ŽÅ«rÐ臨¬A?j#Åø˜=¯@<Îð‰DœjÒ´�FÔ�]ô=0ûsÝÜÖü–BS·6 ¬¥Rj6Íè”~WŽb7Û €FVÍR0–©î›:õ Z"aŠöõHá fV• º–wæ²j.GDLV­$Š‚ÃdUè‡(ZÖÊA?ˆ>{„hÁÝÆ„Õ ’„}eM¤,•†}¥Ga_™‹�_ü�ÿæºï =aõ‰v¦-7aÕháO˶_äÙ\óœ+�ýû½¨4A?j#…x“¨$™—kÄx“Wúñã‹_¦ûfé3Ê#®e.Sn–€ßî&ºæmó‹äˆk™ãT¯Ð�Úq­Îö0yuÿ¨— õ ÿþ‡¨{8@ î©Äð™›÷ Þ÷_‚}%ü�}e]ÏݪQûÊ/þÇY—¼Bÿ~\ŸaõÉw¡Í×÷—çÖÚ[mþ´1ì÷Øï­êP½Ë·ò~ïöˆ7Õça±SkÛÌúqÒOç"®%((ˆkU…¸–ĵ×*—·ô£Z\ëÙ[ö¤®Î(žçUÙÓ dUÄ›ozkfûÊøL»€ÿÿÃTHò¿r6~…x²¨ä¡a2t\vÃûtîeo?k‹…襻¿èÂ*ïÑhÌ1rd­å¯·qâÔÛyn‰8;·CCÄέSäaκ•L$¨½£Ã­a›¶[�Ì_¦ƒ,P/ýøæ™ÏÑ‹¯/Ó�rí“ê߸rà´Ì&S¶³i B"\Ì ²*“å‚‘°ð˜¬T2Yb|Cíî“Í cc²ª¢ä(>cšÕáªå3cãîYµôúQ®HnêÇghÁ½•j;÷Ž}‰�Nsó‚}eü�}å¦Zo»^ö•õ‘Ú¯aäœ}É«tïãŸèŸ}ã.´«†€ÃŸ.Á‚ýû½ý]ÉÛZ}¿÷m臟ðK³ëâZ"R@„¸V%Nnúíb«â¯Rˆk¹OAÜW/ëÕâZÏݶ7uwºŸèÆHóð<¯>ûžç‰áÿþ‡˜¤ø§T³ûåH7ãýñdÿèFâ ¿^� �+nú€ÎùÝ›E4¢‘ ½rï~¾ ¬Ž��Q,W3žº}ÕÛxO&“žEoOßààrêéé£xÜ™Lމ‰ Êæ²ÔÑaïXp«s™l²a»\²3¾Zu멇ýàizý�AÝðÖ9E¡¾ õ#V�âNg<%Tšâ­(ÄV€«™U…r™¬»dÕl–² wzDöVJ.YN¹lV%«Êà—ŸÐ2Á¦ËT­ÏÙËl²Ò¨ýpoßå 0н~ú Ñ'ÿ®Ô=· «°¯jo°¯6K�‹ÔÓ¾òxªTÍÿø¿ß¾J÷<¦'¬>õÏ]i“u»½bCôZ[&£ýþóÏÒ²%ËhÃ�7r}-áO»±aìKß6Çöì!s)ñW‰V°‡×2‘9ĵ B\ q_èG]ô£^q­j»%ü�úØ.ð?Äp‡ÿÿCLRüSªü�ÚÍzÿ@<Ù?ú„‘øVý¿F¡‡\yó|:ó’7t=¾õÀ—©-F4‘ôp “ºšWɪ^�™ÉdÔ~¼èËQžk¼­�6H\n®T‘LÑÝ«ŽÓ‰‹�ÏT:E½½}N4'Õ¿»À?õZw©Aç+Õ[?:e½3X7…u¿«Pï¥�T2^6ç¯cÛ= «ræV%“¦`Ô½7»•\Ž2#céé²#Fâu dÕtšâ+N§@0(^7_2—LQ0Yµ€ôò ‰V€~#õÉýDŸÞç-aö•`pö•¨z»^®Þö•ë,ë –ÿqÎ¥¯ÒÝ�ê «OÿkWÚxV�Öþ4‘Ñ~ÏdÕë®»–2é4xÐ×h£� ŽbpHèáO;¤ÅfàO‹{ö�˜¤ø§T«ØCˆkU—9ĵŒ±A\K� ⾈û–K„úQ�¸Vµ�þG}ìøb¸Ãÿ€ÿ!&)þ)Õ*þ#ÞÌ÷Ä“ý£S‰ÿaÕÿk„zˆÀßoý�~tñëº߸ïËÔÑV?Â*=ïTO3(ëm¼sŠû¶¶vß’&y-8³jwWµw8“ÉÑdU– ¿§Ü¯&»~Ð�¯ž<›ÞûhD7Äõ¾§PÏzÚG|d‘BÁHÄL½ûÞ²jŽr©´«$]~p�¡H¯G¤‘r²ê Ó( ‘ñš�° „‚ «æ¥úsMï¡Õ¡ýä>¢Oï¯$¬>û¾ÔÕá|¶[ØWµÅö•kÛ€tÃ~°¯¤o±¢™ÿqÎï_£»^ kõ™›w¥�ÖöÈö°8Ÿz‡?]ùò'ß®úû_iéÒ¥êò¬±æZtä‘ßpe©ÌäÙ•N-4ŠýÞXÅ~ïÐÝ@?@ò¸H+éÇþ'Í¢>C\k’Œñ  ˆkU*âZzL×B\«\"¼Ò¯ãZÕnÁð?<6NʺÃóœYu``uvv©?N\üöP2™ žÞ>¡18Ñ'Ï—¯ò9‹bàDÿåm4‹~ìâ“ôÁ‚Q<럦P÷:D|7)D�pÈiø|ÝÏ[ êó‘÷.]ž“ñˆ(¹xeS)j[aºÔš2.2$WÝ^=‘ `,*•ÙÕ¥¥�núý(/õcÁ¿ôÙƒ•¢ûÜíûR·Ã„UØWµ·ØWÒ[hÕŠÍb_9�Œ¾EQÿã§¿�îœDX}öæ]iCV —þt¥?ýÄã�ÑÓO?UÄkÃ�6¢ƒ:ØQ•gG;Í7&êKb¿w}ì÷b˜B?o“”R©VŒÇöÃÿÒüOךìŸ"®U©=^úíVu·å×B\«âZFºû ö•Õ=·í+N΄çÝV%ÅZy<ﶆW¡4žW¸ÿ¼ñd9ÙD­ÖD„ÕÖ\w̺ 7Üý1�zÁ«ºo_¼ó‹4¥7d™°jç†ÏFׇ�Ïòe4u;cµ+L<×ÑÑjoïðÔx}°Æó+<\c£§§×î”Õúõ «ò-¾êAJž š™ó›~ìwÜ,úè3}&Šõ¨P×LVš‚XhEèùMr> ËM²*�'=4Bá®N +³$Z¯hY&«æ2ŠÏ˜*E:e‚­Ý±f™¬�Hõ/:O¯Ê1Ð÷І~ÔÆöã{´ð¡Ê2Ïܺõv9— ÛνήtÀ¾òîáì+9imý8÷¯Ñé3¬>wËn´ÁZμÀ&‡žkÁŸêgáÂ…tí5W©§YðÅ/ wü ´Â +:¶ˆ~Úï—-[Fsf?Iï¾;O�ën»íA[m½uÃúÓÿùϽôÆë¯Q_ÿÚu×]i�u´#4àO[ßFÙï­ÍªviÄ›œDÓz[vdÎoñ&볯Q~ÿØÿÄ9ˆk•A‡¸–±!®¥Çq-÷Ȫˆûš'¾ð*®e´øÉÿ¨v×Ãó¾‡háÕd÷gnÙ‡z»�!¬Â¾ª½Þ°¯œ×‡f³¯œGHkѪÿqÞ^§ÛúX7œçoÝ�Ö_„U£5‚?]B…ï×\ýwZ´hQñÃm·ÝŽöÞg_ÇÄÛª<;Öñ¤†8~1gÎlzjÎl*d8á"«­>“=ô0õ¤’Fô§/ûÃïhdd¤8ÛM7ÝŒöûÒþ®óéØïÅ$Ù/úQk´°‡ÄÖÒJ)è‡Z“õq­nðÛÅdH¦”U¿]¦7ë ®EýpO¬ê‡q-£Ù¾Âó<-ÀónÔÜ©ÿÃy\áˆaÚj÷Ä“Å䥀#Â*ä”!póýŸÐ‰ç¾¬Ãä©íM+ψÑDR;JÝìbã„ÒD"ÎÌú³ó}½ÉƒƒË©¿ªïɪ±hLͪâÄU²*Ë$_~ 7£~ìyÌã´pñ„N<68#G]3½Éüé„\:ÑgUUÒc²j2¥cïÄ•§pG»M µÁdU¾bÓ­ïÃo|@óÿzM,XBݯAk�qE{:„ú-/”K¦(5lfUõˆ´@ nd_Ë€»Púá¨ù&eôã㻈>j@X½yoêí±¿WÕ´¯rYŠ,ü€”HŒ2ÓVUuÃÉ‹ƒ?°¯œD´z[°¯äpn4ÿãç—¿N·> '¬Î½m7Zo V�$þt •Ù³Ÿ¤ÙOÎ*~ÐÝÓC'Ÿ| Ez�Ë/ûýðÈÝuÇm´`�>q<§8ˆºº;©Qýé·Þz“î¾ëÎb†\^ÌÕWŸI‡vE¢õ‰÷4£?-w7©]Ë/úQk”…‡Å�ª…¹Á’“`¿ÙCˆki뿽Rž×Ò0A\ ú!·Û‹Õòc\Ëhä°¯¼#«Â¾Ó�É¥üf_ÉͽZð?œÇþ¹¦­xÿàxò-÷½K�`¬âÉbò‚R­‡«­·æ˜q n{ðS:î'ÿÕ•˜uÓ^´ÚŠq!Âjš [ŠâØC(7‹ßjã,°üãõÅFgYéíí÷-±·`¼G#QêŸ2Õˆ¸Í‰ñ1O3«úÉ`nVýØí¨Çhñ²„NF6¨'¬¾pûî´îLï2½;�…›íÁŸÖÐ]¼h1]}õߨpÊvøáGÐZk¯ãü²òìHçe�ŒŽŽÒ ×_GË—k/xñ i³Í· í¶ÝŽRé$5º?ýá‡óé®;櫓±’M¿Úê«ÓGåy¦Uì÷bìý¨5ZÄ›ÄÖÒJ©fÒ�ö¹÷Qû¡@&CÙÞ©4¾én”Øx7+pT-[M?×"õ´ ĵ*Eq­JKôĆg)ÔùY´«^6‘T�„jF²j ¦ho�Ô‚dÆ4÷k?ÕÕíÜ`uÚäw§ ·ÇÙ=Á ï3«&>_FÏ¿EÃo|Hc|JÉŃj¶ÝÂŒG)ÜÝAm+M¥î�fRïÖëQ׺­¡ Ðaq·\ÐŽ~|t{€>¢²Ë9ÿÜ‹¦ôÉß3«ÚW¹,µ¿ø õÜ÷W |®ë8×=•ÿJÊL·§°¯`_YV"�+4ªÿñ‹?¾A·Üÿ‘­ïØ�ÖY„U#‚?Mj6Îk¯½š~öY¢ 7܈úÚÁŽh�_öû‰D‚n¸îZ²dIq^œEö�C¥)S¦4•?Íñ�[oùö®<Š«k¿qw! .w§xq)E …)T)uo¿RêHÑRŠS(îÐBq÷`–@<Ùd“l’ÿ?3ììÎîìî¬ÄàÞçái³s®�{ÎÌ=gÞyïÄÇ?æÚ°Q#ôîÝ×&k*§‘§9ž–3¹2¥Å?Œ�—å›ä®¦|¹§É?¼ö­„Ϧ™z“O|õ{«A«ÆüƒåµX^KÊãX^‹åµÈ.X^KþóÈ\ÉҘגšÛ_±|“¹¶]Üòe5ß$GOì}·FKì}·‹Ñ—aþa\oEŸ9ë6þ›ÈòÉ–™-«õŒi€VŸ±gÓ5®�-ûbä´Ó"¡�tBí*îF«´QRååÁÕÍ­Ô«¸$7'Ô7éÊVÇ ê*ÛGe¨¿4spp@@@�MÀª4.𻓓S±1Ú–&›,Mc1å –øGë¡{‘š–+jºÞG…ð(oª·’¹NÇXc§-J±%-³²áà^L÷×ÂBä?òUð8¹Þ{Ã!IrÑ�»¢U?¤ ûØb•°ýÛ_Yl<ÅTÑ’ý•­†f­|5ç2Öl¿-Ιõ�^†«<Â�çpõÚ-¤¤¦�Ùþ~Þ¨P>µjVCãFuàåéa–ÊsrrqîÂU\¼t 1·ï!==nn®ðôÆ’�îHÍÒ°î—d<­ÈTàáÃûHNNArJ÷_Ef(æSÿSÇiAAÁèб#ªW¯aT¦ìùØÑ£ø÷ß½Bnnn˜8i2<@ýë¯5¸s;V˜ó AƒQ§®I½Z+ð´ÇÓÖêG]ßÚû½©q˜ã†Úbù&SZ6ÿúÓäöi�öY °@Rª�ªÈŽl�ìzí�[%0ãÄ,SþÁòZÅð6Ëk™ïàÅTƒåµ +šå}‹ÎKc^Kj¶¦žÖjˆí¯4,M{šÒ4S6f*>7UßšëÌ?X>Öû)ŽºÌ?Œk¹(ãóé ¢õÊZ>¹8l”õÁ4@`€UfLZØþ_<†M=%Òɶ…P·†§AÀ*}ÉO`U7÷¢= Û EG—Ú™‘дEŸÚmÐ×`ôâª( ½@¢ùYÃ&ªþ’†Uýým2V²j¯¨æ-¥ËÒd“¥i,¦ìÎRÿhù¤g扚�ü¸îa¦z,þë” ³wr²IÇùYÙ #ØÍ8˜Û9õSl`U9�“ààæfÆØŒëwpë—uPÆ'ûAuÔxkœýL•méqPæêÖZù´‹·pù½yV5ã×<ÕÞz±ª#•™˜V’-ýÃtoÒ¶ð�Ø¿€Gõ«ÿ­ì‚` «zϪžØ ï=Kà�,fT•šUv£ÎHzyº¥*áØÔ‹jŸÁöWše)M{šÒ4S†kéþÊT»r¯[ë_ÿ…ÕÛÄ «g6<‡ðʦÁ‡rÇX”r;vÀ¶�ÿ‰�ºýQ¬Ò¹SK èÛÕäÇz©©éøgßQ:zZ•*¹*{l=‰œ<~Ïi,žNOOÇæMðàÁ Ø·_?øûTÉñcGqüØ1ÈÙ¸ItêÔÙ`|Kr%”[Ho¿ó.d*ULÙsRR.œ/Möï?õ"# !:ú:6nXòk©Ò¤Iô|¾7w)!!žcoUi1ÙË�J»÷è‰ å+H¯›ñôµkWñ÷ºµB;~~þ3f,�9fU¹ñôáCqðà“öÙ¬ystî,¶Ï}ûþ�ƒÍY_0w[·i‹ˆˆ:Ugè›���ùsƒ"KÁÕ%ò”)oÂÉÙ6ñ•Ô€Øý^®…ƒí‡ä«Ê*ÉÒd“¥i,¦”jêùÁÝSŽl€ß_ß™jŠ»^àáeÝ6ÈŽheÝV(t5þ±­©ýËkí¾Žåµd™u‰±¼–aµ³¼oÑ™diÌkš­©ç‡5Zbù&�öJÓž¦4�Å”}ÉÙ_™jÚëÌ?¬Ñžüº¥É&KÓXLi�ù‡q 5¤¬ç“MÙ»Î4`K 0Àª-µÉÚ*óØu(CÞ:)šÇ¦¹íÑ0 YJýé•¥c§Êü♷Ĥb hX½9¡nˆYÕÑÑÑj•Ñ—ˆ.*‰ÔÉ&sr”ðô4 гz‚&xVü£ÙÀ]Pdç‹´QÿÓB¸…h~*,(¤óAaçX4€m9k™Ÿ­„ƒ«‹Y,†ÚU)²€BØÔipì……P)²áèáf“1›Ô1G&¥ÀÑÃn®&Å‹JÀIË¢›n»ÉÇ.ãÚ—K$»ó¯ˆr=šs×ò2² ¼û×ã ¼§96V]Ñ%Äu¾yn‚‹kèzý0ÿ0¡ú§Ì?b×�éV÷¯èŒr–û¿�2ž‡ÖÃëÀ_°OùbLÙí#õ…÷JÌþ uÌöWͰýU©3ÏbÐ×s£°z«°zvãs¨Q©h� ¶˜à¾ÿŽcíú�²›êÓë9ôêÑARžXþÙw [wì7¬Ô®x1. Q÷ø¯·ŒÅÓ+–/Ãm-ÆJ_??L?IxþÜ9lÛ¶E4¾.]º¡e«V’cž3{&RSSeÏŸéãÇ7Þ|Û¢� éeÀ²¥Kp÷î]¡Ïá51t¨qvý½{vãĉã’ã¤X²o¿þˆŒäé‰Ñ”˜M--ÔÞ Á/ víQæÜïÉæý6)©)\N÷Êxøúúr`U*râé“'N`Ïž]²§Ò¡c'´kמ“¿sç6–/[*»®” ­Mï>}àé!y™ºß_¼x[6oš4fƒV �öÐyyÓÕÕò½‰µc`õsüÃ�¾X¾Éö–ô4ú‡ÛùðLJæ+ËÎ9ÕêCY·-²ë´†*Ì8S¸T,¯e¾ÚeÕ`y-Yj*I!–×’Ö>Ëû�UÚ*ï[Ty­¢›¹¸e¶¿ÒèÃTüQ\kBý<�û«âÔŸ­úbþÁüÃV¶ô4¶SVü£,瓟F»as*Ý`€ÕÒ½>ltŬ�½GaÐë'D½þ=»-šÖóѬ‘^JÑ1s¥½¨YGJ’]µ¨tD›“ÜÜ«šjÚwÒ1«ÚbMéŕ⫒Mfe)àííSTê–Ýî³ä�ì‚Ri°Ê�áJI_ÅÛ»ºÂÎ^ %{QŸæedr@ls˜UsÓȈŠA~VÜ�áäë·Jåàäe˜™š’£-®’“˜Âp9P¯DÉILCv\rS2àèá �šáâïmÕðblFÂÎíÛ•Ç>�‚ž)šr“Òaïä'?/¸W*— _«ú*ªÊq+÷"åäU¸–óCÒÁ B7¢Ö‡#õºÍ¾ÿñÛŽró.Pj˜Ù\BÐ`Î;pô�w{nRqñÈK΄{¥`x†W´xŠäy™Ñ¿¾r IDAT9PÞ{dõúZâæœü)íÌUæC¶?™Û‡®¼)ÿ°¶}9õÉ?ôog¦ö˜UÀã#ú÷Ã}Ë:#$H>(D½¿rLM€×¾Uð8¶ v¹_8™˜`êÀ·‘ÙÑ8 IŽŽl)ÃöWm²ý•e–õ´ÄßÌ»ŒU[n‹”p~sgT«P|{KV€ØO?üìgdee ÕÔ¯�Ⱥ59fÔk×cpér´¨éšáUðÎ/ëu§Tæ`Ñ’u¸|å†èZXX0êF„ÃÏ×ii8pøH–Š*ß»/ÖAZ¶ ÅÓñññø}ѽþ¤€’ümÎ,¤¥¥‰ä È÷ÖÛS%?6$ÖÒË—£ôÚ÷ôôDÓ¦Í9vLíBû[:.>8Xÿ9öL SŸª �_'N| ^ÞÆ÷‹�=ªË‘©È�§MÛvhР!üýý…߉‘vñï ¡Pð ŸêBcïÚµ»(ŽÍ/(@bâ#DEEA™­±]P®¹÷û+—/cÆ¿…¾ DÚ²Uk¤¤$q1‚œxšúœ5ëWѸjÖª�ðáÈÍËÅíØXܸ!¶ÏÊUª`Ô¨Ñ\¿×£¯aÝ_Iº1É6lØôu�2[‰¤¤Ç¸ÿ>ˆýV·@zĈQðóóãíVFe¬ägçàñ¾³pòõ@@žµËšR�§Â™—§#/‘’¸W AÃùïlRŸ„?®AFT¬ Ü­j¼ó¢ÑadÞ¼�¸å»�ròì´Žøõk�°Á�ðpó!¤œ¼·òA¨óýD8{A—tô"n:Â�„ÍY_){ÌKÏä@áæ€¹ÍÕyÜŠ½¸·F¾?jÿÎ’�x¸å0Ê=ßU_íctÆüÃÜñ[*oK°*�!fµÖÍ?KŸCX°ô1ÐRcw|ï½Kà~f`ƑӺm%Žÿ Êzí,U�Íë±ý•F¥lesó*s þoþ¬Ü¬yVÑ.l¥°}#?ÏúSÐw�®íпo‘þ¯GÇbåš-xô˜gÅ<°ºt³•R\ó뜥¸yKž ôÃÈ¡}Q»V5Q{ ‰øzƨòø÷IîØ}©6ÖüÒN2ž>rø0üOÏ&ˆ©sò”78ð£º\¹rÖk@’Ú•ˆ1TêxwŠïnÞ¼�íÛ¶"3S}åÕ  Ñ: ÁV™œ’Œ… æC•—'´Ö«w4jDÀIÓ…€¸ ÌÝ©øùúaòëoHV¤5yüø1V,_*ȓΦ¼þ¦¤<c¿yó&ÜÔ€¾0djÕŠàê›O/ýó�E–Ã&½†,E&—‘Oß¹‹åË— ãmÓ¦-:=×Yø›æ‡];·#9™·Ï.ݺ£e‹–‚Ì¡Cq#:¾~¾ ­ºÔ©[ÖÓErrΜ>�³gψX‚IׯŒŸÀÅîrãéÝ»wâÔIÍÉ<“&MF@` é…–)ñ¬ÅÓ2ÕRìb–ø‡î Y¾ÉöËö´û‡ç¡¿á»î{Û(ÎÁY�:CÑzrj±¼–q•³¼–aý°¼Ëk™{Ãby-ëÁª¤s[åµÌ]?kåÙþJ£A–o²Öšž¾úÌ?˜<}Vm»•5ÿ(«ùdÛ­k‰i@¾`U¾®˜ä3 �ƒ§Ñ{â1ÑLWüØ m›ø €UbÔ Rœ`Äg@õfOÑÖ›__›µGöAÿŠÌLÁ­B‘ip×ì0PáYô�z½¶s˜CíB€U×àäg)K¬ªà˜]-a$¼·v?â–îž°K-yØ�ލ2¶·Aó¹»|7î®ÜkÒ¼ìœ80fÅ‘ÝQ�“'/1ÈP•¥Ä‰AŸrE§@4Yò!Ç>jn!�dfô=Ø»9÷QMØ;: 7%�ë�˜µKaAbæmFÂÖ#F»qò÷FäÏSÀ­9c:úü4 @ v6Uß+²*"¾Gw $Íë̘éà’æÖ|íWFõCàÒKSçB̓OêÏ� Ïj¡¦º6x�ÚS¥gàæ¯ë‘zêÿŒtuFËM߬Cú%¶Úëÿ[ŽÌ+£):uD×´Å´äôdì¸cosr”ðÒbkߥŒôó¤=j###�/yyùÀE—¹Úи Î�>fà÷WŽtï74#s [ZN¬O@•÷„¹ž>©Zë�BÓúг½\G-¹‚BÝøC†Dz�BÔ§“•* 4@Ÿ¾ý šßœÙ3‘ššÊ]¯R¥*FŽzɦ¦J÷ºåË—"îΡ]Kú™=ëW�A¶jÕj1r”Ñq~ÿÝtŽ�”Jµê50|øƒòwîÜÆòeK…ë/†J•*› VÍV*ñó�ßs÷w*Í[´éŸþ6'ž¾té"6oÚ(Œgô˜—Q±"oŸÚñ4ÙçÝ»wàâì±ß*Úº Æ„ “ ʦ¦¤bó–�¸§aGÖ¯�:ÊŽ§/_ŠÂÆMë…>ú÷ˆz‘‘6±«g1ž¶‰âlÜË7iÊòM66.Íyí] Ÿ­¿Ù¼SU¹*È ® »Â|d×kÇ�Xµ Ëk±¼Ëk±¼ËkÙüÖ+4X’y­¢›•ù-³ýÛ_™o5ÏN æÌ?žk7¦eÑ?Êj>ÙüÕa5˜¬×¬Z¯CÖÂS¤�£ç’Ñã18i錖èÐ,Y<Ù +¥@J¥Je¶ìJRCÖfºðñö…›»õ/�Kâå÷ò 3Þ>¾ D]B¶Y§çv½žë}¬‚“[&œý|JhTMîèæ¦Ä”3 ‡[� ö7ÍKdCuèUuóu_ÁÉKßèØ÷˜9 „œ~½TGÄW¯ÀÁÅI$ž—‘…S/|&üVï§Éð®[Uø;éÈEÈ—÷ˆ;¾æÇ/Á-LÃrD€JÇ€(1–Öü`8ÇÄ© „ã¹~ú �ÿ9-gØêÜáÓô�ó.P©õÞ|dÇ% æG£ôi-¬Ò€HOu§O˜V“Ž\Âõ¯5 „Æ~×ì¯;ÈrÍ‘µu¾›߆5dÍUWˆt›—–—@Üúm£àÛüï¯áè©h!P!±‘’dÅ%àüÄ…u©0ª*�è¦7–øÇ3K �3ت“ú!´Ÿ>k%­oôw+�tà‚œfôÖW×k}þ|"« `UKí±Îô pöO¬ \ŸÔž�o㚨õùËzþ”ó8gF}#ˆV�<¡}Úç¤dpºN9¦uŒ²ƒBûµA•q½dBe)V†�YI}bq¶·çXnM•˜åÀããúr»þè„J¡îp|tþË¿„ó�(ž9U-J7=îÿM÷aj Âu53«!€©ì†˜ ÓÀ³­�B'g-fkëÉ€œ–?*s ‘›§ù2©…ðötw«‘¾æz³@.ŒT»¾zÈóv]ð‹Q×1wÁ*A¦}Û¦þ¢qFmÝïÞ{ˆo¿_ €ÝÝ\ñÙÇSàëãe°ïC§cñïóáêÄ‘ží‚†¾ªOgþÿÇv¿þü“ÁvZ´l…®]ùý±£Òìj�¤¿¿?232°&ë>eŠ4)±‹þô£†©Ž@‰íÚw°©³Ó&1nª‹““ÆO˜$3/·3Òé… 1³C«±òíÿ¾æÀ�Tš4i‚žÏÛ›íþýÿ Í ØÓÓÓìxúÚµ+ø{Ý:¡�þ 00æÆÓÑÑ×±ö¯5B;êñ[OkšIÿïð‘QÝîʕ˦Xbó¥5 ’µ\�aáÂy‚lÛvíѱc'ƒuýVÿOúšÄ‡#R~¯ûA…ä½Aï^cÝ}ÐøG1ZÓ±ö>¨µ§ÒŸ§¡{47YÍ tõhpLš*z}i}€¢ÊχJ•WW7Ã÷o]}ëôI,ÁÄ^Lý¸¹¸ÂÉ™F‰¿s‘óñ‰f®Ü=ÐŽ†ô¤žÌ—dÙ�[$6SÊ�¹Q^ÁNçÄ >ÀÑßB›~ÛwËùè‡S¼¡­»èùª+dè'mw–ûñ˜v[†ü‡¨û‰­p?§¹_ ÒBLb›8$eèÇP´î'4ÏòZ,¯ÅòZ,¯ÅòZ²¶�f •T^Ëì�qö>O£`ö>¯ˆ�­ 6ÏüƒùG4ÛbrYõ�é ¯`ùFñ‰]—¶vFå0ë±(Ŧ|ÖÓ@1i€V‹IѬ›²¡�ãRÐm¬øŒØß¿mŽ.-ƒ`µ”,¡­7'Þ^>p÷�™;ezÁVœÌ»Üf¤§Á×Ï¿Xû5W/O³|~~!"{ïЙb!êNË‚g•’Ûxæ¥eÀÑÃÝ"°*½;=ô ä¥ñÇÒc§‹:ðЍÌý�qõ I,—ÄäØlÍ—pôа}’LÊÙh\ùx‘èÈö .MQit8ùz"/5“k'ñÐy$º$zÒ¯-ªMÒgÉ:5êkä=æ�›¯<¾ÊäÁ÷×íÇ�ÅbаGÍJ¨?óuîe�F¯}ñ'ROóÌŸÚ% CCÔúp¤ÞïÄä3[ Ž èÐ嵇[år•˜Asâù#J�ü½ÐlÕçzí$¼€èo—s¿um†ð©šãî“�_Áµ/þЫã×¼B¶‡W­Š00'1ÉÇ.ãÁºýœÞÔ%üÃêЈû3~çqÄÌÔ“Ûtå§p�K;è™—¾A~¦Rh«ÉòO,bÏ$°jnr*\‚ü9ðìÝ5ÿâîŸÀF£%Â-T œ-,(D~v6gŸêrñíÙȼʳ’Ñü#¾+ÒKÆõ;¸ôö­o‹TÙ n‚‘vñ¢§¯@�’gS—j¯BH/ñÑÆœÍü½w~ÛŒ¹ë«m�G÷@Åaü1ËÖÙc#ÔúPŸ-ùô5\ýôwØiÑ\ZãO¹©™œ�«KØàލò rÉy”‚¨÷æ ¶­k ºv¬gÀ6ü!?+ö.β²¹¹°st@ܦ†³x|LÿeïŽß;¢Jy„|5މ÷x°*kÁ¤FÛP°¦†Í®3 0 0 h4°ÆøG5 ¼ÿÉ� ‘*vêÐûuú䔥+6âØ‰ó‚è°!½Ñ¡�4s¹ZˆâéO¾]�Á‰B½fí^À€îuDñô…óç±uëfA¦mÛv8|ø�ð·ö÷ÇŽÅ¿ÿjûéèø˜˜бòêòÖÛS9¦nÑFöí×õë7�3}Y2)))X¸`žèˆùîÝ{¢Yóæ²ê«…ˆ¹ô§fuhŽmÚ´5ØÈ~øþ;�|§ÎhÓVZþvl,V¯Y…|"öôòÂK/�†¿¿á�› u¼ÿ>y²N...9jV57žVd*0sæÏ"û$�uêøœ]Ìg}ÞµkNŸÒ0¿;í}“§§$&&bÁü¹Ú0szFfýú³ ¦¦Íš¡G�ç ®W…7̳³Œ‡ 3 0 <]à€©R Ô'q‰pðƒuÀÕwo<ür ]\ÁòZ,¯ENÄòZ,¯ÅòZ¶œ”d^Ëö³±¼Eö>O£;ö>Ïr;zZk2ÿ`þñ´Ú¶-æU–ýã»W±lSŒH QÛº R¨ô‰U¶Ðkƒi ¬j€VËêʱq‰N]JAç1bÀêü¯š¡g»rP(Í;¶¹Høäˆêa7éSÍ-íJv=b®tps5z$¼±Æè˜öÓþDª¿3庉_²æ&¦!ñðExÕª$YÕˆ}òü+3À+ý:¨ª¾*Í•~9†”ª2²¸&èNÛpþ»ð¨"&D“ñŒ˜ÁÝš¡Æ;/"õl4.ëcÕ•j}úÚÔÇ­™ë�°ó„ô”ííÐdågpñÓÜÌwöåé(Èæiµ½=þþpø5©%jCÔjçìˆV[4 µ 9ϱº³u=D|6†ŸcANùL¥ß«L쇰þúŒ 9¹ÈILÃ…)¿ ã h×µ>æ�ŠÕ¬¶Üòì�éØlý¢ Æõ¨Q æ¼-Û¾Ô‚X5).A ðÞ_û·Dã $ÖQêÈvb;Mü�Äx„WDƒÙo ã!ù “AÖíxá7){º»z/î.Õ°Æ’põ·‡ \w±í*î&àÒ³¬^ßâ³Ç œÿTé¼P1æO¿úÅP=œKùS�*Çû}äçsívlˆšŒDA® —¦þÅ�»Fí�ŒÛÕ7ÛfÌ©`VR?'—³A;GùÏÂ[Ë€Äú/y·Îo‡šÞÙý¼ÏfUë^ó¯fh5Ô¬šcL–i€ià‰LVIjɲ 8qJÌ&îç烞ÝÚ£uËFp4rß¤Øæ­iß"'‡ÿÄÃÝ ß}3Õ$Ø•âéWßÛ„–5n K^¯#Æë(Ч7n\�ËQ&ï _ã¬îßê�{e¯¨lÝ’v™0ÿ0e7Ì?lwÒnqãAf,ºŠ¥Ä€ÕËÛ» b¬š²{výÙÓ¬>{kÎflD箦¡Ãȃ"‰9Ÿ7EïåJÃ*½h¢cŽŽÒ@$9‹KmÐ˹âWÊ—)ev6rrsàããkJÔàub¢IMMæthKfU‹daE nÓRS8°ª5¶`a÷¥¶ZIø�ÂY¯—˜©‘Tÿ‹B¸É;QÒ¦úÌKM‡ƒ‡ìe2gIuN µcý>ØQ hYýÍ U®ÛFì‚Íx¸QÃ�å×<µ¿+yÏ)TåC•©@Îã4\xc–Ч6㣺}ícì=ª‡¡îŒI87þä%§s"ĸ™û8 Y1ø¿[Ö�óÑ1òåz·Fhï–8ÿÚ/[gÕ×ú#´¯†‘*nåÜ[¾‡kÃÞÕõ~žÏjazªz°ñn/à™Á\+£ñïïéÉ\zw.2¢ø Ä¿M$j:šûÿÜä4œù�ˆ1Ô½j(Λª×%-é˜s{'G\ŸNÇØ?vjMí;‹›ßóÇþÒ±ˆmvþ`ЮÎOú Y±…ë5¦EpW1ÀÁ”QX5çq\ƒE AÝÄ~ýYo³fESÍáò‡ �vî'çQõy]¨£ÍR«^׈Ï_Ö³§ô+·õÎQ_5ÞŽàç ¿‘<Ør÷WýcÝú"fÑÄoàíÜ{,?¸#ÎŽ�.i�ä1s7 a‡pmÌŸÔͼqפ?�›ð#²ïð `ï†5Pﻉzàî�¾mQqTWdßIÀ•Ï£ ‹q»–D£EïÉf35i:ùÙJžYÕ^çØQ‰†´ýÜ~n.’Nê¿ÜÝ2¿=júå ì“ç­`W-ä‘÷T´Ù‘ áR ²(™3#&Ë4À4ðÌi@`U¡ÈÂ÷¿,FB‚ì©Ö“Ÿ¯7úõé‚ÍêKîÑ{æ4vîÔ|¨C̵t¬¼ŸŸŸI=é ÄÅÅaÙÒ%ÂÏcÆŽC…ò ¶£ píÓ§4lÈÉÓq÷·boáàÿ!á SÝPpp0lé�kV¯ÂÍ›üž­z�6LŸ^îä³³²ðçÒ%"0²º®··7:vêŒÈÈHYy‹#Gcÿ>ÍÚ´4WCEOO£Aö>OÚšJâ}žµvm«úÌ?˜˜²%æeòýÂ+øs£æd(Zï+Û» ¬š2}výÔ¬>ƒ‹Î¦lX—¢ÓÑfØ‘À¬O›¢o§’¬Òæ„WWñÑÛæ¬'Õ' jY9¸433ƒ;.ÐV`U_?îÅhY,´†ºõõõ7ÉpTçgé˜KÊ?è�AÝçK`•«º»ÂÞÙÙR5ò¯G qõ‹ß‘zòºÐŽ�“#ü[×CP§FðmRË {+�]O ûù þ¸yçr~{§“—æøwu£z,ÈÉ�£§÷ÓÕ¯þDÊQžiË£f%4˜õ†hÚ,¢$ êÒ ÛŽq2N¾žh´ø<ÜzwÿÜÅýfïæ‚B• …y<£”wƒˆør \]qaÊ/PÜä¼Êõj…ê¯ú:3æ[á8ôòC;£ò˜žzú$ÙKo΂ò‘ØÒï§F|�¼¤4N¦ü�N¨<¶ÔIKb^½5gƒÀ‡R®OTŸ<@ÔW¾2vövšÞúm#¶áu^ fǫ́IG.áú×K…ºÍÖ}%©óô˱ˆšªŸ¸„ Ñ¢i°7ã#�Y50@�ÑR°Z÷‡Ið‰¬®§?í T*œñµÀоj}Ä3ÇR‰zÒ/Üâ×ÔÝ�½ç½6s§ą̂oD¿×ühÛóÇþªýãÜø­Z_ò�œÇ‰H>~ ·çñ€e‹ì±a Ôýv<Ê”²GÒ³*C�s¯þ ËŸtbÊŸ¢g¬Dâ~ž!�ÀÒ•F÷Àµ/4@5몺ݻ«þÁÝe¼oQ©ýÅËðoi˜ùÍ袹hNR_×?ÌéóæR;$�Ô¯±in{Ô¬ê…�o_„ãÃó_üeS5ˆXµŠÉœy3Y¦¦�§H2«4ÛôŒL¬X½/iöuÚZ¨Vµ"Fë‹°P1¸ïüÅ«˜¿h� :dPO<×±¥IR<Ýcìnôi¤aO-W¡.Þœ8X¬>Jx„… ç mU¯ŽaÆ#!!‹.~@å*UAÀPuy¾Wo4nÜ1±·°jÅ á÷z‘‘èß ð÷åË—±qÃß&Ç«hÙªºtéfR^Ogfdbá‚yÈÍãh©tïÞt¬½%%:ú:Öþ¥Ñ71ÎþúíÎ�ÛX¾L³÷“Ó§——F� _?Ë>¥�?×®]#0ÊÖ©S½ §kƒ2ZÞ±mhþR¥B…Š 57>¥zº€Õ±ã^EX˜þg$«O“Îccù�˨¯1/�•5]Àp—®Ýвe+ƒu`U–Z™ÓÓi@Ã*'G!„e'5:º iÜ (ë¶ætÎòZbÓcy-±>X^‹åµ æYY^Kò¹UZòZ%ùPeïóÄÚgïó¤­±¤Þ畤oðû.ö¾[{ ˜0ÿÐÖÀÓä?,¾Š%‹V`µ¤ïÀ¬ÿÒªX-­+ÃÆU"¸r3-_Ô°ºÐ ~ü 1^è&:°¸G›÷¥î<°Ë’B/˜ˆY•˜_ÊJ!�jrR"\\]áååmñ°Õ̪Ô=]\\, ]C IDATn«$+–¦Í;­�µÇhÚJ—%íuz–<`•ã¹¹r¬„Ö:ª^I,\öö¸ñÝjd^½£×�CCv@H¯ÖpôûRÚ…›¸üþ|¡ŽÔ‘ìt‘«æÂÑSdÕfPu ðA³•ŸŠú~ôïÜüaµäôª¾6¡}Û õÜ \ùPtÐŽüõuxÕ®ÌýtåóÅH=Á3k�/ø—ÓÊødœó­P�@¤AÀ5$޾P¥*�|ú:îÿõ/r&qrönÎh¼è}8ŠA”Ä<ÖGÃT[ë“—à׬¶èˆ§s~àØ+©TÖ… ª %8‰%ÅÁU£ã«_.AÊ1žʯyD|Å�;ãz U—ú³ß„g¸>³éµo–"ùð%AŽÆÐVþÑîX59.�~ÜLùÓ�%;9;ælØÝÎNÈKå™îœü½ÑhÑû"ÿV)”8=â+(y`N@‡F¨õ¡å¬jRc6ç4)ÿ0jh:o.’Në³mø­jWó†û±-ð_-@›Ó>'«û²Ù+’Gyš=.V�i€iàéЀLÀªz²§N_†Í{�’Ê3ÓkWWL™85ªW~>vü–®Ü$ü=nÌ`4kiRwO÷ze»ˆa5(¬.Þ™ü‚OŸ={;¶oÚjÓ¶:uzŽûû·Ù³�’š"Ù±‚¾õöT¸¹¹!99s›-Èé²c^»v¯[gr¼$àà舢ví£òêxš>þ\¹b9nßÖ0%Tª\£F�–Å*ÕIÔ¥KØ´iƒpiÊëoÂ××0°Tàjj¢~}qèp£mkCO8pÑ×ypiÕ*Õ0b”æ##Sc0výò¥(ü»o/ÒÓõí“bw{¥JûÔmK°:jôT®Äïûµ‹vÏpüQÒïeÙû¼’ò ­ç*{ßm0>gþ¡QMI¿ï.)OyÚž?ü~ KÖóD<ê«%e]¬ßÒ®X-í+ÄÆW¬¸›‰fƒ÷‹úünZC íY^t„aqŠ6' E&¼½õåäŽ#K¡€£“œ­d^”ÛŸ-äèK«ª‡‡§ÅMª_®³¬Ÿ_@™ìjOš^®¥¤$ÁÇǯÄ·d“¤ÏÒX- þQ’‰ý‚Ü\ä¥+8à§6°Ñ‡)ÌÏçÀªN>^pôpý�xø"â·޵×n×)П�ùþèŸÓ¸ù£†ªÉêÏáâ'>†ˆŽ9/ÈËã¶ÚåÞÚ}ˆûƒ?VÕÁÓ -þþZt]ب¾HÚÆK?†ƒ‹p<1èSØ0L«xÖ®„ú¿j[oÍúÄpJ…ŽX�øj÷ÿÉ'®àÚ瘥¾Ó†!¸s½:Ù“pîåéÂïÄdê(zjVÆtD•±½9yŒWXw 4�EO¾ø¹p,{…á]Pé%àªRäàä �…¾Â?� Ž�DcR>LÂÙq3À�÷G ­µ*¡ÁL1‹­±‰Sÿyipö÷åX_¥ŠÃꌉðiPÃ`³ù9y¸ðÚOPÞç™j íìÐdÉ@˜Šî‹¢F‹ß‡[yi¶±áöžñT]j}6ž5+þaÍúêúGQÙ£oÓÚ¨õñHÎ?äø“!åšò§»kþ؈uÛ0dÓ7þ �öœâÄéžÓlÝ—stû¤{� ¥€Ðº²Rþa–Ó¸ñ‡’Ïè×ú{v[Ô©áû´D„}ÑÈW™Û´X^›qÕ`5³ý H<�¯——#ª¯{/㘔ôŠî�:ëÜi•’œÈ1ö»«÷WzMHu$þ-7G‰´´Î|}üá$‡©Yg,¼ãëôÅ1EiÉ:ºJ×ÑÓ›T?O”™§ÊCZZ*¼=}ô÷Éz}Ë›ô" 666ÍþJçk�ôôjDêÁi÷šŸ_€ìì,xê},'COÆKÇ›P/é,5½éÛ¾¤ñ낌±é®�îX ‘žžggá4†5ÛocûDk¸üûfòò‘�Œùp• ÌóUÉ5Ôžq}Ól§ºž¢R©pèÈìÜ}�c^Õ.Þ^žøâ“)p²÷8~òþ\®PŽ5-›ó¬åÆ ÅÓ/¾¶-kÜÄÊUjŠ7Ç÷âé�;·ãÌi kê Á/ "¢'OǺøPªÔª�† á.ååæaÆ ÍGFžžž˜U](ѽní_¸q#Zø­nÝz¨R¥*÷·½ƒœ�¹BCBBMÆWÚñô™3§±s‡æƒ5²q:‚ÞÏÏÏ”z ^?súvîä÷ÁT¦N�7wý Ô×£¢¢°iãz“ýÑØš4i‚Ž�ºÀÑQÿc#“ ÐŽ§oDßÀþýû¸jžžxë�Îå´eL†ìóÜÙ³8røˆyU»P_&½Æ�•¥Š.`uøˆ‘¨VMÌò¯O_½rë×kXx»t뎖-äùÕÞ=»qâKÐsðÝiïµ!ï]‹EÃ.(àãiúÇÝûˆœç¥©gG¾hâ¾C·¦‚BäååjÆor,ú÷cUn.— ¿â磻JúuäÝçMÜûåÜ ͧPædÃÑÁ‘Ë•isÆFÏîÜ\~ÿæâìb"Gbê9%GO¦ukÚžôû!; y8;9ós0µ?“²/ÉõЯÉ=g!Ç:¥ö-iÿ0­“k¨»ß”²ÛB~,ùù*8:’�HØ£I žäÏèd n^&ê¸Ü8MÇÞèßꌞä ÿL Õ‡Ÿ­G�s« Ëki>ø•‡³¼–fOÁòZ,¯E÷í<+Ëk™ÞsG^Kþ“Áv’ì}žX—ì}ž´m•†÷y¶³zù-1ÿ`þ!ÇZ˜<=x�_Å: «WwtEùr–Ÿ¢,dž˜ Ó@YÔ¬–ÅUcc.2 ÜŒS ñþŒº|óvŒê[ON¸.²¾¥¦ÍIFz¼}|-fd¤ÃÕÕ­Ì5SS’áââjôE�©ÅP¿\£„;�U‰ §,upëííËLJ²ÐXHŸÄpTÒ¥´øGÝç·ë½Ï©ÿE!Ü Ÿâi‘êˆÝQý’ƒ ¡2þ\ýõÀŸæv@ÉveÂc8ùzs`UÝ¢ŒOBÒÑ($þwŠè8á²£·þ> ÎÞ<¨ðzí¬¶¨Î ä~zü—}fnÓ†å VÓŸ�ô¯Ø®-±ý•FAl%m,¥eUlN¡Õ‘”üüÇ5ü¾NüEüµ�]\²{rcú¹zí÷„×Ðg˜¤z99¹Øº}þÙLÔÌà�=Ð¥¿¯¹|õ&fÏ].\ï×»3zvoorY(žžôîbT/Ç3ÑS©þ&�i'ÄÓKÿ\‚»w5ûɉ“��“ÕeNÕîðšîanÿ~ÆtäæòÌßüûð£OD1óéÓ§±k§X:yÊ�Jµãé´´4,˜?Wè—úîÙóy4iṲ́nŒ =rûöý#ˆ¼ÿÁÇpr2»ž?wÛ¶mÑk’ôàáî�  `T¨X‘õëÃß_ J2g ºñôÇ@ë§.¯¼:žüšSbbnq Ab¥•*´¦þÛ/BÕ2Æ¥z «£^Bå'àdª¯{¿ÏËSaÑÂùHNæí”ô6yòðõ3¾×U�eÞÜ9HJâ놅•ÇØqòŸã,ž6ÇZŠN–í‡4ºeû!i;+‘ýP¾ Þi+ XµÐòʇ#½ë8Ç]�}V2;G^˜þG¥,¯ÅòZR&ÆòZËkææYY^Ëø ÛPÞ×ÜÛ¼œ¼–¹mZ+ÏöWleʆJdejPÅt�ùóS¦Æüã郔Å|²)e×™ŠJ °ZTšeí–I ÄÞËBƒ~ü¹êòå‘3°ÙÅ;%Úœ¤¥¦ÀÇ×Ïbp ½`¢—•rÁ…ÄjB²ÓGñNYè�˜®¬j 8SýrÍÁÞ~þ²uPBS6Ø-½Â=íb .¿7W¨Ñdù'p â_üC%õeïä¨LËy”‚³¯Ì@a.Ïfܽ9j¼Í3h©‹$@ÐÁMW|g-×[s6 aÛQ¡­L“%Â5Tó²^.`Õ%Ä9�Ó„#é¹yðmT•Æ>¯ð ÍüÑ¿gDGÆ·Üú7wírnü÷ÈŽ{ÄýÒ¿-*¿Ôª|БóÚ%7=&þŒ¼dþ˜T6˜ó¶HæÆ�kðøž­Ì#¼Ì~KÐ{Ú¥\ùh‘†]µzüöŽ,¥5£/ÿuÇ$UY°9ûmx…—çÇQP(bf½»z/î.Ý-4cïêŒF ¦Á¥œ†�,~û1ÄÌæÙ܃}ÑtÙ'’cÖÕµZ¨êëÚ«µPG*g}uý£¨íÑ·YmÔùš=ó'c‹'ÇŸîü±÷׊å©Í:Ó'À·‘ô‘¶ƒñÀO„Ã뫽>È `[–qqÀû<ØÙÙÃNë%õ¥üCn_Úr7Û!ù¬~Í5¿´AýÚ°Šó­óð<¼ùÞAp½~NnZÒ�Ñ:iýßDÆs#lÞ®Tƒl¥Ñ Û_I›\iÚ_‹ShubÈ?~^r¿¯û~ôîn t)î!ÊêïÌÙ(,Z²Ž“}müpÔ�4üqÊ�C'±z­ÐÙ ~mLzuW—Xßûè¡ÏÚµªá­)š�J æÆí4|;c&\ù}"»×l2ã^¨!ÄÓ?|ÿÇÚI…>„ûàÃ�E@ÓåË—âÎm C+ÉÑ‘öÄbª§ÎýmŽ8$™7ÞzÞ^fÿsçÎa»¨sÚ{˜dRÕ�—vß›c±•SX<ÍòMrì¤8eØ~HZÛ%µrIº‡Ðÿ‰ó –Úƒ²v+¤õ™„¼Šµe5ÁòZ}P~`NW,¯¥1–×X^ 07ÏÊòZ†o»%‘×’õ°�PQÅ6Z±7ÁöW¥kÅÞw» í�ùó] <­Ï�²–O.]w 6šgM °ú¬­8›¯Q Ä=ÌF½ÞfþôµzxeHåb¬ª“£Ä¬j +(½P’ >¥—q..¶{ñJÇ0ŠŽ¹“i{ E&wÜ–5cQƒU��àëço1;­Ì!™½ÐJII‚—§7w\eIƒÇº–À J›Ôï³*UñV¹£Éã ³¡š³$Ëy”g¾ºº ñàyD·’c÷ŒüeŠÁã×/¼>Šw¹®Êõj…ê¯âþ??'§†~‰‚l„PùÕ>(?¨ˆ¶�X ¯LËËPàÊG ¡¸q_z½_ƒw½j¢©$ºˆèÿ-ýоj}4J,Gsøv…ð›Wݪˆüi²HÆ`5íâ-\~ož KÀψ¯_AVÌä&¥ÃÑËžáåáÀ30+Ú`K’k±é[8¸ŠAÀg^žŽœ‡<;S¹^-QqTW8ûŠÛÎÏÉõ/þ@Ú¹Bwµ?ÿÖõDݧž¿‰+h^žW™ÐAÏ5FÚùhÄÎÝ„¼4X@¥Ú›ƒÒÓô‘§Ö¤£Ú¥Xw¥æ® Xm¸pÜ*s 1jöLšOìoëñh�æ(`j«êkýÚ·­¨ÙøÇ3‹¬ÚÙ¡åFb©ë0ûþc\zs6T™YzCª:©Bûµ~7w}uýC»›Úã¼�ˆß|„k^›ñ×�?³;¹þ»`3n<$jÊ;²êýðšQ»>5âkä%ñL¾A]š"üÝ¡¦\Áàus™UóssõüÃÒΣRÎvb¶ðU¿´FÃÚ†�tvŠ» �“Ûàqr'ì”âãŠ-Kê ï!³Ý`ÙÕÙþJ¶ª ²ý•´jJÛþÊ’•. ÿøeÉ5,Z+fX½±»Ê•RÀêúM{°÷_þ™R½Z%L{{œAUR¬øÆÔÿq€>^¾"¦½­aŠüjúoxð€ÿ°†€¥_}ú�{¿vãìÛ§9±ä^²:<7@ˆ§³•Jüôà aL^ÞÞxóMñG8]¹BÃîJÂC‡ G�â*–-ûqwîm½6ùuøûûs“=àqÏÍÇ1o¿ý.<<Í‹©´ãé3gNcç À×ÙÙ™Ñúúò:XOkVðÁ‡ŸÀ˜=ëVŸïÕ�ó É¢Ž§ÿÛ¿‡köÃGŒDµjÕe¹ì?ÿìÅñcü‡e+VÂè1/µÏ3¦CõÄ>+V¬ˆÑcÆJÊëVÕ̯R÷ûC‡áÀ~��:99�X~}|Lïï©ó­[6áÂ… Ü8(gñæ[ï€lÁTañ4Ë7™²‘â¾ÎöC¥o?äzù0Èû°TrôvöÈjÖiÏ�„*´ºì|0µÅòZ,¯%eS,¯°¼ø\±©<+Ëk™|ŒXµ4䵌 ´(âi“Šy"ÀÞçÉÕ”|9°øC¾µ�$‹?J_üa«•gÏ}M–µ|²­l�µÃ4`‰`Õ­±:O­ÎŽX Ï�›�¼” N6üÃêÐHTÏ`•ûY<à–J`§F¨þÆ`8¸™è¸õbÛ(´Ó|ý7pô|jøWkª_˺ˆøBüÒ>'!Ñ߯BÆåX¡ÿv‘¨ý±4ÃYÔûó�~A ªÑU¤ƒ§š®øTø©+G,¾ĺí*Þwþ܉ûk4,å�×r~H™€Ö‰/âΟ;�›�"ê.t@;T�ÐOoÍ3£ïââ3…ß«L쇰þjæÍû¸öÕä>JdèI­>è½âèî¨8¬«pÍœõ•òíÚÒoý¶ [ùc™µ«ô·”?¶×0¨i�ɺ5g=¶‰�‚®óíxø6Öµ,uO‰zo.Ò/òÌrîUCÑpÞT)1“¿‘=PQ™�U †_•".&@R&;Õˆ^˜�ä³y°sßßVüØ �ëò`'£E•·Kàql \¯7%môz¾âß[‰BwÓÏz¶¿²JÕ\e¶¿’ÖaiÜ_™»ÚEå¿þy ÿ?[oîé†àùÏGsçb�ü±q‹&ž}iD´n)Þ©ÛW(²0õ xT›a•dtX‰­•X ÅWñ ‰øvÆäæå SØs±6^ÑBˆ§SSS1g¶æÙ^±R%Œ­Zܺu3.œ?ϵӪuktî¬yž«߸q=.GE }�Ÿ0ÁÁå8°*�T’”’Œ¿V¯®Ozm 4Œûæè9%%‹ÌÍ­W¯>hÔ¸1lOŸ8q{Ÿ€kI¿Ä:k,ž>î¶i±ÇvíÖ-Z´ä@³EO+ Ìým¶À’ëéá‰WÆO€§§ø„)ý=rûöi>îݧ6l(¹ÙYYøé' ˯9 «&¾Æ‰é¤u<�—§ÂÎ]Ûqñ‰]©;íÞ½'š5o.Ë?~Œ… æqkN¥m»öèØ±“ɺ,žfù&“FRÌl?T:÷Cžÿ­�Ͷ†wo(Ú @Fû‘çégQ>–嵺 Òè‚îY^‹WËk,¯î$.SyV–×2~ë.•y-�!U<-ç¡ÆÞçÉÑ’y2,þ`ñ‡ySôÒ,þ(�ñ‡-Vž=?¤µXÖòɶ°ÖÓ€¥`€UK5Çê=•HHÌAx÷=¢¹M{%SFV+†Uz°§¦$s@Kk˜Uå.½hÉÊRÀÍÍÝf,¤4‡Üœ¸¹»Ë'GÇ'R±fÞêàÖÕÕ ÞÞ>e¬J@UzÁVR…ìƒz\\\K Xµ4úG£~;‘“[ Z¦úEX¥#ÕUé°sr”ÍxiÈvò•9ÈMIƒkP€ˆñôâÛ³‘yUÃTå\Îåº6ƒ“¯'òR3‘yëRN\Ž–§ök1þ-ë]©2³qéí9Ⱦ› üæ^- >�Â9ðb¾2ʇÉH={]¸è€z?O�‹Ÿ>pK›m“v-ˆÆ‹?�œbúåX„WDe„öi£'c°J‚qKwáÞj1Ó¶£·ÚÕ‡{åØ9ñŒŒöÎNði\Sr¬,¦þµ«MV®'{bð'ÈÏTríÑkoÿæuàݰ:PPˆÌ÷‘|ô" óx`ŸzΑ¿¾'/éûkÎãT\|k¶À€)¥œÐ�íQu|_£·ÒÔ@f¹÷ ›¿®Å£]šãUÃ^èG/7(ï'‚À”*-–Wu›!ýÚ¢êÄ~’÷kº]˜ô²nÇóâÜô®¡ÈŒŽCâ� "[ éÛŠ˜‡Èˆâ¾a/tD•q½E׳¾³l^Û7‚k�æxxí†le�ä‹·oGÂVžmL°*åO&÷nh�?Ýüe-íÖ¬•GÍJh0ë “K}sæßx´ó @ÓÁ-7ýOˆnª²-*vöö¦DÁ%õ3p ² `$ÕÙwô¢¤^ÒgÙ[ú}+4‹”XÕjØ>3®Q‡à~ñ\®‡�PËäŸ$½ü-²u1*ÎöWrµiXN�eû+±ŽXüa<þ˜¹ô:¬¹)RÚ­½Ýä_:«ããËÿÍÆKàÅÁº£S‡¢g­R™ƒß—¬CÔ ƒû { s§VBÝÜÜ<|þÍl¤¤ðÌÚTÚ´jŒ!ƒ{ÂE‡Qòö�û˜ÿû¤¦¦ ²1�püfUhÇӺǩGFÖG¿þô—ö—.]„ƒƒ#êÔ©#¹OÐf%¥ÆŽ}åBB„xZ©Tâ×_~ÚîÝ»/6ÒïR_i©iÈÊ΂«›+üýÄϺ¾bÅ2ܹÍÔE¥zõ6|\´E<­ @}mòøû~ö]¼x[6oÆÓ©Sg´hɳçGÑb}�0á5ª¸?)×qõòìÿï_`Z»È—Ú•Sˆéué²?ñðÁNœ±'¾G#é²xÚ6þ¡½>l?$ÇZ�˰ý�´~JÃ~Èwí xæO‘STÁ•‘Ñi²š=�BgWîƒ Kó±Ííey-–×™Ëkñê`y-^Æò¬,¯eüŽ]òZÖÓ€5`€Uk´Çê>uHJÍEÕΚci‚o�©�·ÆT/rÀªš ÆËÛ§ØÀ�™™pw÷°)XU©Ì¶dI 2ôBÕÒ¢«#©µc3gNêc¼½|ÌýšÓ�Ùôô4îŸ5Œ·rú‘#Sšý£Qÿ�ÈÉѬ~Z·93“/£RdÁÁÍUÈËX«”(ËKÏ„K�¿^[w×ü‹»î”=(ψʨÿËëzòÊø$\š:×(pR·’[Årˆøz\C¤Áb6Äí…[„j•_íƒòƒ:È«¶ öqè��£æ´áÂeb�ž¾ÉG.™lÛ)ÐM—~$b‰äÁxvHØy1³5/›š¯ÿ=4àEëó�Àjª3× A¨7c"œŒWªLHÆ­Y#õL´^ÛŠmüÇp 4Ø£QX ‹ùR·‘?ý…Ç{O™š wÝÞÕÕÞŒàç•O�ŠAÔ •¸+U!¨[SÜ“Ì IDATÔxknþ²NC¹^šcýÔu¬]_u;¶°GòE;GGÜùc;näY‰uí‘~+ O xó΋(×­™ÉµÓ�·ÛX#jÿ°³Wóà–Vß«\˶W“Ö °j~vbV{ …'î•ÅÓ[ UC+úËËåWÏý ï«Ç`¯c �7eè‡P´Öl©åéÈöWæ®¶Xží¯¤õWš÷WrW¼¨ýcæÒh,X£ÍѸbþéŽ@?ÓG€Ë�ƒ­å-Y‡3g5Ì£Ô~pPš5�„—§ÔzúÌ%(²²…®½¼<ðå'¯ÃÝ]Ì<}-:3ç,%©‚·—'7ªÃµ©ÌÉELLœøJ2iY®Ø}1ªQ<}'î–/ýSè·mÛvèØé9‹T{ «V¬êÒqñînÐŽ§-œÉRq÷pGë6íàâä̱-g*2ÿ Þ�[ÕeÈ�¡¨Y«–ð÷É'°gÏ.áo:ž<½½½a‹x:;;›6mÄ--pfƒ† Q«Vm„‡×”ë^�¾†uý%Œ©]ûh×®}±ÆÓëÖ®ÅõëW…1huÐà! ÔŽjÇÓ6ü�+—/‹ÖœÀ¹uëÕƒ‡»'>Æ•ËQ ½¨‹‡‡&Nš 77±}ª¯oÛºçÏŸ䉵ÕË˙鈎¾Ž,E–ž�H¶[·²>r¥ñoÚ¸W®\áÚ!píÐaÃ9ಱÂâi–o’sscù&óNf’£SseJË~(`Ñ{p»ôŸÉá«Bª"­ç«ÈnØ™nHœ¼µû¡&w³¼–Žæ‹"·EA=L–×by-Kó–j²…=²¼–ñ[vYÈkYûü`ïó–o’öƒÒ²¿2¹±2"ÀüÃíñu™0ÿ�Ò€µ1pYÀƒ”Å|²õÏZ`°L °j™ÞX­§T©y¨ÔQó2Цùú¨šxw\x‘VKbóN/OÜéàÀ³Z[hÄ.ãååmmSf×WoN¼<½áî¡Ï˜fvƒZh^¶Ò‘©qÐæ=55ÞÞ¾punª®-¯ÓfQmÏ*XÕÿhÒ²sÄ`ºú6¬R‚‹ÀªÖ–ü¬lðÕ[!�(‰%3ñß³&»òªWµ?'/iŸSÆ'âöâ�H>tÁh[vÎŽéÓ•^êÃà�‡[#v.Ï$åàéŠÆK>4Ø·©ÁÛçµ/–pbµ?ÿÖõDU Tù¸»l7l:ˆÂ\žýYª´ÅúoàèÁ¯�6/õÜ \ùp÷»k…`4þý=QY·âüD ë—±1umƱ�ªû18Œ§„£§”“�q=7¾_Å1¶R¡ãÞéØwc…«rÀ„RmÄÌÝ„ø-‡�«ßÞÁ=š£âÈnpñ—÷¼H:r 7~Zƒ‚¬ɶƒŸo‰ê¯âÀ·AìÜ�œœ!6YK×W»skí‘|ÑÎɉc'5e�Ôonz&bÛ„¤(K­�Éõ§¸•{qo9ÿ�Ž“¿/ù.¦_§]¸‰ËïÏçêè¸ùß_ÃÞQÞ>Â\°jnj:\ËYl�ºÆÂƒUyÿˆ^¤\ÐÍ.ü¦9Ú6 2nÃ&® Ï{{8ß¾·¨Cp�: §‡â#Å…fìÿñZ¨‚*J¶ÌöWV-W™í¯¤uÈây¶5kY4æ¯VoÿÛþ¾¥°J̨s®Âµë1²&Iûýɇ£vÍj’òÇŽŸÃ²U›E Uc §(ܰïrM䍸çŠv<};6–c+U—þý¢^d¤¬qJ  çõèë¨P¾ºwï_?ÑÇvÄÒºy¿/�[zôxM›ñq$%&bÑï Aìšê¢fj5'^0Ôwrr–.YE–BR¤~ýúèÛOÿƒ]¦Ò�žC»¶íäNQOÎ’xšî­«V,ǽû÷„öÑ©Ós æR5cªn<�—›‡µk× 6Vž}ƒé‹/EÕªÒöI�oݲ .�9Ôƒ${ïÕ«�l»KMIÅÆ�ëq_kžÄ Û²•†�XW¡,ž†�O°U.…í‡,vo¡"Û•þý�ÿŠ/á~r»ÁÅV•«‚´žã‘ÝHT%a[øËk±¼Ëkñ®ÇòZòß«°¼–ñg3åŸJ{^ËÏKw(–ÄrûbïóLçwåêÒR9–o²Ts|=æÖé�Åçúú³EþJ»Uöü0m£e1ŸlzVL‚i h4À«E£WÖjÕ@fV>ÂÚi޶£iLŽÆ×,2ÀjQmÞ }¡Â½VÚÜå£9ÐÑñÞÞÆ™ÿÌmW޼zóîC OŒ+rÚ‘’¡„>©hé—¢t öÑ†ÆÆA}¥¥¥À×Wü’ÕÒ±[Z�ì#-5ž^ÞO5³ª-ý£é€]ÈR`•«ººÌ–®-U róàìgÚO3®ßAò±+H�ŠEöݨ2²açhϱ{zÕªˆÀŽ�àß²®Á¡PÒÒÞÙvŽPÄ>ÀãÏ"í ä>JEžB 'o¸W�o“šêÒξž&§E€½kŸ/ᎇ¯úZ”ëjš ÒX£™Ñw9¦EŸ†™‘rÓðøày¤Ÿ¿‰¬¸ä¥e¢ ;pt€k°ÂwDÈóüñ«ГðoONœõÞ<($¢Æ»Ãà׸¦0ZÓ”ÓWý¿•’C´sq‚k°?\îù–ð ¯`R?Ô­±“—F—icpù=ͱ«5¦ Cpç&&Û²T 7M�;‹6#åÔu¨Òxà…½›3œý½áV>~-#àת\ü¼Ìî"'!÷7@Êñ+ÈMJãÜž5Ê#øùlS_Ð{^F&ùˆ¯ÆÁ+¢²Á¾´×Wq;ªt ”Òë«Ûˆ5ö¨íêvåØ#ÉÚÊŸ”ñɸòñB¨Ò²Pí�Alß@Öš��]ûz)ÒÎß@…a]Paˆ%ÿÈè½4?ý½g> Âè‘P¥ry£J‰ºr+VmFjZ†A9Š™ÚµiŽÉ?äp̪ê¢OÇÇÇã÷Eü=nœ2å xy™¿/Є){Þ¹cΜ9#kÑé˜÷—ÆŒ…·—è~¿aý߸vMÃ"J ÉaÃGØ,ž¾pþ<¶nÝlpl+V1ÇêºΚù 22øõÐêFŠ?À’5a­—a–ÄÓÄL»~Ý:ÄÞƒO‰½´{÷žÜRñ4­ÙîÝ»pöÌi£Ã Bß¾ýVÞ¸}îÞ½§Nž4ÚÙg£F�Ю}GxzšŽ=X{äèaœ�Hë÷&²štìÄñ‘­â–×Ò_m–×â?Êfy-–×’º²¼–ñ'DiÏkÑèmõü°äYÉÞçY¢5ÃuXüÁâ¹Åâȵcrìù!­Ý÷e5Ÿl am0 ˜«X5WcLþ©Ö€2§Á­Å_³¿úbu|2©v‘Vé(ÂŒô4ѱ…¶P0}tT¡TÒ45%öðõõ³EW\pKG!XU.8Ó&?y¹F O?ÉùZÓé�^®YÊBz!}È»R @ bb¢>KªÐ˜32Ò9–\Kçm˱—ÿh6pÙEX-Tås OkK^F&ׄ6˜ÑÚ6 Õ§¤œ½““MÆ]Tc´u»æ°’rIËäT(nÅ#ú[Í1¶5¦Epצ M›9R»�[3×!aç î'Á6[ý9Ý­gê•$½È qÐÚWaþQ\š¶®Küƒ«Úˆ^Ê?®/R%Vç~Ñ[”38ak÷WÎ1çáyt’ãQè䂬fÏ#«iwÉþØþJzØþÊ:¤Úeeel¦ÅésVÜÀܕѢáÜÙß~ÞÅ÷¼³fÕcoßÃ�C'qóVœ6õññDÕÊФq]4ˆ¬-+^¡1(•98yú"NŸ�B£$dffÁÓÓ~>¨W¯š7‰„§—�Ñxš¸«V­Ä½»q VЖ-ø,-ríùzô5\8wã"K¡àbXnoìäOOБôá5ÂÑ aC8;;sŒ&O¯^µ·nÝd_?‘ûðÀVñô£G�°rÅ2(b†Uê;,´<:u°0IõÄÄÞ¶-[¸±¼òÊx‹Nè yZOÓ Ò}ûþÁñcÇ„qð—te*ž¾ïΜ9…»qw‘žÉƒo½<=9€jíÚµQ³fmYñqzZvïÙ…»qqÈÊÊâÚqvr†§—^³&jÖªOÓ@Uª›’’±Ǧ¤j@cÛwíÚÍ[´0h®,ž.Ë7É»›±|“õ9yš6,%÷ùan?ÖÆ IÙûOç]m¯°úʽPo·b½)�û)ñ´ú~Øs}f‡"žn®§_ü;ýò?·òÛm»íþ–=ZV°E<�|“œ×á<$‹”™v85Çy­6Èkµö=‹Œ‡¼–™”C©Èk9N²[ØóZ —‰ø£±âñG>YV hˆ@X…�ôïrU*s_~ä� éôc¶¡‰éª¬øi\6ÝK¢'x¹šk—ä+ðD å×(NNMÐààRׄ[ÑX ¯×+’ö j'yòá$�K‘MÍ›+ï0yW†¬Êms¹imÕyšáÈ¿îiEêU ÈUuå¤}ýc÷ÞA£ã5¢rý³Í‰UÊ®ë}}Šcˤ~Ô94ñì¿,yñÞ.Úùg'Q4®—\c‘U EŠeÒÒóJCøGP4AÔÈ?ÜÎNäÍ«?üúŽ´ß[×–ç+9¨p¾’ÃÉd«0ž¯âáWüÁÕUÏýÉS‰Îýíß8€zºôî©&õïµlÄÓbÄý²gžâi±~æ·@<-Æ ç!1FÜç!9œL¶Ây¨9ºÈkùOVE^k±}"¯ÕúŽˆ¼–ÉCMvòZˆ?ëÏóÔl½Qkœ¯Üaˆø\ ?Äçb¼Ÿ‹1ò">ç|2WY�ÿA>YN7hÕy€°Úy:ÇŠ,Ýíf*ç«8`:ã¸mµVGGG¨R.[•A½ªJÊäX&Fê"«r’}l|Ô"«ê®n*2N“IÝ>Ÿ£žž^Ñ’]]g¼˜<‰4~5=Û_óÊE‹ «¼õÃwÒÐhÁ¶<¿ «Åñ Šg3‰-~uœHª×+Å¢5Ž_„Q~]›—¯¢WÅg6i¹l‰�ØùÂ9?§·üeVÜ.7œJ‰ž¬”øòÔ4UŠ%Jô5®˜=¾ü_ôÄWΙ•µÖ»ÞJ›|á=R²eq•&êzu»ì¸:ÚÁ?t ¨GF3ÿp#]ä,{ù…ybñ(g�¸#í¿§aç+9-á|%‡“ÉVa=_ÍÇÄÏøã¼«ž¢ó¯|‚"ñ¹=÷?÷HÝYóg,“vaR6âéÖèúiψ§Õ,ñ´/œ‡Äq œ‡äp2Ù ç¡Öè"¯…¼V+ A^ËäÝÉ™l䵜áf¢WòZˆ?kÏóÜ{ÎWî0D|®†âs1^ˆÏÅyŸ_pÍótî•vÂ*òÉrúA«ÎC„ÕÎÓ9V,@`­=n¡©\y¶Õ{÷[�Î>q{ׄՉ‰qâ ¨¿À3è>œð�°T,R"™”ª"ªs¡<6¿v·¯¯_§XKÖôÔ”UY5™L:’ͯ½à?2ÄOþÕf©TÔF n6aND$S)©99Z´æNaö�½»›^_•³!²õñUêZ_3H’âJSc²j´1QYRŒT3¿Éª¥‰IŠe³ž¬U ��8i™[±ŠRK)Þe'£¾p浴⎇¬ñž,½ù†S¥†à¤t%_°d6ûüóŠ[éß×Þ={y» Ž¡®�åHx2“`²*QÕ7’²Ì›µ�¸AOoßVþát$ÿ`ÙË/$ybñ=òû_Û�Ú{áð8_ !ÂùJ"ã­Â|¾ªƒãwüqþÕOÒ%7¼jÓÕ«÷H]V›0âéæ®í·=#ž–¿í"žc…ó�#n�|“N&[á<$Fy-ÿ~„�¼VcûD^«¹ß"¯%¾§yÕ" y-Ä�­ÏóÜ{ ÎWî0Äón5üŸ‹ñB|.ÆÈËøü‚k_ s.ÒöÆ.ä“åt„V�‡«�§s¬X€Àz{ÝJc¥ÙVïÚg]:ïä\V9A],©··Ï3üùUï\ų»»q>Õ‰0Ù–9™×ݫʵçû©Š¤¬›h,F©TJ4 ××y\a7�ɸ–ÕJ¿â…Ç�!Ð�ˆ¤ð°ûÇþŸþ=½üê”mµ[W¥î $ÐØŒ+ 2YÕ‹WøŒÄ¢¾‘‹£ãïÎzREÖ žõ¤er°Ÿ=Ý‹D<ÿƒkiå]5Âj÷Ò¶g}I8ŒEÆËå)µlI˶ó«·î± ½é¤Oe«4`ª„h•9É´…È äM‘8™…¬°ìf„ÕÓ�ÝžÙgÝ–Ãã|%§œ¯äp2Ù*ìç+Æ&ñÇÕ7¯ s²Ü¦ª×þx eÓ ¬6³_ÄÓ�‘ ‚=›xÃî÷&ïär²q¿—éY+ä›ÔðC¾IŒWãäµ¢bÅh�¼VsP‘×jŒ òZÑ¡È0äµ8Tî¼nxž×CÄîl ñ‡~ˆ?Äx…1þh÷øü¼«Ÿ¦ó¯z–"Ñ9î òÉb[F‹ÎD„ÕÎÔ;VÝ��ö¹�†F‹³-Økmºèÿí䘰šËå¬Ššºˆ£2Êã_ŠGYþNlÁkÄ+• ñŸx<.3¼TÆ…+šŠH•|x/ F*’r`ů1O§ÓRsvÓˆ×Á§U\eÇžœœ t:³H‡²ý½n×þqðá÷Ò‹/OØ sBX­V*DqF¬V©œ/P,mžxÍ ­–ÊDQ&«š¯âºÈ&«U²’ú=]Þ“U«U¢ˆxͳI˾^Jô÷6t«çϸŽVÞù um½Ãö£ >¶_K÷ã œ˜N-Îaä‘çéÙÓ® žÍ7¤7ÿ1Jöu9sm^/æ¯Yg6ïÿ�D´MüCrµ³ÍTüƒ;-¿(B#�/å;ÇlOïÙ·9aç+9Íà|%‡“ÉVíp¾ JüqÑu/ÐÙWØ «+þt¥SþLÚ�.Ùˆ§Oë²¥ùrO7F÷ûæ¸ ß¤ß‘ocÖxá�#ÿ y-±†5µh“¸y-5{@^K¯6ñÉÕËk%žVÅAÔù&Bæ¯#þ@üÁ >G|®r·éD>È¥7¼@ç]ý’ &ä“U¬m; V;IÛX«›¾ãZ9”ŸmûŽ=֦˾팰ʿj)‹”ÉÚ_-5‡�ÆÇLjI§ýý%,îÆ•U#’–L›ºd˜¹ýBbì‘Mþ‚ÑËà–í€?¦«Ó²î³Ù.!®Ú Ã¥ vñ�÷y=û☠UÂjµ\¶H�L VýX¯g¯T(÷¦Ò—ßdÕÂȘU±Ô«õZúP iÖɪñ®.J-m~{ê%zö”Ë)µÎRÚú{GP,ÓœlÌd¼Òä¥×X"$«ªÚO³ö–]1WÕRò‚IÁ?$µZ­R»ø‡äŠ­fNü£aõ´£·£÷ï·^Ãáq¾’Ó ÎWr8™lÕ.ç+™ØB¦�Ûø£au埢TRýÌfRïA’�xñ´n{D<ÝQÜïã‚|“n¬ÉC¾IŒk˜ãäµÄúÕÖ¢�âväµä­y-I¬ÚÈ?$Wl,¯%+Ë´qO«à j‹|“!ó× þ`Ÿ#>ÇþÑü~[÷�ÿòŸ‹ Ÿl~ŸÂáD„Õpê ³6ˆÀæï¼“^]™›aïÝÖ¢Ÿ|ogå «Lå?¦+jÎG†‡¬×Û÷õõ ¦:!”}  2&oê,7•Ò[12ŸÏS.7M©dŠÒó¯NçW¯0ÙWDÎUÁfa[>Ž��ZUhuVÁu3'Qßvò�õGz|ùˆmÉ[}­JÝŠP¨]¯k6─ɿÐwBt•›�½U�¬êŒXëd¼ù}ʹ<14ÞÝEÑ„¾jÏnçe›ãtŽr+VQ¼+K©¥ƒZD3Qµ<9M)&«zô±éLV]PmÛ£ámÃÀ?äP‡¨ùG3Âê©_Þ–=`}» V*„ó•Øq¾cäE‹v:_‰ðò*þ¸øºè‡ *¬®úËA”L€°ÚLGˆ§EÖ»øºWö¬>³Å=p¿×�¢{¸ß»Ãù&yü�ocÅ÷ð°Ç Èk‰õ¬£âvµ¸Ý æÈk9CyßÖ¸Í)ð?ï«’×j´*ÄÍu�çy�±Aüáì¾Zï…øC?Äb¬Ú!þ˜¿Êvôä“ÅvŒ@ Ž«° °�­º‹^~mzöÛÿÚe ºúûovDX5IR\¨¸©ÉI*–ŠYÕË*|8rR=”ûET”4õ -®Ø:<¼šz{ú<©zËëãO£5êÔÑÈȰEVu¢�óP‘ÅvÓ.þqر¦‡Ÿ²-Ëc«Ô³‘&ãQµBÑdRÜØçµjQ_*nVò‹š^kE Ÿ‘h’´a²êë«(–ISzÍ¥ZæÈdU®©KžÌ¤89]e› Îð�Á?Ôý­Ybÿ”/oC<`ð8_‰íç+1F^µh§óU+̼Œ?.¹þ:ëòå¶é¬þëÁ”ˆG¼RkèÆA<­¦2/íYmf‹[ã~ïA}ýq¿c‰|“#™È7‰Qj‡xy-±žÝ¶@Ü®·;Åy-gÈ!ïÛ7‹¬ ¼¯J^káÊ4×5žç5Çñ‡øÞŠøCŒ‘L Äb”Ú!þ¨¯²]ù È'‹í-€@Va @`Û½ûnzé•©Ùoß²Ã2ºöì]ib²özä ~xCŸžž¢ÞÞ>O§ÇA ��N§•Çå_*2‘s!™“¿ç�îJ¡<Ï¡¡UÔÓÝKÙ®.åù±@c£#”íêö¬’oqÍÉ´|æ„¿ÒŸ]e›† aµR,UªM…€¬j‘¯¹²ª÷ä Æ‰‚LÚ ‰²‘½ÕaK%)½Ö"“”ºÎ2K㓞VV Aþ!e&ÿpV¡¥Ybÿ¤#·¦�G>Y¬'Û Ðq IDAT´u@X…-�ìô¾ßÑóÿœœýv—m—Ð/ÏÝ�Ƨ‚IXåïÔÔ$õôôZ¯÷êÃÁm.7mUöTýða�‰ª +lšú#Ïuõê•ÔÝÕÓVdU~åX6ÛEÉTÊxWU¥½þñùo>H÷>°Â¶ä-¿Z¡ž�›û#'«ùÿ\�3è?“–üë~®0ˤŒT¡Õñª«zÒ’É´LVÕAêåÊ,7Ñßë™yÉ&ƒ4‘à­ ª,¿˜hä±Å÷è¯~+úØ»jå±½Ø?¡‡ó•ÈëÌ^¯¿R ç«Ö8w’\vËtÆ�Ÿ±2üÀÁ‹yw™µzýÒOËaŠû½N¦Zá~/‡l'ÝïåYÜ ù&§È…¿_;ùÇçN~€þðàJäµ ˜%òZÈk0+­"‘×jß¼Ö•!þÐê:ÊÂÈAÖNç+<ï–Ó9·‚Èaÿã”øüÒë_¤3/G>Y¬1´D ¬Â €ÀvûÐ=ôô ã³ßî¸õÝxþ�$¬òÆ;99áKeU§ã2Y•‰µº+¨63dƈ‰�©tšº»{ÚÂÞùð><´šâ‰„EXMàÕÝAÖ+ÿøòiÓ]zM:±Ïd¼J¡Hñ®la³ÍÉפe¥JU&·ª@ËzˆD¢‰Çëa–Œ�Sz­e‰9—UŸD½²h$‘ÐB~•YW `¬cÙŒLs£màrðVá®ücùED#�/&›�pÄVtØ{6²*Þ9=çÈi°q+7ãâ|åùZ_œ¯ä0tc§r#Ë?~üóé—ÙŒcâf)mßñ´XÅnü÷{1¾¢¸ß‹ª]wc§r#ë~ïdÎÈ79A­=ú´› ¯eÆ.·#¯eƲôIEÞ·5–AÎûŠòZ WæfßBüáÞçÈaèÆNåF@üá'S}árÈÂ?Ä8)>G>Y¬/´u@X…-�ìñ‘{é‰çÆf¿ÝþMýtÓÅo¥ñÉ`UXµÊã��ZdU®VêÕ‡7üññ1êëëVtå9ΟÛÄÄ8¥ÓÏȪ<~>—£Jµâ¨¬W˜ªŒÃø3YµJUêë d2ø¯“WYŸ®¶^úÇ1ßûÝzï«¶©7«°j‘ñòEŠw‡�¬ZuEs«K®~ê†LÚj|®`Z­V)–N9žf=i‰F)³öšZ檃D«º šM(ÞÝ¥ÚU{{ø‡<¤ðy¬µ|öB¢Ñ'V¿vø–ôñwoˆó•^œ¯ÜÙ_˜{{y¾š�“ŸñÇe?‘ÎaUÉlO·†ËO{VRä ‘ñ´*jíѾï÷ªšÃyH±öiߎþ�¼–ûDÜn×…R‘×r†3ªu¼%ÊÙèd½y y_§èµÊk}ò½Û#þpŽ³Žžxž'‡b;ž¯äV.ß ñ‡_Õ±ð;þh”`\ý׃)_Lz²þ¼œâéæ÷ý¶g;Àý^­öjÛ©÷{-Â?TÐj¯¶íêÈk…ËN;%n—Ñ òZ2(uV›Nñ�fy­¯~f úô¡›Ì*ñ‡¿ö�çyrø·ëùJnõr­ÈáÔŽ­àb­Ñ?�Oë -€@Va @`û|â>zèÉ‘Ùoß°QýîʽEXåWÜg²]”J9¯¨ªøzpÛÓÛ×’ÔÚHîÂJ«ªc;i_'«:éÄ>¥RÉ" 3–¬¯ˆ¿AÄB4'¯ýã›ç_1VAˆ?%Wþù J%½{ÃEØìñtc�ÁžUl ÷{´Ú«m§ÞïU´ÿPA«½Ú¶« ¯;í¤¸]¤&«"¯%B©Áuä}[‚–¼o³¼ÿû3ØÔZ#âþ¡± žçɃٮç+yÄ-ˆ1j×ð±fƒèÈ'‹õ†@ Ž«° °�ý>}?ýå±áÙo7Y¿›îýéÛ„„U&òÇt5ÏÑÑJ&’”Éz÷JqnÇFG¬Êª­*°Ř‚x8qƒ ·SS“T.•¨«»'”dÕvö�ÓÎ{‚®¹¹9a•Ɉüš%U8ÝØQ§÷å¤~ib’RKCQOZ²€ôšË(–vÿ£&kWV�zG|á¤~qt‚RKc¡«#üC’îätš4{uÚ‘Ý„Ž^PýùäàØf|@X ¾Ž0C�8ðð?Ñý¯žuƒµ³ôÇëöiIXå�?¦Éœããc!¶««Û3TêÁ-WõŒÇÝ¿öÚôÄ9 ÃøÁO4‘p-KV€•Ôs……ìX¢vðBÞ\ïDÿhöê´/bsú܇7óxœ¯<�¹é 8_ÉãßéñÇ%×½@g]±ÜØî;�º³ ¬6³"ÄÓvdp¿—¿ß˜h‰û½<ª�~¿—A ù&”¼mÓîù&&y‘�ý¿Kž¡+~ù"òZÞš¯Òh�·7y-%ÓéˆÆ�è­òZŸýÀÆYÕ‹ýC‡�á|¥E½2p¾Ò‹§ið7è™é ÿ0ƒ«©Aöä“�h}:V;UóXwSÞõù?Ó=¬š½¾Îzào§±‰™×d/èéÕádrrÂúedo¯óWY«ª�Ƕ*«†�Ê¿j2]áVC]ó`üYÖäÄ8Ȫàýô�+~³’.½¾qb_Æ^ÐÆ,Z’–¹<å^_IT%«Bk¼Û}…k®ºË½$3sR¿04j‘U#ÑůC7« H"�êË/ŒÐÈ‹5òÅÿ~#}áco0®*œ¯œAŒóÕnˆ?œÙ�“^_óýðJ;aõ•{ Þîàÿ�ÏÉzuôAº}ôÀ%xž§hÖ8_!þP4Ošë²K·“Õ5Äòšè„øC�Æ-uÙ¥©y ŸìYôï$@Xí$mc­R¼ï‹¡»þ¼r¶íKÒôð¯ömXaÕ«‡Å\é"‰Pww�Ôt4ª“)ø—˜ «ÿ阻Ÿ2tþ¢‡\ükXTVm­Q¿ýãâëÿAç_ýû~:^“±µ$-§s”[±Ê"«&û)Ñ«§Â5Wõ”¬Z(Pah„Rk,õtÜš¦4ƒ@'ûG³W§}þ£o /öF£6‚ó•3xq¾òþá�ßç« Ä]û�ý;aõŸ¿' ôzWÝ™×ø× ñt {Üï�Ù î÷¸ß;³œÎèÿ€˜²ôóú<òZ¦Àu)·“ãö…ÐU�×riMí×½“ý£Y^ë“ï]—ŽþÔVxž§`î8_á|¥`.×þÿè8£WXp+ÿ@>YH4íx@Xíx øàQÐm÷½>ûõ`_’»i¿E„U~U­V�Vå1r¹iÊd²žVåqG†‡¬_båa±IKeb(ÜVg- ”L&µM•uf²j§øÇe7ü�Îøñ³6½oyl•z6Òf Žuò+×ËSÓTšš¶*¢:ý”çUVMö÷R¢¿×©([?®®êe…SNêçW SzÍ¥‰áÆueÀ?:×?–_@4òäâ*ÃG|x3úÊ'6×âç�„à|å Zœ¯ìÉÑN9_9³ý½.üÙótÎUö&ýãîýi°_ß™_ÿ¬ý•ˆxºFVE<­n‡¸ßã~¯n5Áï�|“~!«SäµôcªC"òZs("¯ÕØ¢�×B^k¡e|öƒ›ÐÑŸÚBÇ-(Ð2p¾Ò¯œ¯ôcê—Dø‡~äáú1õK¢Wþ�|²_ƸaD„Õ0j s6ŠÀGŽy�n¾çµÙ1z»ôÔ-ûÛ«^NòùYŸÞ ©ýaµýuŒ*"pØ×¢ï~u¶W6£åw@ãUë;.ñÍŸx<®(Y¾ynzš¢±˜çdÅ:™¢»§W+ùR~åÞ¶äõò·ÄÜ\.GétZËäù×=c£#Ê•U¹ŸÛ ±:Љþñ«;_¡¯Ÿù˜ >¿ «œ´¬‹Ë8·KNS$JÑ„¹{�››/ƒ+—GǨZ®¸#«Î«¬šZ6Hñ®¬î©z"�u˜[±Úª¬ê†¸ìÉd=þÿxö¢ÑÇ‹DQ;áì3‡nBÇ|F% œ¯œ98ÎWs¸uâùÊ™Õèïõ£«Ÿ§ó~j¯°úüíûÑšKõýPMÿ¬ý•ˆxzˆO«Ù î÷¸ß«YL8Z#ߤ_O8éÇ´.y-sتJF^ËŽòZ�-y-äµ¼Îk©ÞËLµÇùJ?²8_éÇÔ/‰ðýÈÃ?ôcê—D¯ýùd¿4�qÈ«aÔæl�O�ð0ýâŽÿÌŽ‘LFéÅ»¤±‰*ñ+ê"‘%\T,Mž¹Ädؘǯm®“)ºº{´‘/Ekõó:¯·X,º^+“‹uUÁå9�Ž [8UH´Ü�íÒoÂj§úÇí÷½JGço6sÞêkUêÞÐ ¯–ËTššvU´œË[UU£ÉðTãŠÔ¹WWP,›¡ä@Ÿcðyí¹×WZ>•Z¶Äé×ñ$4t´’ú¯¯ª‘U}Ö#?pa{ Âþÿ`;|ö¼ ?ºš¢©ulfù©÷oBÇþ�^Â*ÎWÎ<ç«9Ü:õ|åÌrô÷:ÿªçèüŸ=o¼ü¶wÐÚËœÿ(Hÿ,ƒ%ñ4âi‹Äý÷{{ K[ä›ôk ç!ý˜Î—ˆ¼–Y|e¥#¯eG y­Æ–ƒ¼òZ^çµdïa¦Ûá|¥aœ¯ôcê—Dø‡~äáú1õK¢þ�|²_ÚÆ¸aD„Õ0j s6ŠÀgOz„®»å•Ù1¢Q¢—ï=˜Vå­ïTˆ„ªå“U½$reÎjµJÃC«©›Éª™Œê´Cמ'…|ž2YwUu>\cÝ�ŽS_߀Q3¥,ž§úÇ}­ #NzЭ_„Uþ…}qlœ’ƒýŽU]Ÿ X2IÑT˜ÈªU‹dÏf(Ñ×ãxísdÕ(¥×òŸèét!õ¤¾E¸Mû[Žé‰P„7SŸ?ðø› ûÇ3g­¢ñ,¥HÔîŸxÏÆtÜ[j±Tœ¯œÃˆóÕv�|¾rnAz{žwõsô£ŸÚ «Oß¼/­·VûÇLN‘D<Ýþ¶�xÚ©w4ï‡û½~Lý’ÿÐ�<üC?¦ %"¯ecÑüC_䵿PB^«±Å ¯…¼–—y-Ñ}ËËë8_éGç+ý˜ú%þ¡yø‡~Lý’è— Ÿì—Æ1na5ŒZÜ�"ðùS¥ŸÞô²mŒ—îÞ�FÆ+”J™#þpµO“•[�f½~~l”JÅ"uuu»&pUŒ&á|8É妭õºùLOMiËe�OŒQÿ`hɪLzîTÿxèÉ!úø±¶™ÓVÇU©{7¦Þ—‰�…¡J.t\Ͳ0p¿×�©_áú‘‡èÇ´™Däµ�×òÎÚZ�„¼Vc|�÷EÞ—-ë¼VPî<œ¯ôkç+ý˜ú%þ¡yø‡~Lý’è· Ÿì—æ1na5ŒZÜ�"pÔw§ÿ⟶1ž¿ó*–Ì¼ÎØ2/nxh5å yêíé£l—óª„F•¡Q¸Ž²ï\1�É¥n«³Z †J…FG†‰ ÃK�>5ÂhŘò'æ� )3¯0øÇK¯LÒAŸ½Ç¶œ­O¨R×z2+tߦž´d’"N�~øõc‘¨\’žÉ­LÕõ©V*Dį�—¿>nqlª„êf.u²j,•¤ÔüŠp3÷z]X5“ÃQ~}\b �=î*H»�kyjš"‰¸+{t;‡zøüÃÚsøÇò ¨!aõÃoH'鎰Šó•º÷â|eÇ ç+u2Ùãì+—ÓE×¼`â‘_ïC›®ßþñ“S\O;E.ØýOë×î÷ú1õK"üC?òðý˜¶’ˆ¼–{¼‘×r�!òZ�1D^ y-¯óZî½Y�œ¯ôà8_ ÎWú1õK"üC?òðý˜ú%1þ�|²_ÚǸaD„Õ0j s6ŠÀWO‚.¾þ¶1ž¾í�DUgU [M–7M“d¿Fcså¯ÑÑÊ妩§§W ùÒ¨B4gœ™øèæ•õŒÛÔÔ$e³]qYQ’ç2<¼Ú"­†•¬ÊsçOÔ ¹/,þñúªí}ØÝ6KÝæÄ e×U#_:1uNZæV¬¦ÔÒAo^a_­Rijšâ\ÍÔ¥Ô×Ëkà?ÑdR &ÍFbQå~¶$M.o‘<ã™ ¥– j[“ÒB44®ÿÂ>ÑÛC‰þ^ �‹(ŽOP,� Yþ¡æW�âÏ^H4úÄâ{ô‡Ü€¾ù¥m9ÎWŽ`³ª´ã|5‡ÎWÎìÈd¯^ù]|Íó¶!þå>ô† AXm†;âi“é�lÄÓúqÇý^?¦~I„èGþ¡S‘DäµDµ¾Ž¼–;ü¸7òZ�1DÞyßfþa"¯åÞ“õIÀùJ–uI8_éÇÔ/‰ðýÈÃ?ôcê—Ä øòÉ~YÆ # ¬†Qk˜³QŽ?ã)úÑÏ^´�ñäo÷£hÌyåÂFæ�I²_3�˜¬Z¯Ê„Õvÿ0Îü'�»ZêÔ䤶J´,krj‚úûCYY•�d‚‰[ân+…„É?F'Š´ûî°-g›oT(»¶YªIËâø$Å»»”+¡6Ó5¯¡<�§x·Úku+Å’%’««:ýÔ+«Æ»º(µ¤?üdÕ¾^Jôõ8…Ã}¿j• £cïÊv,YþáÞŒtK˜}èµÀ?–_H4Ò€°zè;×§S¿²­£ià|å6ÂùÊŽÎWÎìÈd¯þäYºøÚ¿Û†xè{Ó7ò·š¹É5»•�xÚ-‚Áê�xÚŒ>p¿7ƒ«×Ráf‡˜Áµ•T䵜c޼–sìê=›Åíî%+J@^‹�×R´š{™×ò`9RCà|%“r#œ¯”! dø‡µÀ?ÌàêµÔ ùòÉ^kã…Vì=ÌÝßøáÓtÎUö‡’�þú”L9¯Rfd¢„Ž��Ñää„U%´··Ï�„ðuÑA|œžš¢LV�P× )þuÏÈðõöõ‡–¬>+�›±Sÿ(•+´íÁ·ÚÙö¤*eÖ’×I+]¯ƒR»02J\Á3¢©ª.¯¡41åˆdɯZs3�:Y• žÉ~½÷Âj¥ª�Ð+ÒOýuiÉÁeÒ¯H¶êõÂêaŠ÷v†¬š_¹š’K<›üCÎb‚âË/"y|ñ� Þ·ÿúô­£Ô «N÷9Ô‚Ù ç«`ê%ˆ³ »œuųtÉuöØð¯×¿�¶ØÔljQÑóæ„x:à Rœî÷Š€upó°ßï�¨þáµÎìtÿ@^Ë™]"¯å ·ù½�×jŒ!ò¾Èû²e´òÝy-÷Þ¬OÎWú°lwIA?_™ÀþaÕö” ÿp¦W]|Î'_|ís‰Ì½½ùdg:A¯öG„Õö×1V¨ˆÀ7Ï}†Îºâ[¯~þvêîJ+J VsÞdÇÆG)�ÎP__°&àÙ‹E«:«Žj¢LŒŽ SwOoèȪ¦aæ· ¸õ�í¹…Š¥êì2¶9¹JÙ5ͬʗ¤åÐH�¬Ÿ;\»Y¯¡86AɽdQ™9ÕɪÉÁ~Jôè­ŽV-•µa$ZK-i¹ŠRË)–ñobbaõ�E<Ž&ýÿaüCd9­¯wŠ4Kì¿w¿õèÛGo§¢ÛýCi°6jŒóUM™8_ߨÏüñ³té vÂ꟯݋¶zCû¿©Â©vO;E®=ûá~�û}{Z¶žUÁ?àz,I�äµÔpD^K ¯F­‘×jŒ!òZîl y-õ¼–;ă×ç+œ¯‚g•Á™üþk ÞLtúÇ—>M—^÷Eâsùc䓃§sÌ(€° =`Bà´=Kß¿ìyÛŒîûÙÞ´d@O…M?–š›ž¶ˆçó9êôc ¡“ñb‚i,¦‰ W­Î’U™–cÀXèÂ!ˆëÖá»}à›(Î.oÛSª”Y¦µ¦’–Í*–ZdÄUC˦)ÞÝ¥eAVRd̪~éõ‡“–ù«)µt€bÙŒÖá9ÑI$WWU©ç[ëß\´m¶A¸J‹E‹¬4Â!ÿR…?Q‰J‚ó•à´Ÿ¤Ú�5¥d"IéŒÞ×�›0±íð§�‰Îºýã­¾“†F ³jÙîø¥×¯Ùº›�UåôµDÕ*¥×\æ˜YŸƒÌ빸ZDibÊ3ѯ‡¨ÏUUë„[™*¢n0[Ø×JZ�X$OR¨ÊØLV�$âŽIÄ•B�(‘êo‘UGÇ-Ò­I E6Âsæ‡ñ®¬ TFÚÂ?ÜÃÚ©þñÜÅDÃ�-®ò|À^kÓÇïØXÝû‡{-Ö$8='9í§kÞNåà|å9³ýÚÑ?~pé3tůþaîî+ÞJ»l£ç=f5â�tÄÓfqwzßvÚÏìjÄÒq¿cäG‹v¼ß3Žªy*?°Ÿ?&üÃo 4?¬þ�¼Vk{B^«1>Èk¹»!¯å?î�¼–C™¼–*êNã§ýTç§»=ÎWºÕ#/¬ç«f«‡è± )xÞ-ƒ’™6NíÜi?3«�—:ÿøþ¥ÏÐå¿xùdyøÐ²ƒaµƒ•�¥7FàÜ«ÿN_?ëiÛÅ_œ·;m±é`h juL§‡ >Pòƒƒ˜Ã×mû¥¸ÉÉ ªV«ÔÝÝã×”Çí„_a™ð�Ý?x�Ž×ˆ¾üÙù˜8Å6™ûeEÌtȽ¾Š˜@Ê•UM’çÏ�+Fp²/ѧÇn‹cVeÕÌÚkx^ÔdER®0ÊX®®êäÃÞH,*ÕŸ×Á$b]Õn›Í·YÅÝz{•N0QíÿPEÌÞ¾“ýcùÅD# «ûï¹�uâNM�5±¸Ób­7ÎW:P4+ç+³ø¶’îÖ?ÎøñstÅ/í Æ;/+íº-«ÍpG@X ŸÎ0cÃ\zÃ?è¿÷„m”Ÿüß.´Ë6kÙ½xþEWô "Y•ç¦úŠù°(yÞS“4¸$$g¶¼°&T¼Æ¤ìðž[)Ÿ¯ÌNgçϦ(¶}Nez¶¶Å‘1ª‹ÙÒ«�n²ªU©µP X:%õÊ{�ë4Y‘”+�Z•USÎ*«ò뾈ªRÄO&ªòC€Do·NxÉâ0ÑtZ;±×Ô¤áî�…=w Ñ𣋰ÏîkÑy'/®°jrÿp£MNþà|åAó}q¾2�q«ä¨ÿøÞÅOÓ•¿zÉ6Ì­—¼…öØÑ»3š(:ñ´3ÜZõÂý^?¦º%â~¯Qyyðy¬üj ÿð ùÚ�ÛdÏC óZ;ýO’â;äOq»c謎ˆÛÕðC^KŒò¾bŒ¸EXò¾ªy-¹ÕϵRÙ?æËÆóèfªÌñUiÇÃR”ØÍa•c•|ž’K¼«ÎËäX®šì×SÅÓª´P­H½î^U�¢öL”-MM©Hʺ‰Äc ×ô‡N°QŲ£CÇ'(Þ••"Ð�ˆ¤pø‡$PMšÁ?jÀmm·2mêâùñGDªä„o¥T²ª…êþXdÕhÔxµSž7ÛE"5ì—…‘QJtwk%ëÆ}¾<øGctáάî¹Ëˆ†ÿ¶ø>õ_»¬Ažº‹3¡õÂùÊÐ8_¹Ã/è½MøÇw.|Š®¾ñ¶¥ÿúüÝhŸÝ–ßæ‡xZô&ìYÏÌÄRO‹1B wÀ?Üá‡ó�;ü‚ÞÛ‰ ¯eתLÎJ¦ òZfóÍÈk‰ïFÈûŠ1âaÌûšÈk9Ù??<Ï«ÙÎWrþÖVðwšƒ¸Ã/è½á‹5„|rЭó  ¬I˜K øÅÿ¡O�ð°m.§» ²Ï�˜_&Á‡“b¡@™¬qŒ­ÓÓS‰R¥²©NLxîL�)T䠜ɪÝ]=Êkn4w&“š"ªÖDZpN&“:áëHYã“%ÚõÐÛmkßrï õ*OXeÒW+�¦¼ÑW‹È¯XE‘xœRK,‚¤W«RÛ¸‚�‰æÆdÆj¹¢½ú)ÿ¿49MñlÚ²j±d‘}ub³»j•ò«G(Ñ×CÑD8*AÃ?DÐú:üc1>Íû{î¼]tZp «8_¹óœ¯ÜáôÞ¦üã[¯åtÿÀó¼šnp¾rçãAï ÿp§!ø‡;ü‚ÞþÑXCÈ'Ýr1¿ !Âj�´�¹�ï~•ûÚC¶¹œö•­èýïÜ(ó ú$øpRÈç)ÛÕ¥<Õé©)Jg2ÆÉšÍ&æäáåC«WQ*�öµ*¬,Ø<ß±ÑÊvu+“U½,dפvãÚãÃöÄþvËÐàaj„U£$Å€Ç'¨’/Rj逧PZ Úr™¢ˆÒü@€«œ.üTŠE‹ëDf«ÅsÅÖé×VPjÉ 'Uo­V§u«°üÊÕ”èï5^ÁÕí<ç÷g›�´Fþ¡fqÏ_F4Ô Âê;-£K¾õf5aµÆùÊ# ƒó•Cà4u3éßúÑSô³›ì„ÕŸŸ³+í·Çšfß~bO»Ó©I{v73qoÄÓ‚óš?Lk)Ü-àÁÖÎCþêÇ�üçµQÚ÷S÷Û€¼Vc}"¯ÕÜΑ×j� òZÂ$òZBˆl tæµÜìxž§¦7'­q¾r‚š¾>ð}Xš�ÿ0�ª¼LøGs¬�O–·#´ ¬Â€Àn¾ç5úÈ1Ú¾=é [ÐGÙ¤c±’%*:=œÔ‰ÙÕÕíÆ…BÁªªªZYudxÈêÓ? ï•ê¦@`œGG†©»§—Нç¾~U½5…‡.¹¯®˜¦·âw6qm›¦5�˜Ö5„V9ü«ôÒø$%¹²ª‡® ËcDzåQ­ ±Ø"2'Ëäû“îJ¡<ÏÜk+)1ÐG‰ÿîKÊ@µèÀ¯«+¬ªUVõ¨’¯Îù{% þ!Fºü£Ybÿ-;.£K¿íaç«ÆöÆ•ëq¾ûb»·Šœvþ“tÍoÿiƒûº¾™ØsÍvW�ãõ!ž^ ]PìÙ±R%:"žn âéæøÀ?p‚øïãSqÚçãw#¯%Øï�×’8l‚¼–¸Èk‰qꄼÎW8_á|åÿù Ï»Å÷c7-ð¼Û zðÓ|ä“ÍØ'¤¶' ¬¶§^±*Ü~ÿ úÀWþj“püáo¢�¿wSRÃÛ•}ü'oýêh&«æó9R=„s¿éé)_«“æóy‹t*Zã|-rŸ±±Êf»”×ì‡50ù£NVM*V·ä¾*D^?Öçטì/½2N‡a¯D±ÎfIZÿè¼_Ój:.?Kã”è#ŠD<›W (MLYdIÕWPåʪ +l²L^C£ª«ªcÌoÏ ¦ÿóºU…4ÑÛ.dÕ åW¬¢xO7Å2i혹Á;H}ábm´‹<÷c¢á‡ßwß~)]öÝ]Å@hh�óUcq¾Ò`\m "HþqêyOÒµ7Û «×ž¹ ¸×Zm€´™% ž¶ã${6£q"ÄÓ­‘E<ÝøÎCð�`øÇ?ÿ3I|æÛd�ײëy-S§9¹\}y-1VÈk‰1ꄼÖ%ßÞÏó˜òMbÿ脈? þFüá×ýÆ«üòÉ~iã†Vè5ÌÙ(wÿy%½÷‹±�qô'ßHŸýÐŒŽDá|xçÛ¨§S²*Ëf²jw·:‰M^¹\Î"ªª�U'&Æ­ Ÿçmªê¨Î_@²~˜¬ÚÛ×/ÔåB\qxo}xg|^z%GïùÂl —®“ M¿^Ðe¦Zäpr½82æ}eUwtœ’ƒýÊëà_¼G¢1ŠÄcÊ}�t`Œr¯¯¢x6cVÛáÃI}^W¡enT‘°ÞȬþ!F©�ü£au×í–Òåß3OXÅùª±½á|%öÃNh4ÿ8åÜ'èú[þeƒþ§?؅لÕföˆxz™ Ù³‰{âéÖ¨"žÇÓÈ7Ù1ÂyÈÄ�*|2½Þ?ž{iy­fbå �×òÍ‘�×’ƒy-1N��×zóvKè’Óv>Âó<±½¨¶ÀóG|îÔîàzŸW ŸìÔѯaµµŽ5·D஢ƒ?÷g[›#?¶ùß›CŽüšŽ U±ä •?""§Óà–×\Èç)�Q=¸.E䦧)žH×X�ç<>>F™L–T«”ªÌYgp[,-²j_ÿ€0Q±pެ[‘þUÖå´mÐýã‰çFèC_ù£myÝý1ÚêÛ5 ‡“»…ÕÔ\2H‘¨·•U 㔎Ësœ_-µ02Jñ®,E O äñËS9â¿Û¦²*p_[i­)½ÆRЦ’ž`¶Aàb�µ›<9ÑЃ¢ˆ� ωý+¾·›-p¾Z ÎW. ÊE× Ÿ¯Z-ÍËøã”sŸ¤ëo±WX½êÿv¦w¿}mè·wWÄÓ5ýâ~�û=âéæ÷:øüþ,ÿ@^«¹>˜à†¼–gW‹`ˆ¼–PÈk !²r£í”÷m–×ÚeÛAúÉé»·ÄËxZ¬µxž×/œ¯‚u¾R³n÷­áð§V„ø\|Ž|²SkD¿ND„ÕNÔ:ÖÜ�?=2Dïü;ùìðmBG}r #Èɾ‚@ep·U<¸?ÏK¦ÒE.7í¨B*žɤo$Ýé©)k|YBf¡P°ªÁöôô«ªÊ:ÖIVå9�ŽSÿ P— 틉®"ý«Ø¤Ó¶að�‡ž¢�k'¹Ç“Ú鬊ÓekíW­T)¿r5¥– h­TÊIãH¬yåS+©¿z„’K™¬m¹&nKUš�WVåyÇÒ)­X4ÆcUòy‹Ð)š«'Ò0¿â*·bUK%J¯¹ dÕ&˜Â?ÄÆæ‡T D•2ñ­¡BT-G¬{‚õ]%BÕ2ÿ»ö7Y×Äë˜ßâ•[K4úäjŠ&×´uÜy›%tåÿ5'¬â|%Æç«Öá|ÕŸ Æß<çIºáV;aõŠïîDïÛo±Cth ÄÓd½¥ñ´ÝOûsCC<Ý ~h†|“^»A¾ÉŽ'üc.Ÿƒ¼Vc_C^Kï=HUòZrˆ!¯%Æ y­9Œp¾Û‹j œ¯p¾bð¼»±çÀ?à�êÈ'«î¦hßÉ€°ÚÉÚÇÚ"ðÀôï'ï·]ûÄ{7¤ãßZ;bü ‹ƒÄTJ)Kǯèd‘üÀ=ŸÏ…’¬:99A©TZš¬:59I•jÅÑZUŒFwYyù|Þ"« ,Q&žòÃD&«F"ÞUâl´®°øÇý¯¤Ã¿ñÀ¢%¼ùÜ*EZó4eÕéª]~ÅjŠ÷v{FþäÉrR?¿j˜RLVmAjm´°…•V]-^²s9—÷Éi9nÆIýüê!ª–+Q•U›CFÿ ŠRÕ"rF¨Â„M‹Ð9�ØY®Öžüw�ìiý»ÁwuÒ§%‹eÔúÒL{þ®<�£H,5oŒÚXL&­ÔerAéJ�dZ§N6µˆ¥<�ÏuÙÔ’Q›¯ÃW‘xêÈIªeª†ˆ"•E„Õ·¤«¿ß¸ÎWb´q¾j�ÎW­ñ‘9ûœrÎtý­ÿ²MþÇßÙ‘Ý]±Sth ÄÓr?BôÞu™$î÷¸ß»±¥ Þïݬi~_øüÃ�-ùåÈk-ÖòZn,Ù}_äµä1D^kæÇÌÈkYFÓ*¯…øCÞ¯d[ÊìÛ²²ð<¯1RÈÇŠ-ñⱕ4o!sÃþ¡Ž0òÉ꘡Gç"Âjçê+o‚Àßž¡·vŸíêGÞ€N:r­˜1¯X(P:“Ñ&׫ªM<Wºàj£ªî‹ÅŒV)m5§‰‰qJ§3ÒdU>ìÇã ­¤âFós[µm¾L7•UƒD¦‹ÜùÇWé+ßúÛ"µîø]~µ|cÒ/“2ùcºš'“F¹Ji¼;«êªŽÛ×’úC”Z2¨µ¢«ã :Vò…¶"tVŠE*�MP¥T¦do(צÃ?*E1¡“í4šHQ4Õ5CîtFèd"f�Z'�Î#tÖ¿«:Ke*M S$9@‘jÌêg#tδ¯g#t}ø—:�&M¹Ÿ÷r«Eª–&¨Z)Q4Ñ·hm;n5HWÿ`1aç+±ªp¾ Or4,ç«…ˆú|óœÇé†[_¶Mç’Óv ¸žØ1:´âi±âý²gñÌÄ-p¿Çý^l%îZÀ?Üá‡|“?äcÿ²y-»Ý ¯%ö#“-�ת¡‹¼–&+C^Ëç+Mö4O žçÙ1ÅùÊŸÊ5ˆÏŸë¿»Ù%bÿp†0òÉÎpC¯ÎD„ÕÎÔ;VÝ�Ç—�Ñ[?z¯­Å¡û¯G§µ�6ÜøWa…|ž²]]Úd2Ñ0™4O*qs8áu3YÕ¯Ê�ããc”Éd¥Éª^¼Æ¡Z­Z ]ºcŒ‡‡WSÿ reÕ\.gsýÒOÝÂæ¿ùÝ¿éøï?ºÈ—·=™¨œ«ÒË7Eãüº{¢HŒIªeŠ$ˆ¢‰Øì÷ÑD„¢±j­Mœ(Êíø»8±úÅ’Ü¿jqÇøßÑd„"Ö¿«M,¾•FF)‰R¢¯GÛ}F$(tIý"“Öâ¢e…æ:'õ™€[žÊYzoUYµRš«Èi‘"¹Zæ¼*�4Si“¹ÕÖk×¹2f©:SQ“3ç3U<­×´Ï¼’}^eOþ®^ù³V=sîõîÖ8õÿŸW)ÔªÚY*×ÈŸ•x­zèLÛ:±sþ¸Öœ+3Õ@çU¥ª˜ØY-�W*�Ľó^t¥È$ÙÁÚÍ èŸj©vC §JT­Wý®VÉVܺƓ¬é=BÕ¹ׯY_‰Ê¢ê4Q¬—" ˆ¸;lÙO?=cÛŠq¾ÎW­1ÂùJlC¢~Æ'Ÿý8ýü6;aõ¢Sw �Âj3½!žnmÑ~Ú³È×D×q¿Çý^d#n¯Ã?Ü"hï�|Ób<Öoš¿“þ�¼Ö¼2l?ÂF^kî-1ÈkéÝDIC^Ë9Æ>æµLîÎ‘ë‰øñ‡œ¥8oÿpŽ]ÃmÏ»Á‚øCü¬N¯Ö¤ù½ ŸlB«�Ù®€°Ú®šÅº#ðÌßÇi×ÞcëÈÞkÓé_Ûѱ̅ Æ|>§õõòüº&šþðá}zzŠz{û”‡â_Ø12õç—fcc£”ÍvÉ“Us9‹Djr¾üð€‰0ºtÇ­¦¾þu²êô4%S)£ë•17¯h&ß´\Ë¿è”sŸX4|×UbRàôæÈ-–3ªô“Õ¢L\ekŠÇ§h¬DñÞØgæTµø^uÞ—E›ùSû7ÿ§FcrØìu«R,_*Syjˆb]‰'(R­2p–Xfõ±Ü?B‘Hm¬Ùñfn u™óǶ&Çrj]k2"‘ÚÿG™…V—WûÛ"µEª3×¹�5ó]} ÑU«eŠDc‰ÖúÔÛYs›ÓR"y-ÕUfþf‘V+&VVY�W#tÖ¿·d0É“ �,ƒÉ˜LòœùÎzý9Ë)Wj2¬±j$R«ïÌ«j'_·úε©Ë™{|¹öZõü¨EÆ#JÔ^ÑÎÀ×_ÏU>ƒüqås$EVSÝ^-£á/ê¶Í¦ZçÿP$ÁþQ¿^³o«ïŒ­Í^«‹ãïk&7×È’=ÓwÞX³0Ï^®“UæH 3ó¬ZJ¬É¨M´n`3¶]—[_Dm�<Û¹uÎ_sµnÏ3³°Ö4#×’ÅÃÍŒ5#ËúÒrî:ásîÿgñ`;œ?ÇYóE[Ö;Ì[N}M³Ë¬“K-,këµîsàÖ&ÏF_»q¸ûÌ8Xµ4F‘XϢʪ›oÜC'|nkêÉÆi‹ÍæªÇ›Þ?ê‹ÂùÊ�zöÆùj1ža<_Å?Núáãô‹Ûí„Õ NÙž>vÈúz ·�¤!žn®LÜïõ:î÷¸ß×@¾i±-À?à*þ�¼òZÈki:£ ¯…¼VÀòZˆ?4ùv=ÅŠçy‹E¾ICÞÚ�™âywkиžw;0¬y]°¸Ãùdwø¡wg!Âjgé«•@àùLÐNïÿ½­åþ{®Eg�¸“DïÖMê|OO¯–*–œLÊsUÌtZ‹¼V³ç_MMM’“¹Wf^n’üÙlîŒÑèèˆEŽÇå*ÅyQ Kw¥ Ƙɪ½}ýÊdÕé©)ˆüÐÏ|½…Õ?^[•£ÇŸ¢«n|‘–ÿc’&&›°]%-åo?µÊ‘ŠÄçHWò½¶´~a¿š¢Läò±øÈ! µ‚e•ªÅ¡†d<¹ÉøÜ þá³8¼‡þ±ýýô³3ç*«â|%¶œ¯Äá|%ÆHÔ"ñÇ7Îzœ~y‡�°zþÉÛÑaïÞ@4ý޽Žxº±êƒ`ÏNŒ÷{1j¸ß‹1µ€ˆR»Ž|Ób¼Âšoâ•xáœ×zê¹Qºú7/ÑS/Œ"¯…¼–üMÇø]~R>µD^Ë'à<¬‡þ±0¯åÕþa}ÄbTˆ1µðâ|%šƒ“ëð1jð1F¢ðBâëÈ'‹1B PG„UØX€ÀK¯LÑvï¾ÛöíÞ».£óOy³+¬¸’&W'íëëw%g~g>xe²Ymòš róKã“k1“8ù—f*dU®¦Æ•U¹¬ÉcšHè!öñ:GG†©»§WYæää¥ÓŠÅôWüTÁ¯üãëg?Owÿéu•e£-@�÷Z‡~pü³3ÁùªµRp¾-ÎWbŒD-‚|ã¬Çè—w¼b›î¹ßØŽ>ñ^V›éñôbd‚bÏ"¿[x÷{1b¸ß‹1µ€ˆR¿Ž|“³vÈ79yÓ•ºå}é´‡�×rú |F`a^ ç+ý Áù ç+ýV¥&ñ¹/ÄçbŒD-°ˆ’»Ž|²NhVa@`'uÓÇ IDAT/¿6M[t—íÛ·î´”.þ֮ޱbäôÔ$õ :–±°#¼2™¬ñª˜|8áʪ:‰¶Ú@h!È:¼seÕž^éʪ:ƒÎVkÔ=ÎÈÈ0uuu+“U'&Æ-²ªlåYSzkÿøú™�ѯî´La¹@ à �ž®8-íOÑ’� ö'­êÐMhÝ5k?Âùª5®8_‰íç+1F¢AŠ?N<ó1úõ‚óÝOÜ–>ýþ EËèØëˆ§íª’=«%î÷b´p¿c$jÿ!¤~ù&;fí’oR·g=�×r†z ¼D@”×ÂùJ¿6p¾ÂùJ¿U©ID|.Æ ñ¹#Q ì"„ä¯#Ÿ,�ZVa@`¯­ÊÓ÷¿Ãöí›· +N‹#¬øõòu²ª®ª�ããcYÕ$Ñ�À…|žò…|(ɪ\q´§·O#ÝAg3cÑ=Îèèe³]ÊdU/lHÆaÚÉ?^ymŠ¢±­³,C÷½ð*ñ¥¿-† JTµŠ÷FˆªU"«’/i}3óŸz·™k3mkýjÍgûQ„y2×�¯ÍʉP•ªÜbæïyÝkCZc²ÜšŒÈÂ)Q$Rµ¾ãk«OuÞÐf«ËØÚ 2©õõ$¨·'Aý= Z2CF]6P#¥®±$Cý½ü}’Ö^–i ˜{#ÎWflç+;®ít¾2c1òRO<ãqúõ]/Û:œyü6ô?ØH^H‡µD<]S8î÷f ÷{ÜïÍX–¼Ôún�ojŽ™gj�á<$ƒ’½ òZ꘡@À-ºòZˆ?Üj¢qĈ?ÌX–¼TÄb¬ˆ1jÕû‡;üõæ|ò¯î|‰"‘øìeä“õã ‰í�«í¡G¬B#«† ´É¾·Û$n÷¦>ºæ¬·*�’›ž¶*u .ÑV Õ‹’ö|8¢h,FýýÊëö³C¹\¶*«ª<<(•JÒÄV7kÓÜò!œ+¤& ¥iæðÞÆþñÒ+“tÐgïQÒKØG£DñX”bÑÅbQŠÇ"a7‰P4N�ð5æºV­ûÓ[™ŸËÄ}‹§kQik„Ùj…©°5-óc«¢Jµj}_æïøoþS®Zß—Jüÿ*•ˆŠ¥JØ Ã|�X€M³™8e31êéNPw:nPûºÔ×›´©}ÝIêëMP_W‚ÒÉ Å£yÚtãµp¾òÈšp¾�ó•#Qr4ˆñÇ ?x”n¼ûß¶©ÿk[ÓÚØÝ‚Û¸7âéY5ˆö,cv¸ß‹QÂý^ŒQï÷2«‚ˆQ‚ˆ1 ‹ ¯Õ<¯U­V)ʹ­™\W=¯ÅºåkÍòZ¥r…*ÎkòZî\½�@àh•×ʤ‰– di 75›×²ò[Ý ë‡Ö:>ˆ?t ¸XžçÙ1Áón3vÖJ*â1æˆ?Ä…%þP]I�ýã¸Ó¤›îY�|²ªRѾ#aµ#ÕŽE·B`x¬Hî}›­É–›õÒÏÏÝS ¸é©)‹¬:¸d©62ËL¥ÓÚä5Z·ÃC«­1ú-rYX>L<åʪ}ýÒT>ÐXd:Ãë, ”L&µAɶ•J¥¥×Y8(¯EhwÿxùÕ)zçg~o:™È�GjäÎx„üwŒÿŽXÿo]ŸiÇßÇãѹöÖµ™ëu³}£32jc$æ]¯�Yû>6ów„*TÌOSoo7%’‰Z_KVm^õöñÍP#DÉχeÍ͟ףó£Ã?¦re*Ê”/Thxl‚¨§R%B…|…òÅ2å‹**”+p»™ïò*ËT*W­~¹\ž"‘U*DÅr� [.W,²,·)•*3ßU©4C -–¹_™r–¬šü|¾Lã“%�A ]™e2qêJÇ)›�ÕþN׿‹Q6§îlÂúŽÿm]ÏĨ‹ ©3ÿß•�YUNè«~Ú}ÿPÅËö8_‰QÆùJŒ‘(9Ôøã„ï?J7þÎNX=ý«[Óç?Âj3�"žF<íîŽÐ¸·Žxa¾dÄÓ‹qF¾©µåâ<$ölœ‡Ä…é<¤’×â2sÎ)•ŒÏä´Äy­x´JñDl&'%—תçÇ8ÿ�ÍäÄy­j¥LÙLÒÊéÈk™Ü?æçµ8‡•ŸÉg©äµ˜Ëù«r©Ò0¯•Ï©P,R4–œýa8òZî|½Ã‡@³¼V2¡d¬LƒÝÔݕԒ×Âù ç«:&÷/¼ùX/P¶��øCŒ9â1FaŠ?TVtÿøæÙO#Ÿ¬¢P´íh@Xíhõcñ�˜˜*Ó:{Þb»´Ù]ô›‹Þ& ØÔä$MNMÐààRŠÅbÒýZ5ä4ñxÜ(Y•ÇZ½Ê"orUØ0}ø×Ž\YU•¬ªK?"Ýé$«ò/cñ¸reU¶K&<{±æVxÀ?¼÷,ø‡sSþ‘Ë—)ÇYëo&³2©µF”-ç 0–*LMNÓätŽ2é.*Ïgk×êmŠ\avæáCý»…ÿo}_ª?xà*´•r•¸Wô°ú×ÿ¿þƒÿ.Uˆ�à˜LžJF)‘ˆQ*¥4ÿ;µþ�JÆ(Á'¢”äï’1‹|‹V(“ŠSWWÒ"´'¹oŠÛŬvéyýø•dLLe²i´’§þ�.êÎêûá…”±8AÍ]ìbüLíâ‘í-ઈɵ?î�ÒM *¬~ç·¢/~l9Ø ñ4âiÝf¯›¬Šxz±†�ojmµ8‰½ç!1F¢ÈÇŠR¿ŽýCO¼Ð*¯55�§j5J•jd6g5›§šÉcÕ~î.¯•ˬF½}ýÒdL®$kOÆR÷á=ŸÏ[óN$ÔªÒñ/ ɤrEVÝöÿÐ�¨X'à­q‚4Ƈ«Î2‰Õ"ËZäÚ:ÙµBÅ"“a™ËÄØ ��ŒY׳]=V•Ž*W ­ð+qùïA¶þoëx3ß•«U‹L˯ijÚðÿׯñ—†?¼¿ y«bµìžÀ¯økV•›¿·*GyÏ®UW¶þŽÖ*[¢Qâíœ+s;ëO|æo«O”q®ü]¦îlЉÈ,ᔓùÝÙ¸#T°,† ç+qòûöÙ{££‘õf‡ ÇÇ}ÿQºiA…Õoµ%}ù°M�.¹íû!žF<­ÓÈOÛÑD<­Óºäd!žã„xZŒ‘¨EÐÏCÍæÿi–þ!ÆHÔÂ�¨äµømKÖ›•fòXnóZÅb™¦¦§µå›D8©\ç\H³‚NòZ•r‰âÖ�§VŽ«ž×²~@�àç�óZð­5nëÆ?Ü�î\ö1vð1F¢ðBêן#>W·½=² Ÿ¬Wï�ÖÞ€°ÚÞúÅê À„™�7ÿÖÖsÍ¥)úýUû ¥���Q±P þ�Aiâ‹H(+ùcòa1“oFG†‰Çb²j3"Žh®~\çòÔä„EV•ŨÙHçtÞù f%�âjd¥\.g\ý®¬ ÿÐi]r²àbœàbŒZµÀþá¿f½±Ø‘ÁþaÆÎZIÅþ!Æû‡£vØ?Ž=ýQºùžÛ–rê—· £>±™;Ú¸7âiÄÓºÌç!œ‡tÙ’S98‰‘ÃyHŒQ;œ‡­þ!Ö=üCŒüc<¯pg/N{#ßä9çý°ˆ±Ãþ!Æûö<ïvæ'xžç 7Q¯…ù+ä“Eˆá:˜C„UXh€@ïN7Ù¾ìKÐý×î׫±±Qâ�¾¯¯_¦^�Uy²#LV-—CGVåjqù|Žz{û´a®KN˜$ª‹ü[*•,Yª‡pž÷Qí§ ‡ºø‡nDÅòàbŒàbŒD-°ˆR¿ŽýÃŽöurÛû‡AìbŒD-²{ú#tó=ÿ±-ç”/nAÿû)V[éñ´È‚q÷{±p¿c$j–ûýÂuÀ?Dš­½Qù&1N­ZÀ?Üáר7âiÄÓú­JM"ö1^Ø?ĉZ`ÿ!¤~ûöu«ÑÛû‡OìbŒD-°ˆR¿Þhÿ@>YGôè\@Xí\Ýcå-Üõ·T*Í½Š¸+£ùΦ=FGG¬ª—]]ÝÚpõê5µ<÷r©¤µ*¬6Zâ_–Ë%­˜ëš7“KU« ¶›m�?ª¤S§YuáP—ÿÐ�¨XüCŒüCŒ‘¨öBê×±Ø1Ãþ¡nCn{`ÿ#ˆýCŒ‘¨E˜ö�¯žþݲ€°zò‘o¢¯~ú ¢evôuÄÓÁW?î÷bá~/ÆHÔ"L÷ûùk�ˆ4Kÿc$jÿ!¤~ñ4âiu«ÑÛû‡OìbŒD-°ˆR¿Žýû‡ºÕèí�ýCŒ'ö1F¢Ø?D©_o¶ Ÿ¬Ž%zt. ¬v®î±ò¬ñ–›)—¯Ì¶HÄ#ôØM6ìÁ|*™¢t&£ SÞàøõö²¯¸w:ðää妧­Êª¦ÇÍ‘«ÉÊÎ�çÌÕl3Ù¬H¬ãëN ÃÜO•X*š¤ 6uYA:¼Ã?D_W±ø‡Oø‡#Q ìÍÂþ!²¹ë8_Éá$j…ý£9B*Øà|%²4ùëaÛ?ŽùÞ#të½ö «_ÿÜætÜgß(¿èl‰xÚ{¥«ÜÓ/ˆõƒxAŒ‘¨EØî÷õõÀ?Dš Yù&±¾D-° ^ÙHý:žW´F û‡Ø’p¾c$j�óò±"q{ùX·Öúã|…ó•¬%á|Õžç+ä“e=퀫° Ð�uö¼…&¦jU-럧o=hQK>¼g³]Ö«ßu}¸t8Wç”%o:—“(…b�º»{Œ�%š#'+d1äyS$BétZ$Öñužã¯J<5AVu²ˆ %àN4hïÿp�á| ð÷xbÿhŽ!ö÷öÅp¾Òƒ#ö=8Ö¥`ÿp�g÷�ÿýî#të=/Q$ššà„#6§aµ•E žvï/*p¿WAKÜ÷{1F¢a¼ßóš�oi6XdUä›ÄúµÀþ!BHí:ö5¼µÆþ�|“{+j-ù&=cÿЃ#òMúpÄþ�ýCŸ55–„ýCÂ�²p>ù¶?Ø Ÿ¬Ç† ¥ýaµýtŠi@`ýo£á±¢MÒ#7@©dÔúŽ«{NLŒ[dUURc«éñ¡:™J'�òë"‘ˆE5MŒ©C… ËøÄâqir«hìF×óù¼EVÕkPȪŒ'ë”×à×þ¡yø‡>,YüÃ=žØ?šcˆýý}aÿp�a]ö}XbÿЃeX÷�¯œú'ºãO+)™;[íÞHßøüæz€iS)ˆ§½S,î÷z±F¼àϰÞï‘oëþ!ÆHÔþ�xZd#n®#žvƒž½/ÎWú°D<­KìØ?ôXRc)Ø?ô¡‹ýC–Ø?ô`‰ýßýã˜ïü�n½ïUÛàÈ'ë±iHi?@Xm?�bEØdßÛiÕpÁ&é�_ìOÝÙ¸UÊzzŠ2™¬V²çôÔ¥Òi­2Aá”P£ÖE"ø ÄÄJr%?<ˆ'Rm�ΕuÀ„aU²*—ì—YƒÓyÉöcÝòÜýœ üCV[âvð1F*-à*h5n‹ý£9†Ø?ÜÛö÷Ö%`ÿЇ%KÂþáÏ0ïÇŸñÝñÇ•6¾úé7ÐÉG¾É=0m,ñ´7ÊÅý^/θ߻Ç3Ì÷{ä›Zëþÿ0™kD<íÞ¾O»Çñ´> çKÂþáWœ¯��uoEÍ%`ÿЇ.âs}X"«Kìþíÿû�¿Ñm «È'ë±kHi?@Xm?�bEØü�wÒ«+s6IºîÔÛ§B>OéLFÃ(s"˜Œ™H&•‰’ª“à_w1¡Q•�©:ŽL{>¼s%Ðd2)lÎm¹�Éj°\1—IȪب”¯.ÔE/“?Ä6Òÿp¡Äy]ázp¬K�¸ÇûGs ±ÈÛöy¬œ¶Äþá¹Æý°¸Ç3ìûÇW¿÷è¢ãÑŸÜŒþß—¶pNK@Ù¬�Azxa5¼ºÃÌ "°ÕAwÑ˯MÛFøÝU{Ó`o\Š`©25Þ¨‰„2QRe nËÄJ>t©2UÇ‘iÏkæO:�6çÀ-•J Û¹i066J]]ÝÊØp@$C¸u37™¾^·Íº|¨çJ³ºñ€´¶ø‡ØCàbŒD-°4Gû‡Èzæ®cÿ�ÇÊiKœ¯œ"׸ö÷x¶Ãþqô·¦ÛïÍÆQß”NýÊ–îjc ˆ§Í*÷{½øâ~ïÏv¸ß»G¡±Ä òÈ"^�ÇÊiKìN‘C¼ 9{žÏ+°¸µ/ìn÷Çþ!ÆH¥â´·Eü�çƛ`~ÆÂžwë@·&£S÷ä“õÙ$µ? ¬¶¿Ž±Blÿî»éÅW¦f{V«Uºí²½hÃu{HkÞEånf"!'Lþ"^v~*‡ÓÕKùÐÉzzz•ɪ¼­,.NÛyYÒ¿9’ýƒ±ÔM††´¶ ø‡ØkàbŒD-°4Fû‡Èrì×±¨áå¤5ÎWNPkÞû‡{<Ûeÿ8êÛ£;îÕÈ—þ{SúöÑ ¬¶²ÄÓî}¨™Üïõb‹û½{<Ûå~ï »Ä jˆ"^PÃËIkìNPC¼ 5»4ìÈ7é°/ì:Pl-û‡^Œ¸Çûö÷VD„ýCŠØ?š!€|²yûÂ탫í£K¬D#;½ÿ÷ôü?&lo¾d/Úx½nm£xõ+ºr¹L‘H$dU^3“eˆžYÎNÐ 0 ¬Â€@výà=ôÌßÇmW~ý£=é�÷jÁ‹_%ÏÕNãñ¸yÍ„ðÁ‹?A¨¬jN*)Ò#ÏÛäœùxSS“ÔÝÝ£f»rÝÙ{Ð6oìw�W§‘ñ8ˆ˜˜§d")EVu °@¿F½T,R&›UŠ+Ãrßd2©ÔÏDãé©)J¦RÆÉªü %ŸÏQW—¾ÊÂ"<à"„Ì^‡Èã ÿ�ÇÊiKìN‘kÞû‡{Lƒ’…¸×åB ð÷˜¶£|ù´‡é®VÿàFôƒã¶qXK@<­O¹¸ßëò. ÷{÷˜¶ãýÞ=*dåŒ�o’Cñ´NnZaÿpƒ^ã¾Ø?ÜcŠý£1†Ø?äm û‡Ù/KĸaD„Õ0j s6ŽÀ~Ÿ¾ŸþòذmœË¿·+íºÝRÇc3/‰‚ôèxŠGF†)›í DUR.õÏøG£QÅUÔªdÄb1G}•kÑ�mˆçÁL~x&«ööö™Æ&þáÔ ‚Èãÿ�ÇÊMKìnÐ[Üû‡^<ý–ÿЫø‡^<ý–¦Û?¾xêCô»„ÕO½oC:ûëÛú½Ô@��xZ�ztÛ³›Y!^�Gñ‚�ÿÍíÍ+2Ä# žv§<ÄÓîð[ØÛ«‡aˆ§õê­™4ø‡^œáDÈÇêµ)Ò/è@±µ ÄÓæ165üòˆ§MÄÓæµeþaqìæ165üòØ?°,¶-ä“ÍûFh@Xm]b%8ôË¥;þ¸Â&ñ¬w¤ý÷\[i.iÏdÕt:­Ô/Ì�K¥’U ”ÿ„ùúãê°~¯Ã«‡““–­öôôz¦6ø‡gPkþ¡ÒEáæ165üòsráæ165üòðSñÇNy�îù«=.üØ!ëÓ§€°ÚÊšO;÷uÄÓαkÔñ´^<ý–ÿЫø‡^<ý–ÿЫø‡^<ý–ÿЫø‡^<ý–ÿЫø‡^<ý–ÿЫø‡^<ý–ÿh®ä“ý¶NŒ&@X “¶0WÏøðÑÐ-°¿úñôc·§CöYWzü@>‰P"‘�Á@ É±XÜSb5ü#¶îdð'¨©õ�¨á¤ÖðóÚ€˜ÇØÔðSÈÎÉ…èÇøóß|�î}ÀNXýð�ëÑŧí °6’ˆxº�”é`)¸ß;M± î÷Š€¨9üü2àæ165üòˆÌ#k~ø‡7ãyžyœMŒÿ0�ª]&ÎWæ165üò8_™GÖü¦üùdóºÃ탫í£K¬D#ÿ}ìCô›ß½j“ø­£¶¥÷í¿¾Ô(^ýJHj2h¤„@P^‹À¿LâI,Sš¿JãjµJSS“”J¥­j²^}à^!­ø‡~LJ„˜ÇØÔðSÈÎÉ…˜ÇØÔðSÈÂ?L#û¹“ ?<¸Ò6ÌX—.ýÖŽ¦‡µ|ÄÓ¡VŸ«Éã~ï >©Î8IÁÈFðój�˜ÇØÔðSÈ"^0�¬ùàÞ`Ìoí0ù,Æü*:sø‡y½ã|ecS#À?L!‹ó•ydÍ�`Ò?�O6¯?ŒÐ>€°Ú>ºÄJ4"ð©¦_Üñ›Ä“�Üš>|ð†ÂQLýC80¸F (åëù�ÄdUÓ$Òé©)J¥ÓÄɯ>ð¯�Ö?üC?¦ %Â?Ìcljø‡)dçäÂ?Ìcljø‡)dáæ‘%:â›Ð}Ø «ïßoºü»;y1|hÇ@<ZÕ¹š8î÷®à“êŒó�L�lÿ0¯ø‡yŒM�ÿ0…,âóÈšþacìæ165üòØ?Ì#k~ø‡yŒ±˜ÇØÔ¦ýùdSšƒÜvD„ÕvÔ*Öä�ÃOz„®½å›œã�Ø’>þž�[ÊæÃI2™t=>x�@¹\Ä/h™¬ÊŸD"a „J¥B¼^“c4š<üØJ� †‡˜àæ165üòöä(ÎWæq61üêv™Ø?Ìb|ÄÉÒ}®° òž}צ+OßÙìÀ!—Žx:ä t0ýÿßÞ½€É²Ü¯Ùݳ{öœûL Ä(„ˆP‚1¼?ôó ä��ùО"*¾>@TTTã�7òBnîÍÍ›ð�7B®æž³gŸ~UÝ5Ó3;»Û=Ó53;óÛdïΙ©®îþuÕTWõ¿«Pl´ IDAT}ßÏ€Öqß÷ÁV(¹úQþ`¨å�K­Aý(%«?]^¶üÔ�òÆÚ�òÆ¥Ö ~”’Õ~”—-¿õ£¼±ö£¼q©5,¢~O.uô从V×ñ¨Ú§¹>ëo¾.|Óùµ±|>÷S~xÑŸ{ç ó^D7÷ŽÉ`ª@ç“Þõܶ´=9YdC¸p°kºÂU9&1X5vîööö®©äÅ›­~\ßCª~”?vêGyãRkP?JÉv¿x°*Ç¢¼ÈõYêçWÕ ÷«Hv}Jïù-ýô¿úÊðò׌ϰúQøvá?üÃ÷½Î»U|Ûõ§‹¯Ä Vå;Æ÷½ïû•¨¡~”?*úÓå�K­Aý(%«?]^¶üÔ�Å· Æ[•cQ^äú¬aUމþ‡þÇ*Öõ£üQÑÿ(o\j ‹®Ÿþ%¯ /µñäRÇS¾ë% `u½Ž§½éIà‹þÁO…¯{é/Žåö¢?ó{Ãç¾èÙcïµ=99>>N‹ýöž8Ö2›EŸœ\„ËFÜ–MVU?V¯Š©å�‰ö£¼q©5¨¥d»_\Ó~”?]× ~tëž^ûÑÝlž%>í¯>yÍo�eñïÿ´ð-ÿè�Ì“íÚ/«?½ö‡xeâõ§Cp>´zõÍùPùcâ|¨¼q©5¨¥dõ§ËË–_ƒú±ã6ÁªÎ¯Ê‹®kP?ºŠuOïüª»Ùª,¡~”?êGyãRkXFý0ž\êhÊw¬®ãQµOs |é?úéðÕÿöŒåó óÌðÅŸùnÃ÷b§uggçÊuÅ™3ƒAúõsµ@|Œ_ü-Ü»Œ““i{¾Î×Ô�«Ëú,)Ô�YÔVoõ£Ì1Q?ʸ.:Wõ£Œ¸úQÆuѹªeÄ/«ŸöÅ�…G^;°úáÏ{Zø¶¯°zÙÑП.SVÛäêû¾�Òê§ñ}_æ©e\�«úQF\ý(ãºè\Õ�2âêG×Eçª~”W?ʸ.:Wõ£Œ¸úQÆuѹªeÄ×¹~O.Sf亞V×ó¸Ú«9¾ìë~6üýõóc¹ü¹�z‡ð7>û=Ò{1µd@圛Ÿ� ýu ’]ÄÉɪÇÜø{óæÍ>÷Jå¡~”9êG×Eçª~”W?ʸ.:Wõ£Œ¸úQÆuѹªeįªÓŸÿÜ· ßñuÏ-³Ak’«þôräUå¹�­ÒŸîCñò<|ß—1V?ʸ.:Wõ£Œ¸úQÆuѹªeÄÕ�2®‹ÎUý(#®~”q]t®êGqõ£Œë¢sU?ʈ¯{ý0ž\¦ÜÈu=¬®çqµWs ü½þsáï}ýËåO½à÷„¿ýWÞóZ«®Ê ¢]C<é‹?%�WåâZ<>G‡‡áæþ~¢©iãI]üY•àäëpò®~L/vêÇÜÕñÊ Ô�+‰fJ ý˜‰-ÝØ¢ýèf§ýÐ~t+1ý¥Ö~ôgÙÌ©Mûñ¢/z4¼âu¿=¶ôœ· ßõÏþh™�Z“\õ§ Û”çy·Ja^Á«—÷}µÑ,)Ô�YÔªáõºÙé/è/t+1ý¥Ö~ôgÙµ¿0ïš�_Í+xõòêÇÕF³¤p~5‹šó«YÔœ_9¿š¥Üô±Œö£ÅóylBûa<¹LÙ‘ëz X]Ïãj¯æøÊoøùð·þÉÏŽåòÇ?äá+>ÿ½ç̹üâqÖÎôY2ð³ï½ˆ''q |{{»ï¬‡ù­Ê‰eì\Þ»öoÝ*¶¯2¾X@ý¸¸s» ßêÇrk¯ú¡~,·®öÚÕõcµKèr·n�ëǧ~ácáÑ×ÿÖð¼ÏSÃ÷|ýó–‹¾âkן^ìÒŸ^¬÷&¯m�¿ïç9®Æ›æÑ[ŸeÕý…õ)Íýï‰ú¡~ô_ªÖ'GõCýXŸÒÜÿž¨êGÿ¥j}rT?V·~ÄñäW¼î7Ã`0Š{1ž¼>uÏžô+ `µ_O¹­‰ÀWã/„/ýÇ?3¶7/x¿§‡¯þ’?¼Ò{xtt”‚>W!ð¬-T P‹?›¬ÚefÕU¹èÑöX®z:õcuOÞã–u�yXýè·Æ©êG¿%j½rS?Ô�õ*Ñýîͺ×�Où¢ÇÂc¯X}Þ{?%|ÿ¿|¿~!×,7ýéÅPýé‹­õú-‡ëþ}?«Öª”3ýéY�`?Ë©ú ý”¤õÌEýP?Ö³d÷³Wê‡úÑOIZÏ\Ôõc=Kv?{¥~¬výøä/x$<öº7…ÁÖÞpC�'÷Söå²~V×ï˜Ú£¾ößýbøâ¯ú©±œ>ä¹o¾î¯¿OçÜãÌ¡‹x\ûª<>¦ PP�>;;;]ëœvQÇಠ‹û�Ñ�7ZméÇ\¬JyYÔ±Y•ýmuðëDêÇÅZêG—’tuZõãb£E}Gi?®.§“)ulÔõ£Ké\•ò¢~\~Ñ¥ÿñ)_øhxìõ¿=–ásßë)á¿AÀêeuCºË7Çìiõô|ß÷÷}?kM\Ô1Ð_è~„ulVåü¯‹�öCû¡~h?¢€ëÓË�ú¡~¨Ë t~µüc ÿÑåìºJ«ýÐ~äöãS¿èáñŸ|Âxr÷jd‰ °º�Ý._-ðõÿñ—Âç}ÅǾßzÛð/þÎû^½°­ºˆ´ÊtEuŽÓøÇgK:_ÇǬè¡-¶YêÇÅ´êG±bwm2V?Ô�kSX—°¡ê‡ú±„bwmV9Kýøä/|4¼r"`õ}ßãáðCÿæý¯Í~/cCõ§Ë«ÏRžËoU™5èO—q]ç\ÕçCë\¾çÝ7õCý˜· ­óòê‡ú±Îå{Þ}S?Ô�yËÐ:/¯~¨ë\¾çÝ·M¬Ÿö%¯2žé  �¿a|†Õ÷y÷‡Â�|ã,«ª_‹õêO—=L¾ï}ßû¾ïÿû¾l­-“»ñ¦é®ê‡úÔõ£ë7¯ó+çWÚí‡öãâ2 ~¨ê‡úÑõÜ*¦ßÔó+ãɳ”Ëlª€€ÕM=òöûR�oúÎ_ Ÿõe¯Kó^Ï~8¼ô«ž×J®ô €­6bEmÒÉI×™LÃ�7ŠÍ¬ztt”òî3 )w ~U?tnsG%r· æV?VôK}�›¥ý¸[ýX`A\ÑU©ê‡ó«2çWŸôùñNoËü½Ÿý`ø±oþÀý6X�ÍÒŸ.w|ßû¾÷}_æû¾\­-“³ñ¦é®ê‡úa¼éò2Pò‰^e¾í“«ó+çWÚí‡öCû1K‹£ýÐ~h?´ÓÚãɳ|£ZfS¬nê‘·ß— üûïùõð_úÚ±4à]ßú5WϤƒãàOÛ ¬M:Ñ&8Þ¼ysíw»ëŃ{÷î…½½½b.1˜)«Æ€Ø¾~â]•1ÏøÛöGý¸XJý¸ØFýh[ÃÖ7�ú¡~h?´³\<Ð~¬o»ÐvÏæm?þÂç¿"¼j"`õ¾ëá'^úAm7a#ÓéO—9ìó–ç2[U&Wýéé®Î‡œ9º¼ �½ø»Ãxìtý…2íøuÊÕù•ñ&çWίœ_9¿š¥ÝÒ~h?´Ú�‹Úãɳ|«ZfS¬nê‘·ß— |ëüFøÔ/~ÍXšw~‡ûÂw}ýå&cP`œ½R°êyÞtò~|nîï¯}éëúØòƒƒƒ¢A¼±\ž�� ˆmsPÕ�+NÞÕ�©@êG›ÚµÞi´_õc½Ë~›½S?ÔçWeϯ¦ 0¾û³�ü«—}GéO·ùï–Æ÷½ï{ß÷e¿ï»ÕÈå¥6Þ4Ý^ýP?òÅâ.O•ÒŸ^ÞwÙª¬Ùù•ó+í‡öCûqqP?ÔõCý˜åœÍùUÆ“g)9–ÙT«›zäí÷¥ßùÃÿ+|âç¿j,Í;>ãVø¾oø�©ËÅ™&ïÜy2ìïßêüxôM8›trg,ˆ3:´ý9¸{·hoìTÆò¹ÌYmÕ�ËKƒúqÉà¨úÑö«dmÓ©ê‡ó+ƒ£QÀùÕùràüj1çWŸøy¯¯~ã›ÇVöìw¾?<öŸ>xmÛÞ>vLºÅQ·œ9r>ä|hzp>´˜ó¡~[µ2¹é/è/t-Yίœ_9¿r~åüÊùU×¶#¦×~h?´Ú�«Úãɳ|»ZfS¬nê‘·ß— |ï�½)|ì‹Kó»Þöføáû¡ç–‹3W>ñ–ß ÷?ð`§@ÅU>qÀ·¯YbWù±}îç,Çóî�;aÿÖ­YmµL|¬ÕéÉIÑu\µ!êG‹‹''K (¾h Õ�«J÷üŸ«êǬ¥Hû1«Ür—ëó{ÕùÕÅÇRýXn9Ÿuí«Z?>áó^^3°ú®ït_xü[§ßÈ8ëþ¯ÛrúÓúÓ‹(Ó¾ï¡Üÿ:Võû¾ï=ís?gÙ6õcµå/Óg¹Ñ_Ð_p½ââ2 ~¨ê‡ú1K«ïüjµå/ãüj1Ç@ýXŒsßkQ?ú­ò3ž\ÆU®ë) `u=�«½šSà~â‡?û9��åòÔ‡÷ÂË^úaçr~≷„Û·ï ]94™IŸ'sîzèúx±ËÖóŠû¶»»;ïfõ¾ü²Íï<ùd¸uûvïû•3ŒÁªÇÇG©l.óGý¸X_ý¸ØFýh_k—ý]ÖÜRíGûã6OJõ£½žúÑÞª¯”Ë6W?ÚÉe«ëÒ~|ÂK ¯ù©ßƒ}Ö;Þ¯þÏÏo�½�)õ§wz9êú ú úÓúÓ³|™8j¯æ|¨½U_)—m®~´?’Ë>V×¥¿Ð^ôê”Ë6W?®>F9Ų�•úÑþXõ•Rýh/©~´·ê+å²ÍÕ�öGrÙÇJûÑþXÍ“ÒxòÔMÌùP7¯>RëO÷¡xuÚíÇÕ¥DÚõ¼ó¥DÿCÿCû¡ýÐ~\, ~¨]êGO~õ߃Áp1ãÉ]¥Ý$«›t´íkk�—½ê·ÃGÆ#céoîm…×|ÇGß›7¸3ŒÆŸ­­­ÖÛU2a<ÙÚÛÛëeqßâï<³Îö²!™ÄÁû¸]ó H̳]qý÷ÂÍýýy²¹tÙx�ŽÃ}÷Ý_lm2V?.VR?.üQ?ÚÔ®�¾Ç´í¬úJ¥ýèKòê|´Ú�«KÉx çWíÅ´í­rʾä‘ðÚ‰VŸù»o…7ü—ížÙ-¡?=ßÁÖ_Ð_p>ä|¨ë·ˆó¡öb·Ú[õ•Rº/É«óÑ~h?®.%úÓ]�rzíǬr³/§ý˜Ý®ë’ÚíG×2£ÿÑ^LûÑÞª¯”Ën?^ø¹/¯yão†ÁÖ(îÆxr_GW>ë& `uÝŽ¨ýéEàÑ×½9¼àE/?—×OßG§÷æ½ ?.ïX\•ÙGÂîînoÁ³Ë¼cþ¢°ì‹~qý±Ó×WPð´ýŒÁª‡‡÷Âý÷?ÐK=˜5õãr9õã¼�úѾ¶i?Ú[õ•RûÑ—äÕùh?´W—’ñÚ�öbÚ�öVÍ”ÓfX}û§ï‡Ÿúž›-à YJz¾­¿ ¿0Ï�;ï竳,­¿0‹ÚlËè/è/t-9ú íÅ´í­úJ©ýèKòê|´Ú�«K‰ñ¦®F9½öcV¹Ù—Ó~Ìn×uIí‡öc–2óÂÿxxýrlQãÉ]%¥ß«›r¤íg'�W½ñ-áùŸô²sËüäwTØÞMßÝ)Ó:q_'ïóž$åm_õ`Õ>ö3æï¦YÖ̪}óËÊ[ V½wï <ðÀƒ³Ë•Y¦/«>ÊMDQ?Ê�¾Ž¹úÑþX©ݬ´í½–™²¯ïõ£ýQt~ÕÞjÙ)Õ�nG ù=ðÂ?^û3¿3–Áï~»›ág¾÷ûeºa©õ§g?à}«öÑ®ù¾Ÿýx.zIß÷ÝÄÕ�v^Æ›Æ�ú(7ƛڕ½ySõõ�h¼©ý‘P?ºYojïµÌ”}}—¨í�¢þG{«e§T?º�>¾Ô�næËL­~tÓ_§úñÉ_ð¸ñän‡_ê °ºÁß®_,ðúŸ}"|À ü\‚Wû û7·g¦ëëä$^Ä sψzp÷n¸±»Û[ gß׎��ÃÎÎÎÌÞqÁU¸Ó¬ôàS¼xppp7<øàCsY-{aõ£ÛP?Úy©ãNÚ�våFûÑÞiRj?ºíG;/í‡ö# |ü‹_^÷3oÃxúÛì…Ÿû�´+HšJz¶¯?}Þmã|ßû¾Ÿ­ÆošÕmËé/tS×_hç¥ýÐ~´+)ÓÏoâ÷Ò¼×=æY¿ëíô´íœr*íG;/í‡ö£]IÑ~Ìê´ Ëi?º…uk?Œ'w;þRo¶€€ÕÍ>þöþ�Ÿþ…ÿžûçÿÛ¹O_ñ-/Þwc&·8/@Í;óˆ?óÎÚg°j_ûÖ„=::JV10wÖŸh·m^óY××çyœßUëŽ�Û»wï¤`Õy¬®ZOéÏû*CêGû#¥~´·ZvJõ£ÛÐ~´óÒ~œu~Õ®ìh?Ú9­B*íG·£0­ý˜6Àø´§î…_øA«—éêOw+{}ÕUýénî1µó!çCÝKMµ„ó¡Yå¿\_߱ƛÚ;õ£½Õ²SªÝŽ€ñ¦v^ίœ_µ+)çSi?f•[ürÚ�næÚ�v^ÚíG»’²úí‡ñäY�¤å6Q@Àê&uû|¥ÀÏÿò[ÃþÓ?z.Ý�¿ôÃÂÛ<¼wåò“ úšå3Þaæ Àì3X5î[<ÙÞÛëîrd<)½qãÆ\�žËîÜv.$3,�OÞzèá–^�EÔ�nÇBýhç¥~Œ;i?Ú•›˜JûÑÞjÙ)µÝŽ€ö£�—öCûÑø¸¿òòðúŸŸaõ©í†_úá�hW 64•þtû¯?Ýުï}ßÏZ¦ôf•[ürú ÝÌõÚyi?´íJÊùTÚ�Y応ö£›¹ö£�—öCûÑ®¤h?fuZ…å´ݎº¶Æ“»•©7[@Àêf{�À/ýú�ðžâ‡Ï}úCßøüðŒ§íwr‹wšÎЃ�b^1�sžŸƒƒƒ”Ǽ3´Æmˆ'^÷Âþ­[ólÒØ²ñä$äγ}}f57,Ú¯Ò ¦ñ8Ä™Uzx¥¶«kAP?º‰©í¼Ô�óƒ?Ú�veGûÑÎiRi?ºíG;/í‡öc²¤L`|ʃ7Â/ÿÈkW¨64•þt»¯?ÝΩD*ß÷¾ïg-Wú ³Ê-~9ý…næú í¼´Ú�v%å|*íǬr‹_NûÑÍ\ûÑÎKû¡ýhWR´«t¾ë1Ó~t[çöÃxr·² õf XÝìãoï/øõ7Ý à£èܧß÷ Þñ·;¹Ý½sgî€Î8ƒi<ÑÙÝÝí´îÉÄ}άï>8¸nß¾o®mj.;m1Xuždû ìmnW´�?«r¢�îÞy2<ôðSVf›f-êG{9õ£�•ú1î¤ýhWnb*íG{«UH©ýh´í¬®sûqïð4œž�…xÊï<ùd¸¹+õNãilý7�Óž…ô^|ÿ™–‹Dñõi�GáðÞaú,ÞèVå{NOÕr鯵*ß”G­;oGLtvzîÝ Û;7Â`°Ýî@\’*ö?ï†ýýþú‡‡a{;Þ,·3uÍ_öµo¿økOŽ}öà};á×~ì#çÞŸuÎ@ú꣫?}µQ©×ùû~ÒÄùPûRâ|¨�•ú¡?Ý®¤œO¥?=«Ür–Ó~´w×~´³Ò~h?Ú•íǪ\cœõxi?ÚËi?ÚY­KûÇfïÜ©ÆcÓ0k=F›Çb«áÙjL5…ÔqùeNwxXŃìäñØš1/›Æ[cÀÃ|«0†:Û³pï ŽÇî¦'Ùž�ÅñÜÑú›Û—ÇvÏùæñâtÝì$Þ»öoÞ®òIÃÈ£±àvGz<ÕUã±mò<9©&zÛÙ™o¢·æºúŠ1žÜæJC °ª$˜"ð›¿u/<ë#~ðÜ'ßùO?0<ë™÷·6‹‹oÝîà:™y 6гnÞ¼Ùz½Óö¬!s°j_¬¸}Û;;sÍ [bp´:q[�ÙUãÉû�'ß~ÊS¯}°ªúѾJ«í¬Ô�q'íG»rSi?Ú[­BÊfû‘b ]üíU�zÃÁ˜Æ L ¢;¬Ï¯voì ZR°^�Gü‰Ayyà'èU¡}u`ß Äïç­�akk»Ê'æQð¤e‡ƒ� Áz@'¯/ ÆrxïÞAؽ¶êÀÀlØØŽæ>5ƒãëj»GAˆq0i¶ÃVŒ7ܦª Ëzë}L^Ç÷ÂÑÑ�°}ãÁÆÀ[}<ë�¸¡Mð9n6¶»ÞŽáv�•É:¿êä²ÚŽô¿Æzò±ËÇ1�ŽIÛÔ¿³“ƒ0Øž¯ßpvv7* ¶æ»Yîìô^ƒ�^‚UÏÎNBˆùmí÷v\mßv ¦«Ö‡* ãò÷ÝÚÿóeÕæpllýé˽þôòª†þ‚þ¬¥OaV¹å,g¼©½»ñ¦vVÚíG»’r>•öcV¹å,§ýhï¾JíG30,� …º?öÙAdUß<�l2ˆ¬Ž-Žƒ¶7çñª<–óˆ×Qc¹zàÁ8ùLå;ÜÆôz<�,oïdÙh¹ÉmÝL\Ç«�’]ä–G8›û�µr0ÝpŸëq±ƒ»O†Ý½Œ7ºáùÜ~�™4ÛB'G‡éÉ�;y<6í5Çp‡£¯ãtɤö‹ã�[Û£›£ãXl6››l÷�íw½Î8îytt/ììŽ «Uç9z9 ¬ËLN× Œ¯�Žî¦±°ÁÖ�z$¹qœšùNŒ£æ·9ã�†0ˆcÎ�r“�Ëd¹m·êÆôê�Êc¾}|<6çs®Œ¥ñí ׯ~Ÿ«[ù³|,ë� ®l|ÇUONÃÉñݰ}ã�&ùØïp?ó¾LÔ×¶û=–.]N+©,M”½_�Æc[ å2Ñb<öªÜÒ8qˆ±�é^•Ç´ÏûЉEËxò,GÀ2›( `u�º}¾RàÍO…g>ÿûÏ¥û²ÏùƒáZΰZ�¼ï§»WòÏöÖ lmÂNüÝ„íøwg¶¶ª÷Ò¿··Òßø{z/‡‡j$;mçú¸“+ç b'ëþû«È>~â]y[ÛÛaoooæìâvÅŸ8 ÔºþäÁÑ8³j³\]Çý­fþ¯]÷#ó㣣¹g0V?ºÊ¯fzõcü¸äú±µss0wQàÞpÀ£1³^2‹ß÷1Hm{» ÆË³òM ÜÉå�‡‰À½££ÃŒ·¿ÿh¶¿ ÷ò _3ø°9¨�·#n_¼qbggolvÁi�{ñz "­¥eã ×XÀ\öhîåàÃÑÌ„ýîeÛá`dÏ�{GÇáøènØÙ} „ÆŸ‹÷ªÙëYóv4ê†Áš902ÝWϸX&pïð(EŠVÛ}rÂÖn FçW]¿•ª`¼“0Øšý¼#mËéaì6ÿÌ‘i›NÃ`»íã'ã…­48:ëOÚ®4Ë|¿ƒ?³nO‰åâq<;�Až÷ÍU®Jl[×<Õ�öb­ëG5Ž?ösëævxÓˬ^¦ýæ·†g~èœKòm_óáÙïÒ®©¿Ð¾<ëO·³Ò_˜Þ_Ø¿5ß¹‡þt»ò·ê©ÔõcÖ2j7ÜÏ ‚ÇFy�ff«Žmµ²á ¦“�I£ ¨gv› úÝl<ÜÏFp[ž ®iÔÜïø:>Íc{'ŽÕãfµgµLc{›���ÏbºtÃïéqØNã±cÍ2”Žaã&ÜFY­ò‰7Wn¥±˜áxîdðX.ãmßpìï8œß [;·Çƒ-‡åcTlóøÞdð]sL9§“ƒ&ƒÝQžÃrÛn¿«kŸ1¢§oš,»Í±Àå|cοVãMã†ÆcÛ—)ã±í­V!¥ñØöG¡õxì%Y^‹ú1e<ùöþvø_?a<¹}i‘rS¬nÊ‘¶Ÿ�þï[�Ãïù ïë´L3q5[O¼»kÎ`ŠÓ£0ØÞŸ};ÒTVG½ÏlÔ0EìÏ4rv÷1v�×<˜âänìÜ?W¹š¹0õ¸ úѳ:yW?®Kƒ?êÇ�© |Ó~\UnÒ`¨ö£ ÓʤÑ~´?Ú�vVÚ�)´—ž§¿Í^x·g=¾ýkŸÛ®�mh*ýéé>Ϭ?½øŠáûÞ÷ý¬¥NaV¹å,§¿ÐÞ]¡�•öCûÑ®¤œO¥ý˜Un9Ëi?Ú»k?ÚYi?´íJŠöcž8ŠY�û\NûÑ^s“ÛãÉíˉ”›' `uó޹=n)ð‘ŸþHxãÏ=žxk5³TÛŸj¶­øèËyƒUç›e+Ý•zòdÛñ±™óÏü÷?žLÌX:i˜NNÎÎæzléuü9‹�T�§<¬U0žúÑþ»Dýhcµ^ƒ?êG›cžÛ#íÇÕZêÇ´ÁQçWW—œëÌíüjt$õ?Ú”ê*ͼý�Ïü¸w _þ’wo¿Â N©?=í“þô,UÂ÷½ïû™Ê�ñ¦Vlú ú ­ Ê”DÆcg•[Îrú íÝçí/T}ŽÕŸ\Ãù•ó«öµ¢iåzE7çWίڔ“ii´³Ê-g9çWíÝ7ýüÊxrû²"åæ Xݼcn�;üéÏ~,ü×Gþw‡%$%@€ @€�uxñ§¼Kx¿?ôÔðáÏ{ÚºíZ±ýùSéÑðC¯ø?Åò—1 @€ @€VMàÁûvÂg~üï Ïy�‡�'¯ÚÁ±=+# `ue… YE�oùþß?ÿ+o OÞ9 _óÍÿc7Ñ6 @€ @€@�÷ÝÚ·öwÂíýí°s;ÜÞß ßþµÏ Ü·ÓãZÖ?«ÜŸþÕÿy'¼ô»}ýwØ @€ @€ °Q·nn‡›7·CüÇ’÷÷¶Â;>ãVøwÿ9å`g t°ÚULú�øØ?¾÷ÇÞ´üý? á,nÅ ý¿zqvΪT率ñ^õáYýA�4¥«ò„A^(¾:;kä_åšÞËùF9 ê÷c)ÅÙYˆ¹åŸ³A\É ~\mg½¾ô'-ÛXsL›7|”ÅòÍmáæÞvØÞ a{k+lmÂvüݪ·ag;ÖóAØÙ‰iª÷wv¶ÂV½LJÓm ÂVü|g´|L—–Ù®>‹yåüSú�­pcg¶Rþõò9]\vP§ÏÛToOÎkk»Ê?æߋ۴¿©¶âoHù6ßK¯Ó{giŸâ÷Wü›–„ô7¾W¥©Þ‹y�þÖŸ7Òíín)EX �{‡§áäô,œžœ…“³³pš_Ÿž¥÷Oâûñ½ú÷ä$„“ÓNÏFŸ�Õ˦´Sò‰ËNæÓ�ž†´Îêuý·Þ†ãã³´Ž¸}GG§áèø4Öã¿�OÃñÑi¸wtbÚøù½£“pttV§?«>«—¹{ïd-Ž×ºîD $(­ÿ÷·Ãí8@¸¿S›Æ×qÀp'ýÍËÆÄø›ƒRcú§zZW>r©Û_÷Éó›gƒ´¯ºÎK/Þ6€@q�ØŸŒ}ÚÜïŒ}Ñf4~–ú£¹�šû´¹¯ÿÝ쳆êßUžu6Týâ˜Gê›×}ÞÉõ¤¾pÊ«îGç×õºrúj›š}îAØŽ_Xõ˜@Ì¿ZÏx>£>ú¨��óÊÛÇ$†ÛWoOJÓì«§1ŠÑ¶ÆñŒ¸mil �Il¥¿qŒ!þ¦ñŠô»Uÿ{«þ÷ �‡ø!@€ @àr�8žÇ]ONNÓøíqú=MãXn‡MïŸVŸÅtq¼7�åÆ×õ2q\8ŽÝæ±ãã8®[�ÇüR�±à”w�>åÛHŸÞ�Ë�¶¥Ú¶*Ÿ£z|ºÚîÑvå÷ã6ÆÏŒ_ŸÒF÷nl…ÝÝ­ô7ö§›¯÷v«1á`zso+�ç@ÓÑûuº½jü8æ3¾ÜvxøcÉ×§dØÒU°ºŠGÅ6­¤ÀÇ¿äñðÝ?Úã¶%ìetU[¥‹g£Áè4f\LçAî”>öÖÚòÀo•¶ÄUŠW\£|«‹�Í´U€W›íHËæÁñ|½ï´¨[Åékó…¾øVü�¡añ½êÂà(q¼(ƒÒ•½úóô2§ !�Ç7bºø~þ›ÒœVïÅu¤@Œø*b ÓVéÃi•&®ÿ4¯'ÿMA£<òºSÚ¸\üéÝ›!;:ùB]ºÀ/Öáš%‡àÁ³ñ;® ¤�~rø}/ÊåïÖ|‘°Þ�¼ð7 ;¬;j;rpïØÅÓ´ýÕ…È|Ñp\4WÁÂUºxa0·GqûÆöqâ"g¾pš·/_tLU&£6*6u;–¨ªI˜lÇb�JÚ¦sŸ�‚–SNùóÚ<3Ç SûV·—)Ð9¾®ÛÕ¼ÎQ›:Ú¦æ:]í·¾Ü;©%ëàÇø7¶ãi€*SÆÈ“ضÇ©X9 ÄŒ¯Ï&–¿,¸2¶áÍuå€ÊÔYqžÄö?Ð5‚7s€gÄÙØ†Æv6óm„æýËÁ£Ã@Îz�cÛPïk\fè�?›é6ÑÐ�6qÐ.~‡Å¾ýô·z�þîn¥Àô~ýúænu·yLÛÀøÙÞ^u÷y~�ïHÎrZ¡Æeü\?�¾äñð]×¼?]Z=·æó‹áùC£�Ï1â¶4ÏKšiÓIHê7o%ÏkPøM¯ÕBÍÙa`n¼5žÓÔAºÃwìȦ÷G¸Ù¨ê�ÇÏ�Ýú®Ú|£j}îð&Øó›úï±§—…Wýñ ߯ӥ¾u}#oÝÏŽë®úÙõožÛ¿¸©Ë?ì{×7ׯ÷SþU¿Ü¦ ìÞ¨n¨��­)ȵ¾7Ýd»?«ú¸7ràk¼éwJ pê³æj7ÃûÇ1 ·ÑwŽ}ß4fsÀîD9Þ¦¾r#xÓÖc³Ãxëþsüº­¯8œƒ™›ÛP¿ŽëÏ7§åsðt=Ñüw50'nƒ�ÏíKìÛAª píîœÔ—£àÍ8Þœ5��Cõú´èŒ•ñóF°e°oÌÏ4A«Ïªüêàиìðß�õ64óúsÐgZŽÆåëÏ*Ø4Ž�W›ÃmolŸ±ãk_L‹ì@|BUŽc¼9´®~Ó˜o7®Ç‹S€i *­ƒK«`Óê½xóŠ}®x:ùy&-²C2%@ ˜€€Õb´2^7�Ÿþ…ÿÞüÄáXe Jh®àŠÖ�2£À˜< ÂÕ�¤c®ÁœÃÀÓRÃïg½†�œ±ͪ€›i³‘5ß«ÒÔ5uúÜyé4fG.;‘÷p]1¯Æg1'wœ†A2³¤ gSk®gb»ªNZc–¶Æ]ucû9‘.ïKìÉ�¨8Ûš @€Àº 4ïOƒz1ˆblp¯ìk¾¿ƒ)ê»Ëãà�Xÿ]‘Æ Òz@1öÅÁÀf j *ÝÝ ÷ßÞY7RûSH ÷§cöÃ~mž�´�YßX9JWºŒÝÒ¸Á¤ ªœ¼™o‚Þ`R‡e^è™ß¯òk®³þwžÍ´ÞÞiû2š�¿'ˆÿd]¨P-0Û'ïžTýÆ.ÜU3º /6Ö3¼Œ.@VýÙ8›Ku¡¯¾ˆ˜/ ¦ ‘� ‹õ…ÆÑ{q˜ªŸŸn–mÞàZ÷éó{Õß*Ðv<Ýø{SÓÅtò ¹i=õ͹õßôo¦mÎŒ“·±¹oÃYlê}Õ_`µ*&ÏSÓM»)·À›gìÍ3ëæ›h3 çY…óͲÃÇþÆdÕëÆ¤ �XóMãÉòìëO‘φ9¤\ë'’ '|¨o¸mŒùW7ÝŽfPN׆' õúÆž T:gP®–s�qz¿9«q38¹~jÑð†àz–âü¥*Pztcr¼™%}Ö¢ÞÞ®o¤®ƒ©óz‡7×O>Ê�Í‚“7¬òÚ]–&Ï͇ý„Ü·¨'Ø©nð¯ûyŸ‰¾E¼­¯êo Æó©oöK“þÔ7ÈÇ[s¿$Þ08ì£ 'ôi|>ì{4—É“5&øn_ó½úu¼åpØå“û,Uÿlè4N:à‡]¬vÑ’–ÖF þæ€ÖfpídïdðlztÅðqÇ¡zÌD®ÍAÀõ݆©Ó[wdóëfG8wpÓEÈF°o3(7u¦ã…ʼžÓ0¼Ã±ü;¶Ýuš¼íÍ»›�ÔHëúhó.Lëµ)æv„zˆw}Ç�¼4ÐWxæA¿8x—Sšx§w0:™>î5?o.7íuÎ'Þ1¾»3¨_T½v“ZV °0�fÐoàò6‚zÓ{ÍG9Ö3¿7ƒq« âÕÅè÷Ü{uŸ¼ø;š¥hôèȤœûÒÍí�7ïæÀÞác-'ö-öëGéF3"Å÷î˜Ù~aÒŠ¸V±_”ˆë â4œž¨Ó|B\<|z\xwvø4ŸÆ“âFO‡› 6=unìiqõ”ö9Ø8LçIJέ#SÇèâ:à¸9ñI¾Ái´O£'Ù5Ÿ87¼ª±ïqŸ«§,UwRåíËy¥›¹OØË3+Çí?�ߌ•—I÷�Åèú�uù¦¯¸ªÉÁÒ[ù&¯úf²á:êýÞpV;Õ“ëW7†�{‚Qó&´ñÇòºÇ÷áüÍeÙãZîž6¶z¢`ý„ƒá“GO¬ž8þy|cô4‚ê³üøYÃ'4_ç€Ã” ñ$ƒú)9ƒÑ“âšO=¨Ÿž�ŸL˜Ó¥m©Ó�­»~PbÞÖáû3¹qùü¤aeýÄ|Ø(83?a±~²b>gÌOSœ8�=M1?‰±ŽÌšé錣÷ÒÓ7”¥€ÑúX�Î]«§1¦'>6ÎYÓC›�¥õgéÜ6?Õ1¿w&P²§ª$�bpfÏÍŸW½®Çwcúf`èÎvœ5´~„ýy4Ç¥‡¯'Mãøµ\7«×íˆÙ^ °`�ƒ{õcDb`ncV¡|/ìŽ=¤žY'ÇÀÛÑÉÑãCªÇ‹Ô�i>º¤~]­£J“/ Žîr}·k [Ïn4 Æm|–/jVƒ;õÀÏ%0ÓÀR}gqs°kì‚is0jbv£hç‡ë&g L³éÔ³ð¤™zê×ÿqÆ�ú©Õ{õ ÍeS~ãù4gí‰ùT�iÍÚ mÆ÷wo . @5s躕ZûC€®§@ dÍOÊ™6ƒî¹ Ý<;ný´›É¾ëØÌ¼)P·êÇ~oΫú[ÏnuEpp쟃3ê �á6Mö»§Ì~UÝÀ[oCÚæF€Æ” äØGonßXàr#˜ã¢4yÖàéuãý”÷Ä2y=ÍõÇ×ÕÍ0a¸üpyæõmo�Öm�«Ë€è" `µ‹–´ @€�ž®ºÙùQŸ�G†ž{ÔÏ%³�]ø›È#_Dœ6CQž!8ÏFÔ¼X9\î¬zÜi¾h˜ÓL^ÈåUÝÉß¼x9J[?¢¨qa3FOy4jš ?>µ1#@º Û¸?^䜼»?§Éwñ�/S_P½0ÏÑçÓ—Ï�,ÍX`fãž+V�]DÊŽÕÌ"VæG60‡iCˆSq«¤™ƒ+ãl#ç‚5s~ëËió#ã ]z¬b^ï”ÀÎKƒBëôÍýŠƒn9ô\ðg܇±u5<êm3Ú fò,S4åJ€ p òlÁé†ÚÉ ×‰À׿£h›}ÝØ·Í7Ѧ÷ëþw³ÿ›‚x‡3ÿ6fnìNï3�ÒV}üQpο¹-U?¾ Îï�¶iú6Œ×ýò±eëäÌ™)ÏüÙ|2ÔÔ×õlŸi™8è�zÙú‰Ry6ÏôøøzöÏÉ|î»efOÅŸf°:››¥ @€ @€ @€ мá7þæÚÉ‚Û~Þ ÖÍ�Ì®ž´3ºÁ´yëäM±éØüøèæ#¶ó#›ë|ò#Ÿóã«Ó£ªëGj�ò¯ŸòÓ¸É6Ï€œ¬�oÈ­Ÿ=ü¬~wÜŽ(�n^N7 WËéÉHuprõ”£:P9Ö IDATxœì�wxÅ׀߽%½HHHè½é]¥ÛP°  "("Ult�"EŠ *ÊTA¤ Ò{ H ¤÷~Ëî÷G$!ÉÝ$—ùæ}žû@öÎ�9sÎÌ™3³³³’¯‹·²zÃ:6èŠ ¦cLuë£å¾Ò¸<Ç’MSh¯+,ƒt‚vÌç‹ïwp:"ßFtï?ž1OWÅ>OÊŒ½ci=õoZNØÍ’®.Hæ)¶é-žù­ß®MCÝýëqg×1kézö]‹ÆìR…–Ýßcâ ŽøÝK£BÓv¯šÆüí'M³Å·V Ã˵rÈd¼ÍîuóX¾ã(WcÓѺРÍˌҗΒú|Œû˜ðü8bßù“½<ó©·ª©{)!_eéЗY|Íôàw’ ÏÎØÍÌV6êdV«C i?*Û°’Äæoæñí¾Ó„$ƒ‹o]:ö~—Q}šá©É·¢´C òPŠe©±E‹•ö” ¢ÿ.�XÿieCQÆ9AþdÜÞÍ7«ÖòÇ©+„'Ñ9ûQ«qW½õ6OùÛªK#‡°jø‹¬«¾ˆ�£[¢Àı…=rî~^>”ù¶�ÿ税ó,øœÆ‹jÚJg7ÏcÞ¦½œ�Ê@ïV™f�2j`wªÚeg$_eéÐרÓá'~ê_m�%š¹¼º}×…Pÿ�M|×7 wZ«–U”7äV �y—òñE_úÏßÊÄ2ûg=ɘ” ˜Ö YגƱoFoœ”Nÿ:Ÿ¿îã\D*Z·ª´ê>Œt¸?v¡^† synÔfjNü�y�ÝrÔ+»ìøL®|‚;Ïr'ÍžªmÞfÒè¾ÔuÈ¡c0ç|ÌâAÄÉv¸zU¦ËÛóù¬c94 ÊJÚ~œ7�o^#ÙΟæÏŒ¢[̦¥LàÐԮء52ËDþ3�¿ú�+fW|Z1èý¡”Û>Œ1$Ðxð ?_­ =OͤëÄ[ ûék^t“@ŽáÏ™¯òñ�î¬X4Ц’ºv¨F‡j1gÆëÃ8ûÌÏüøjåBlŸÊ©ïF2öÇDeÊ(Ú* ùz##khUÈlP×V-¡vŒV e%ºá žÛP�Å?|Jk[5 ¬�$m�@ �@- q{>äÙo½™¿êCšåš¼c^æüe¶6f‚Öõç•�Yþ€MdžfÎÛC8Ôa5ÿ{«nö Ai QÊZ�@ �@ xäQ0›Ò‰¹ü3SV£Î˯ÑDLî´Ta$Ïó󹆱¬Åyä0q}óWlÌìÆÈ—ꈛRFl–�@ K(±üúQ'žþðG2ŸžÉô~b2õ!9¶`äØH]?™•W2ÊZœGŠÌàïøìûº�CG—"=ä(°’�‹·²F<%�@ �@ðH!‡�@ �@ AÄ¢�@ �@ Á#ˆX´�@ �@ x‹6�@ �@`Üø�¨Û©aÖ§ëH¶¤–•,;ÓµaYÆñ—x­‘Õ1žšIçnï²1áÿñ{•�;Óµ)/¯¿‰¹¬e<€X´±„)œýkÇÑïå¶4~ª-^ìÃ�…¿q%ME§VR¸¸uƒ^ï@Ó§Ÿ Mÿ7ùló’Kà”´c|> ) ^ŸÏSîï2B¶1kÜó´ëÖŒ&ÏôdÀœ�\Ê)§yLwØ·z,}ûµ¥ñS-h7`(3þ æþùé2aѨSޤSCêvÊÓÉ-•%_eéÛMóä‘õiðæ.çðëU=L2/±ôÝ4ùx Éù|m¹^–l¡9ž>æµWÛÑø©æ´ìÛ�á+vzoÐWiÓÖ-SŠeå 0[<„~*°¢ÿä'̣׊’F�™ÈßçcÏ»Ÿf¼¶á2\ß3�áo?MË®Miúüs ^�cœ“CX5ìþ˜Z¯sSš?ÿ,?_ÿ±rÖññÁ¢ÏQ™&_TÆ1ó7ÞbÏ·Ðï•ö4ïÖŠÖ/¿Êˆq#³ˆuQ™O©aÑ«LS$lxò“8»ë$g·Ï§—ãBq{Ó›4éÜ„Þ+/äãÕôÙætœäþ«¥åöÎîMӗdz-*»ßêŸäËí'9»ë$ǧvDZ˜/íQ’ϱ~îÛ<Ó§5�žlJ³ç{3àóuœH(cÿ`•±Ã’-Ê€Âêe)>)©@LǙٯy±�Lئ7hüÂTþÉhëÐoô§ máõðÔôÓ¢Äå%ѳJŒ§fÒùé~,»Q¶}EW¦¥?ò8·æ}ÆìðaèØU̯îFú�mÌýbïãÏ–Ͱ-ð· qû§1li(O}°ŒÏy�tö;>›=‚É.ø²“'E÷»©_3“m vH®yJKú›gq½Ãg¬ü°!.ñÿ²tætÆ_“MCê£W%O&§V½Ç˜¿Ê3tüw,®nGÄ‘å|²à}f¹oà³æNH($''£­;Š�³ûQá^%$4z;´j뮩ÆÛ‹2PÎÑåÛlüt(¿×í@%­Úz•ÄFSZ ×ÏýÅkײ#Ôù¤²X/5¶PƒÌí-xom"=G-á‹ÆÞ¤_ý…ÏgMd„®߬ƒN•MsRp;T£ŸÒ,˲-F?Ñ,éçQë?jì%( ^OÏb[ËL@¾±–¡Ÿ¤å䥼UUHغ”CƒBìþ) þü}'°ì“êèÃö³|ñ ÞŽÕ±aJ/|²óóxjëßnŒ^É$>ô(ë—ÏcØG~X2„Z"â+6–}Žº4ù£.ޱœ¿‘3«GðÁ¾ÚLþb=íI»¾…©Ìp¥<¿ m¨RNuù”jü°š4EGÒhÑjô¬YbÝdûÎKTªS‹;{·sf`]šÜSŒÚ>›“ .ýü!ôfØÜ)ô(wwÚ,¡ÑdÉ •Š»b“ÀŽùïóeH¦ÌœJ[?{RCv³ð‹/1×�ߦö»Tƒ+�…Ú¢4QS/ñ‰Ê9R¡h¨ì'±ãN82•òÄ2‘‘H:�suFãG‹n~Ŭ»ÔÅT–ãr+éù!Öôa †ðÂPRÉðhÏ»c^âÍ–¾Y«Žžýyõ‰5Œ¸L‚ÜŒò-EÊüùû>ô]—ðA§ÚؾFðÁÙ=¼óÛŸÜéð~E\ÆL;»Œ™ÿ6aÄ Á|±;Wa„n_ÉŸo°ñí.jïžL^Ùtº,¹ÕÈ#_â¯ýaT{a.ƒŸ¨‚(×}"ã/öfì–ýŒjÖWI!))ÜÊáãà€C±ë.¡³µÏÑe¶~Å7q½øêµzØ©­WIlô00�`ö›ÃØfߌnÏÍdâÅ1LMÉ›HE½Ljl¡B%™ë û~ȇO5ÈZÀòÂÛí61üÌ)¢ä:TШ°i n‡j(Å²ÔØâ!ôSA ýÇ’@�VÿQe/Aah<©�mHs’:I‹“§~>9Blù&¿ý´“”¦3{pWÊI@`f»™ðk< >vÙùÙ»QÞ»âOÜÅÞÐÁÔª"œYñPásT¥)UqŒšx(‘ «a86ý�î�Nhç*=éÝx>»¯]%Qiˆ—d­|š²óÑ� ?,©ñÕÖ˼�­!uxiá »�­gß§IÓìÛ„rˆê>›ý¢þžÎ¨uñô˜´Š7«ÛåSbI„½ÎéKiTfÝkú¢Üê¾ÀÇã~ºá�I$@IàÔ/s™÷Ëß\ŠÍ@çZ…–݇ñaÿvT¸°g±ñ«©|½?ˆDm9vÁSqÓøÒ𠇦tE{ƒ‡/ãR~;;µ5²poú�´êØQ¨-”dÎo]À¼ÿíálx2’keš?õ6zšJÜÙU3{Ì8Ԛʪ±�ñºc¥z©ŠOÔÌ‘, q'Ðß™”ˆp’ðÈÕg3‰ˆŒÅοå4`ZÄóÃVlÐQÈ&~x%çB��=3:1Õv<“=÷²ìÀ5¢bSqªßŸIãß ©³„Y�ÝTôSÔÌWÕÄ'VŠÕb±ï”\‡bѦ0$wš¿0‚æwÿ–S¹uòGÖÕÒbP¼ LAœ»&Q§Wí;=l©S·6ì8Ï%#øe HÆi–-<@ãákh::÷wJ'O]Å·îk\øv4ö_&V[ކ�3úµìÆ¢F­ ³ôz}ŽÕG¼½ÝÉÉwŽd-álá2¸-áÕÏvÑdÂOLhIXTlï�ÐVƦíC�MA,öGòËM«%áïµìxw«¿­‚mÂ>>{gÓ7¶aã5ÕÙ]M_6¨‰ËŽž‹�š¾SrŠÛ.ª0q|I/š<Õ†“¶àÜÿkæõò/TyJz<ñGÜ]lÈØ;–&�š3lGzwœŒñÄ鼕 άûœ=uÆ1ª™ËƒÎ\ŽäN´‘¨�«ØáøSf¯dÑ�–Äm˰ÕgÈP+�®6mšºrqË þ¼�Ž¢dwåV)9�$PÒI7Ùb“’‰O÷ñ,š¿‚Y/W'øÇ¼³ú¬ú²raäâ¦eìó~…!­Ýî×OE½Jb£‡ƒ½ÎB©jê¥ÆÅ"ƒ _¦ðuP-Þx¥Ž Ê¦w[h;TCi–¥ÂÖí§‚’#úO¡Šs·‘¼×²2N”¯Ý‡�>�Æ»Í\³våÄt‹ÍŸ�f�íP¾žÐ›Šw'öÖªW‘ã“æHÑP®b ö1a„›ÌÜ8v€Hs"Ž]Á$G­' bÖ®+$-z½-¶66h *@üz2¤kì�[+:ÖÓzã:™ªõ“—û©º¸üa蹨é;PbŠQ\:꽺”ÿ­XÃWo5'lÍ{ŒØ„ÚóØ$gjרM ËÝ_ŠFÆå•Ì8T� o·Æ%ßÎdÂh–‘ëdÊËí¨áëGÍÖC™Ô¯!þÎÉ<Û¬ –Ç‘öïÌâ½€ÓLÔžæ=:ÑgÑ%uh‚^«E'’+½&ïåÐw Ö¹µ«Ó¼ûf½R�üÂq£Ú²î£¤`ÝQ´|þY*犊R¯’Ù¨tQS/¶(*rG×¼Ç[kèõé\Þ¨’¨´©åv¨‚Ò,«¨¢•°Ÿ J ÑÅþ#x˜HH((�’L̶´êÞ’fÝž å€ ìrz‰/§¼I�²Ÿiÿ‡QãsЇåOaqŒšü3¹ðÃHÆýíÏË÷qr÷Q®œ@í“3tå)Ò¬šOñɈ¾Etq.È5M I=ñ»SŸ g›¬su¥­tˆ-‡²cõ}6îèvBö¡µ²ƒ™ ¶ù�Î:Õùvaü¼møi 3^n‡Oün¾û/ÎÙM” ˜C 3paås4¸wðmcž\t‚̘0î˜9’ðh¨PÁ÷þâ�Æ�ß²s0ma¼Éµ[X)çã>¼êvãÙÖ5s�‘r�`ÊÑÞÛ�êe§uÑâ“‚çH–Ñúâo ',&‚£§hÿÜÓHgŽr3)‚ð´ Tñ³)Z~^>Ü;j ½^fSñ~VÑOK—?„8° Ôô�lJ¢Cñx”EddYƒ�{EªºW¤jÕ†Ô· £ÛŠ5ì5“.thÉÞ›Tâ ØvÍͲ®'ïŠ#ÕÖ/•­%óß,ØMíw×ÐÆY"ß&+¹áá¢ÃÑÃ+Ç©ò|üüЧÄgP/�äÒ„Á3¶0(-�$Å7G-—W½Þ�s4²¼hð DŸCL†Rĺ+$ÙÂ>s+¦¶Îs諊zeµàâÙ¨ÌPY¯âÙ¢2¯³iÖHæÕbÔ¼…ô«îhaµ>·M‘/Zn‡Å¦4ËÊ�Õú© ôý§ Ë”Z÷òxëd¢¢£‘ɹƒÔD¦Aƒ­ÍÝ+Ü;|ÊÚ7¢×èqtóÆÃ^„y%F�ϱS¯„…8F¯"Žóó¦ËT8‡g«»¡ܪô`dŸ-<µbÇ5¦ƒÎJùm®— }Êf,³å�±ý¨U”1V�.²¯.JûÿÚO|z&Óû·efÖEŒiH;÷ýdÊ©î³ÎOŒgÙøç°9&óê'_ðÉæ:,}¾ÒCš ip(W—ÝëÒ¡û ÞÚ3ž>_ÊÏÏwäý@�$=­Ælç›Þ^ùëÍ”½•kX1c6s¯}«:ÛÄZ;ÿÔØ"¯¸…a¾Î%CºVü�oVì¢óGOß‹¬Y/õñI!s$h½+`ó?Ân#"´]?j�é÷Ÿ9vµ>QÚŠTò)º ’¡Hú)¤ŸZ3.·jh©,K}'gÚ®‹3mJ‚ñÓû�äRŸ�¬ë[ñžÓµÑëÁ˜IfaËbºÚ4ª +Î�'£K‹ìC£28wæÃ®ìk²!…Lƾtˆ¾SbLýò4¨UŽÄÓg1· ZÖX"Âncr­Cy@£F3·�þÄŽ´V ìX%ë nÓö¾…w£fTÒdýý¿+¹Õr£ÛÞu fn^ÆäÖ?{IeYwIãÄ‘ã˜êŽ£yÞý«õ*‰�Ê 5õRc‹Ô~ȼÆ�“†²$åY,NK·<ß«°©é¢švxß�(Oi–¥†"öSÁ#€è?�Nÿ”ö�hY[ËÜLjìÓßl3™B¾ç­Q{é4ÿ[Þ Èº¦uô¦¢ßCzÄâÿ+j|Ž*¿Tjâ[ù+fLfYνUÃl–Qd9ëN®9Õäc ù:¿-^Åá|ßÑ›AÄé} ú 6Ì~9÷Ûk Â’V›Æ (ñûØrLCç±?ña“ûŒÎ.bà¼müù<ýË©í³vå}ñÐHè[Œåó~çyë›OXYoïXq›‡ñÊ�|´2˜Ž>¦§gŽEÞJÕð–Î’”¢€¶Õüaý•+dööºwØ­)!œX»ò”·Ó€Æ/…£aa˜ñΚDšnj‚êYéU�mb%TÙÂ;€ª~°åÆMÌ4ÊžøÊD�ÚÈï¡•x¦÷÷'ðúf ?žgýx{øL>û£Kzd�ûbµz%>)dޤ}U|’8ä(—›ó‘g# 5f°ÿ� Þ•°âMmÕú±ÔO­—-,júŽšlÄ™6%@ß�®íÊqñ§é,ý'ˆð¸hnžÝÄç?ü‹]³N4/ì0(�]_è ;çñåžËDÄGpq÷æìÖÒýÅ®¬ðeþ;‡—ÞìÇ´C)¹V„uu†ñãú-l^¹�_Vnà—•?±ìåÚØ”†/–.ãíZ:@Gýg^¥aøw|²|'A1qÜ>µ–™ÿ ¢R÷gh¨S+�„¾Ÿóf°üø-âb¯±sÙ¾‹nÎà>�±Ðúài<Íw §ðíñëD&Dpiß|&o¼EÍg^ ±ê²²1ßäÜÕL*V¯™Ï6~õ*‰� ¦ÌtÒÒÓHKOÇ`RP̆¬¿3Ò1È*ë¥Æ9(¨ý@:'W�ãËÍùhâ êêRINIÎú¤ef_*lª®ª�§4ËRc‹"öSÁÃFôŸBåyÔú�ª4‚£ñ¡÷ë/â{q ,ûƒ7npùøz>ž´Œ°}é ž}z¸¨ñ9jÒ€ª8FEþº†<ÕÚ�s¿-cÛÍdÌȤ†íeÅïgpkýdö+�­•�4UxnÄ f}<ó�ÏÌþ�ñi0†USú©[°Qã‡U¥±2áû·pÔ¦ Ïv¬’ë̉Êž¡³ó9þØw s±ú¬�}ΨZ!¬˜¹ˆc©ÖÛ%©«à�]èoÌš±„?/…•Ãí«{ùfùÿöhKÇ:ÐT¢×³-0ìþŠyo‘.›I ÙÅ—^dÀ²c¤hªÐ¡¥?{V󿫉2£8ñ¿µìMÎÀ«:ÛÄc‡J[h«Ó»wcÿZÄŠwH3eså7æÌ™Ëæp=.ù´A}àkL·>–}Ê·Á™V®Wâ“BçH*ÐT ’ŸÂ™þÅ£Éxk\iÞ¸"g!¹Be²mÍF™†L2 Ì Èf#C&™Ffµã¸*ý¨è§ªâr+ëY Š‘¤Ø0Â"îÜÿDÆ’&£®ïXA‡b§M¡ØÓ|èR¾t˜Çò¯Þdel:Z—´ËÒ!=-¼™HµÕ¾1Ÿ/V¥Ççé8ø6¢û¨%Œiåª~‹›Î //§dLNz$­#î^÷vÒú¿ÌÜFf-�Ëë¿Fcv©BËî³XôzÝ솩F ~='33bó§÷ayš-¾µº0jÖ^¼{›@r¥Ó¨%LþfßÎ|•…Éàâ[—ޝ/bTŸ»[·ŠPw9šÈX/ïüX²\¯’Øè! _ã›á/³øZνmSéÜc*H.<;c73[Ù¨¨— [¨Átžm{n’}�ûoÏõ•Æå9–lšB{� ›ªl‡QÓ~¬U–J[X¥Ÿ ¬ƒè?…ó¨õŸ!ªì%()N�ǰrº_®^ÂðÍј�hÒy+ßêžu_,�=T,ûuiòG]c1É•Ž#—2yõV}ЕII&´.iÔá#–½Õ 7ɺù£}&N (|÷QNÔøaÔøê’É €|‹í;ÏáØr -ó¾rȶ =Úz°yן÷J�âôY]^›0�Ã&ññâ¦üôa§<¯j.’s{>ž;›r«Ö²`â÷„'Ñ9ûQ«ñsÌùòmÚ8h¨Ð}&K ó˜·¼?í¦e w«L³ÎŸðõÀØg H�Wg0>r+Ftf¶¾O<ÿ!ýdNQR9ÖžGlñìl–ÊóY°àVE¤¢u«J«î³Y6 q¯ÏÖàßmŸ|•�g~M“E£hªæ±•õRŸX˜#YÆ–ÀŠ>$þmäÙÆ�hÑàÛ¨®ËOcW1 ˦¦™Úoãs4ÈU/Òl •ã•¹Ûø¤q± U1•Š9¤µõ¬s0kÇõbmÎkú|¶~9ý<Õô�’#ù¸x+k6¬£aƒ®VÊR �@ þƒ÷0îÙ ÇýÍ‚N¥¾e»@ 'Òvº‰é[æðô#ó ¤�]ÓÚ3�üói—¢ï`ª›ÿ�@ �@ AÄãQ�@ �@p;§¶ îTÀ¦#_üò½‹slI1îdL¯ØaÈþÛæé2B ”5âñ(�@ �@ ‚Gñx”@ �@ Á#Ƚǣºÿx¸,åþ³È²sR’V¼kH P‹¢(h�\Ðhı…�@ AAˆ3m‚bNIÄÆÛ¯¬ÅþsbÃѸx–µ�@ Á#‹X´Jˆ„”²–B øï!ö¦ ÿ üÕáÇ&iŒ^w““Ʋ–FPˆ6�ZOf¯Žïá3 <šŽ\Öò¨á¿(³ ì±õfÁ;Õè �ùwçIÞ=k,ÞôGëÁçïÕ¤ÛÝ×Ö›âùdÙeþÈ,zVξ¾LèäKoœ%…´ô8¦w•éEKSb´žÌ^ƒ§î®¬˜b·8ˆ]fë!mŠ€dãʸ×jÓW ç�5!œ³èé´ÔnȘfžÔsÑ�™œÂÞã!Ì;“BòC�ÁÎËá�üéág‡£9“óWï0g_$— y2Ñ;2¤o=ÞJ½Î“¿Eç/‹µÒ*sôSHYšÖã·ŽÎèsý@áü�Ò�ò]µÑÙój¯š¼œÊ«Å‘’çk[Wwµö¥“�-fWnD²üH ×îCZ6öãÕÎT²×�–œÊþÓ·ùöj:Eók:êÕ÷ãͺ®TsÔ`HÏàÜÕ¾9‘À�l唯_“•-ó8…+G/1æLÆ:”ôÎ }®½¤(>ø_—‹àµK³¬{X°…ê4+“�1%=Mš2¢‘;µ�5RÓ9q)Œ¹ÿÄrË\„49³,²ïòXUe•½/;$;'ú¶  oU'*Úk0efréFKöß@5´ IDAT…sò^P©£~£@F6ñ ®‹†ÌäTö� aÁÉdÉΛ…ïT£uòÞ\Â3 ÙòJßFŒóMbÚŠKüšnÇ W1Ò÷ÁåR9-’á+®s8?›Ù¹óö?p•SF‰ê­ê³¾µ#Ú\)‚�œ£ß¡T¬§>hméÐ"�!Ùãhjb2;þ½ÉWÓȸ—ÆŽŽ-\Ç•ÊöÆôtN^¾ÃÂñÜ4žýcÙ¤Üe)ŠBzz—oF±ü@8GSÔæêôSÈ)lÜuû(CÙݻˡgE‘IK7pãN<›�…ñËヾóQ�ù¿ˆÛ³ú"½™;À…_Vs°¬�jf4,ŽE£ufì Z–8C™Ýg|� Š‚œK}…ûº{héÿt mÒÂøl}4Á Ф�œQÄ4ÖÀË„…G˜(�MÕjììaýÛ’bÑF5Zš´®L7EåáQ£ ;س믋|zˈ‹>ëZ‹O2Î0áJqV' –A²wgü •©Ì;%“äàÆÐ•™Ñ"•—¤`t66TöóäåVxÚC‚ÔK°V52«Ñ�å²$œí´ÈwBxqS$á÷”ª`6Ë¥è+÷­©Óë©èãÎ3MÊÓÎHUr} Ùºòn7®‡òÑþRì]xµSEÆ5Leø±4ŒHÔmZ•�ªX¿ÿ Sbd¼|ݦ CÒ.²ø¶¬ºýøÖ®Ää&Zö¼Æœ;Fì¼<Ú!�Oå Þ?žŽ ' 9â6ïl�&*‡es^G  ¡^:Ú™Q2²ë¦º1—fYêl¡&� ôðoP�­tü¹ë2ŸÜ2`_®ãºUcžœÁ+‡R1©LsŸ¢ûn!�uå±\Ö#âÇËO=Y‹QžqLû5˜C f==y¯[%æ=mâÅÍÑÄ áß°:‹;ÚñïßWtÓ€k€u¨ÍÎñÎÉìE-ÅD²�'=ýnq&TFãîEO™Üs …¸K×xã`r.Û(Š™Ø|'µšTäÉÔpÝ‹[nœ¼Lï Z¯ ,yÆ�£[/±:JÁ˜ixülÐШMmf×Éä›?Ï3*JƧŠ?“Ÿ¬ÅØ´3̼iFA¢~ëZ̪™ÂÔ_N²=VÆÑË›�Ÿ¯ÆÉÀK'Sðæ”ǹ d•5à@&Iƒ›»+ýÚòÕsýx›+ª:·ý” ­¤`.ΰ¯drôBT‰J·Ù6=”н³-êû1ò%wjþ~Ž™7L¹Ã¦GFæ‡I lZ(ÅmÏÅ“GëåD­Gh¦n2ç·ÀRó™Yöu÷ü‹Îžn2ÿ ã﨔¯&M±xЦröÅúí.‹G¨)<Ú8øû3¾rKN90®–ŠH¶<ÝÈã…KÌ¿’Šˆ e¾¿KyáÎ�"µ`$*ÖõãéÔ0^9G¨$G3mm ÈJÖ@®qaìÀÚt3&±ãÔUfW¨ÉǶy °V52«Ñ�¤®,;Jš�ƒ™4ÕÚ´¹öÙHN ~±�)ì¿pƒ¥å«ð¾MÞ½8jøÐ.-’÷�&�ÇW㳜!€ä@ë*6ܼp�Ÿngí>‰ eE¹zL¨åÊšÛñ$©’N‹Ÿ3\:{›åײôLhnx3ÉÇwÒ‰muÈ颌²EÚûøòNÅÖ^°ghÕ÷H©•¥Æªì%xX<¨c•\áÜñ›|y)9«½¦ÜfõÕò,ðwÁ[J%\Q“æ~ŽEöÝB+Ë£®¬²öãe†Æ�†¾Z®�¹ÃŸ‘™È@â�Hfý/yÐI€äÄKÍ\1^¾Â”“ Y÷.â‚ù«1‹šúÐøÌ NÈüsSK‡:®,M  ¶®· ©”{/„l0ž”YÈ"Bñœ½ÖHÇöm\Ëïš2 „g‚ÖÞŒ HIÉäNÒcê55Žt©aKð©+|{3kq$úü æú6æ‹î,¾C":j”·%%ä&Åš‘�ä˜h¶†Ò©œ.$[`þ�w� F¢’ �Ȥ ¾øÛ‘¶Ï{ÐÁ#Œ+1*ÚŒý(:5©ÄˆÆîÔrÒ`JKçè…[Ì=Ox¶ÜW_VôæÈOW¸P£2c¸h¯ÁDû-±h+Weó³Îl^†Å‘÷eÓxùóc‚¶œâ³`3ÚòlxÕ�*(xG Žº ÑÔƒú®:”ŒtŽ_¼Í¼b 1ÝOcIfµÈ#á‰éÓ¹r;‰H]C¦µ÷ecÈ-®È¨“YÒóÄ•ÑÀ•*dCg.ÝföÁÜ2[¬—¤£q“J¼ß(»^éé=¿^*õl ›ê*Wå—Þö¬ûî<ßçØ¦¡q.Ï’7*³íŸ^S¿Ôl©=[’'S…~@¢Å“Møº¡ `ѨrÙ…'3õ¾KPTéÙZö*U4–}ÝqÜ™þn-zÞ�>Û‚îÙÿ5Ç…1`m(%id°F+ÆS]ÅB,Ú¨AïÌÛ�Ý9³÷6qìß Žåº¦§‚‹DzJ&)Ùy;ê%d{†t+OcO=ÚÌ Î…³úl2¹b*�#¯´ráÒ?W8éVõ~ÝŠ«—ZYjl¡Ê^‚ÒÃÄÁ¿/r0ç%Ɇw-iÉ™dÍԤɦ8¾[ÈceyÔ”õˆøñ²@ÉàF¼Âó5|èxíûâ²&üI·#Yu;+‰ÆÅ‰†Î gn&åØl*s:$‰ÌzN4p•8‘H W¯ÆQ­‹7mLÔ¯©áÀ¿©Ô¯äRLá´´héOýˆÛÌyüöϨGB'�1×íS…è#¶�NTÑÄpJ6òoPÃZ”£w¹~�2cïåEÏŠ Ç�&_Xö¢ Ž ýø7¬Á‚ff–m9ÍÐpö^^Œ¶:ó” ¼~8kןœ’Î £=íÛW¥cf<_¬æR:8je €ÅödoºÕqfEdRv|*Q¯®7U’cøâf–Ì‘·xyám$�C_«Ëùˆ]¡Au·Õ°éÏ L¸mÀÆÓ‹±½ª±Xg¢ßžDÒTÊ\<Œì»˜@ZoWžp¾Å•Du2;V df#‰%ÿ;Éæ83:'W†?W�ê¤0òlÖ‚™åzI4ªÁW-`Ýïgx綦?_ƒ¹òyI%M¥ž­aÓÌ�~K¬Çóõœøé`J¶N%j—£qJ4CnX·][’ú1¡plÏ)ž ¯ÁöŽ&&|s�d@Q0ÝóCjò±Ž½Šß‹ŽÆÙ²¯;Ïä¥ÿ2ÍΛyƒ+õû)>¿uw¦`”Ô¤±N+5Ý”bYÿQ4ÔoY™Žá7YtÓ¤z¾(éõ¸éÌ$¤ËØÕ¬Á¿c[ðU]Æt#©Z=îEzË­4¶ø:ið®ãÇÓ†(¦mºÀ艸7ªÁÂÖÎd-2*yŽü°VË2«Ó�š²4ØkeŒ¶".Ü`ôÏùèX•Ÿ¨Åâ{u/ îîÍ�1ÊrŽ¿óùHzÊ9HxV/O{c ·_aêÑD\ëTbJSlQ@IåD˜‰jµËÓÞ5ëÀV7/úV³Ek«ÁI*$ÿB?P¹~¯y¥±éLid-VØidL6ÑA¡LÝĬ3iTlT…©wåÉþm­Æþ´ŠºÅšÛ&”b•_še©°…ª4âóð>–ÐP½IU†–Kå»cñ<‰YPšâùn!ÏÃ�ÇRY�Š/¿í¼Æ&ƒ35c÷u™ÓÙ�žþ¶÷ê­q°Á]2“–{õÊ”f$^Òãípÿš9&†I.<ÝÜ›væX¶‡çÕ¶„gƒÚÕ‚s|¾oéð@@¨óòá½Z&6Š&Â: 俉œÊ?¡&j5ðçiw <Ê—ã�Úöèìt¸d]pûì5>ºlÈþÍùwLKö¨D`p0“Ï=xV[.þµ7wÞií‰sL{ãTf¨B?HtoàLØ™P6„1¢�Í¢S©T®ãEí»SŒÄ¦IÔrNeÖŸá�7’œa$"Õœå—Ì)l¹˜†w ošÝ=`KïÊ35m¸v!г÷æ÷ F³ŒÁ\À#/’½º�|!”e×Ó‰7˜‰ �dÖÁ,1eÝ1W+s11%g�žrNwÏÖ° 3`çhƒ£b&93ë±TCJ"ó¾?ÎûÙ 6ªê¥q Wg/ÞbÍm""Xr.“ªwë¥FÏÖ²©œÊ¯§’(_§OÜ-KãHï:�‹ä| ÖlòmÏ–äQ£@–e ²BÖB�ŒÁ”e»{@M>Ö²W)¢Ö×™Ì2†ìǧÍr¶~²ut·y[Lc­6VJˆ�6°õñgbµæ¬O p*FrF&—"S¹•~×´E3±e$ôZÐÜ gêÑxo1ý˜+›yÓøŸdŽ”ò ’¢è­dú1±mËq¶å¼w“��ØÐ¤M'óOiÔ½ ‘ó�ŸJè5 EDñÕéĬǜ’ÂYtÚ…e <©{<•“²Ì±#7ø¾C ï÷iÈHY!56ž Á©´© &µsÞ\èhØ´ êiØ»;˜�±w30³g×YöäLšp›9ö|]Ï‹ú'R9.ƒ­·/鈴ü÷$’p(êü»ÔËʃšß—´ �õ�ô4oUƒ/šhÙöÇeÖFçc”BÒXÃw y¬#�å²?^F˜㘻!Ž¥.N4 p¥EeF¿èÏà‹W²3ޏìtùkxïÉ�»Èé츜Îm½ ý÷Wd·<¿PH¸rƒ¡‡sŸ±bHÏÌó˜„ ]Ûøâuí:?Dþwˆfþ}•e]«òÉ æ|fVH‰ŽáÛ dº4P²õ¨¡N‹š|Q=ƒùß_f[”oOFõ¬Æ’¶—t ¹ÐÇþß6 áY¿ûëdýßV+s;$‚ »Â¸Z„t–ô­±£Š»†:mq¢mžÚšŒTÐ’uè¹¢`’"Bâ¸�ï³a Á¢9×ÜŸÞ•B8|Õ„SeoºØ%óõ…4õçkií©ê¡§Òs�ñ{'†­wÿP+sq‘$4€\„<⮆ñ}�ê|>¸)CÂ9šÀþ+qOÌžœª¬W%W‰IϱCC!46œíðÓÂ9Y…ž­fSˆ¸ÁîVÕx¡Ú-_2bãïMwÇD¾¾`aAõT´gKò¨Ò� QÔä£XË^ª”cîzU¾®¤X±�•EZ´ù¦ošú¾Å²É¼#%è‘BçÄ[Ozpißyñ”iÅh$ΤÅÝ^ƒárƒB²®;ÕÖãh2£v?•#qé i©†\AAdB&F[=Z(Õ“UÈl5ýäŸ;wb30ÚèñÒS u/l–ŸÏ*€b$!C&=Ý@zŽë1Im´¸i�AÉLfÃ_çùE¯ÅQ’I6@Õfµ 5ƒØ¢ž¦³£k‡ª¼í•Æê­!l‹µt�±Bd|F½w½&úµuåÚ‘+œÈ̹¸f�ŽÒ*K¬Úè:ƒ%cTÒÒ Ä‹?¾¤Ÿ¯cAQdþÝyŠwÏZ~+RRº¹ÀɺœÃo¡_×÷k ´«ëŽt=˜¿ŠøÚW5ïŽ)ŠÌEÅÎÕŽòdr§o5RÒYòÓI6”w¥u +Í+ù3¿¥?»·_`ÊU2êêUhÙÿªÑ³µlŠ!�Ÿ/ø¦�.GQ³ž'š«×ØSäÔÔ·çBå)´ëPØâGqò)-”"úº—g­6V iѦ©¿Ëãµ(c��=½mqéÞ˜.Ù×$��_¿ãÆÆÍgù*¬›S9 où9a{91û�" õý�P¢ns9O*ÙØPÙEKZr:9N4R'ƒ�ó\ý� Ð$œ}ˆUy7[ôé©D•æÃˆje¾S4ýˆÆ‘>Oúáý ¯Ý}«�D —=ºôdÂJãaC <åÞ9,9¿7p%Ê€‹¯H"$k�^Î6è3Òˆ1* Høú{ÓVŸÄ¯72²&Éžmˆ½“LXÞ·QéõTtÒ’‘šATÞ:kíy¦K5úÛÄ2ý·;œÎ;q’ìéÑÖŸÐ[¬1ÝÓ¡Ÿ»-ºŒT"2tåÝéì®Ç©CÚÜý™N‹^kÏôלÙö×e¾Íq'®@yJ³,U¶(F�õÈOÍ:^î]›wl£»>”£ùUÒÕwä…<%—GUYáeïÇË}y_¦µ³gÿŸ×Ùžrÿz|L18ãl rL2g%ž­ì‚ó¥8²æ4:c“ÃÉDr½ag�4×ÕÉlQ?jd¾nbÿ®KLoÈÀî xÏ’SøûÈeŸL+¥Ïs>NcOßgkñºgN™+²î�Š€‰Ý;Îñe¨‚œÉç;`hK?¾¬£G“™Áé+×™zòþÛ´"/Ýd®Sot®ÅËz™¨èDÖüy›íù6<%Ï'ɉöUmÑ;Úòa?÷\¿�3b™üCÇdG^eá~¼Ø±&l %9�O]cí¹lÊfâÓrÛTc�Qd ©Ü}[€<”fYjla§Ê^‚‡EÝjœéZÓg{f¾å•ë+9=Š‘Ëƒ9¨¨HSBß-ä±¢<ªÊzüxÙ dÄóÅÆ ¢ÛTàýç}ñ±“0edt+š‰oóOö€pçÜ5ÞÓ2¦iuÖµÓ�ž”Âî}—Xp.³ˆ�,HxÔ®ÎæÚyÉdý†SÌŽpb`k7ÂŽŸcW�·¡%*7©ÅúÖŽÜ}‘tÀ³�y…à#çèw(ÅÖ‘Îõ<ÑŸ½Ã?F:ÖóÄ6Ïÿá±�²æÎÙ`>u©Âˆž l#Ç¢_BøåÞ]_ï¾ÄÔ6 z± ŸÙK˜228t�á ¼èqm֚ĩÕOø¹k¼¯ ddûúìî©Á˜–ÎÉ+×q¸/S2¿]Ê䥖œß•Ë9}¢Ö��†Ôæ…‡?Ó¶!ÿ´þw’Ïo)Ü:ÄM ïwiÀ W-æ´4þ=Äð#É÷îè[Oæû65 „†Çóõ¦[üv÷,52Ëœ8ÄÒŽ�L臯�„É�É…k·{àîŽx5õR=}•QºJŒìÙ˜·ì%Œii¯:úÇøàÁ­<ÿylªUgOO‰É‹ƒØeÅÇËÄ+¿�@ �@ðØ¡Õjðôñáãv.\>Îi±`#ø"�JJa ‚‚ÝF ÁCÆgŸkÌxÇN_cÒCxÄFP4téÕ‚S½S<Ÿ,»Ì õ_@ëÉìá5xêîÊŠ)ÖêEˆE� ÄˆWD ÅB¡“@ ‚‡…�_6ýË/e-†à>æ8&.<ÌIJ–Ú˜cùð«Ãµ±h#”­‹¦ÄØ‚_Ë'DQÐ:{–µ�@ Á#ͽE›£ƒÝ KÀìÅË8:¸ÓCH øoâSÖ�@ �à1CD,�@ �@ð"m‚Ç#»¦½E¥’ZÖ¢-úÓ÷ׄO™T“F xÄgڊ­Ÿ&ÓzþeŒ¹®kiüÞ—lP­šl2n0wØ$z æì—íq-²iœÛü“~ø—S™Ø•«J÷W0é…*¸Þ=FENâÈúuÌØx‚3Qì<ühÕí&¿Ý‚Ê6ŨKA2Ë¡Ì8�9A¾x^Wµ®ëK½î3““}fçS*Üúy2mÖøñÝïo<ÜÊýW(,žV Z{¼·ß[l3ÖïK±^JÊM~Zþ#Ëw_!8QÆÑ»"m»=ÇÇo>¡²,…ð�ÓxbÎ…<ó‘»èh6b¿¿V^ÝΧ¶¬ÜÝÙt‰I/ÏázqÓ…’ÚÝZókÏý(IÌ]šeå@Í»¤óðG„"©gÌ€ÿoçÙÈ$&¥¢mð»<�ÿ=ï!¡ÕÛXX°Q0¦%põôa¾]¹•ßo˜À£82(Äìù†þ #è9ñc5u!áôVÆNŸÅ8—Ù,Ê …�_2pe Ï8‘EÍÜI»²‡O§-â �7;‡VA¯ª.*dÖTdÄÊÕ¼#çX£6Gñýøél¬ß„j(%�#ß|˯ñ¶H¹GWN­œÍà?<=q+k:‘výS§¬`å8øAl1qâ›Y Ý]…/ç/â…ʶ¤`üØ% �=Ù÷~ ô8ºì ÞÞîÁèO§±¶¦ wmdÔ¬ÙLrŸÅ¬–”˜†Üª IDATþ4OƒW÷álV½b&9â ë¾ZÍ»c~]÷*M­½P–(2&EB§)DËjÒHAíÇZ¨é;Ö+Ër_VÓæwî÷�9“èàãÌ›óƒRÜ9<³5®Û”¨�ý·0]½Æ9±ÍçñB¾ÃoÛoP­~ ·väÄà*´È5VXWtyÒÈFbCϳzÑ÷¼>ÖÈ–U}¨'nÓ%ñ$�^õÎCØðI ÜâÎ1wÒJÞ[]‰ÝïUC¯Ê¿çƒÆ‡ê~°%,™¼“™;wâ�ü›SY WK¥¦�"jâi5± µÆ{uñ½å6c­ñ¾ë%Gòý'Ó™ÛœÉÓgÐÁOO\Ð!¾˜µ�WÒ>bï˜:*$ÊõÉá6À¼…W'œ¦ÝÌ�^=«غxáQ ½�4:´ÿjÒXÂZv·Ö¼ÅZs¿œ”$æ.Í²ÔØÂZóðGqëʼn‰iHnTp´ÃÑþîÇ;�….eºÄäWFðâ¢3è{gzûâ-ȱü¾éú¯3é©ÊøyxR·ó«Lê©ç¯M‡¸-J*×Â%š¾6ˆ)Ý«SÉÛ‹:m_àýŽÜ8y™HYe]TÉ,¡·µÍõû¸]?°0¦ÓVÃ.OêÔÓùèp-&ô ÈÝa•tÒ=›0vÂ`Þoˆ¿—'5žèÁ›­ˆºq›8PR¸x9 çæíy®²Z´¸VmËKMí¸J¼˜nðÇžHjöÄû­üðñð¦Iï7™ÒÕÄæ_O’XFûµöÎø–óÄ·|9j4lǧï¶Á3ì{C²w(¥‡°~Ö4Úv@Å6¯S»ÏÆo»EFÎLäD®ýŠnϾE•ö¯S­ûX^]ðÁ÷&kF¶6ˆêŸüÉÖųèñúšý_{ç]EÑðß¾’@*i¤’JEzï½£((EiR) "JïÒŠˆ4iŠ€ ½ZBBK ½½÷öû#…—@ò&áìï8'ÉݽwæÞ™¹3;;Ûz ÍÆþαY ÃÁ¥Óhت'Þ ûÓ|ÜNÅÉÈ1ü»n>:õ¥DýžøwEß%ÿª32'ìw:4É÷—°wáêµèŽg­÷(9æp†Ý"2¹!Ûø­ÃtÑÝ?àS£;=¶ÅeÞ+ØvH¼Åš‰c¨Ô¨%[ã�™G¸¥{Š¢œt µe�˜ Ho?îT¬Û†þõŠÆ�´ò Å™!†#?§Åt½žø·Å‹3Ç´P ‰ø^ŽãäÆ%¼Ýù#JÔíFÉ6ŸÑcÎa‚“r©Ëd›×±ÿ»þø ØAèÃ?éV7m»w�±ÌU>Ÿþ2£»r€ 7JðÞˆÖÔ‹:̯'Ÿ\•39®˸¹Q®zS&®ƒ}ðvÞTâ#︾u#›�Ú3kPu‹Á3 Ó×,ãÏA¥R'Ä"ýûÓPÙáëmMô�OÉW’ »Eáb¸§gëªxŽÍ i›žx7øˆF_láXŒÑ…"ýž(¦t™¥O@$7ÉEÇ{sØ#3æïó±\º«ûYvÜž>£? [e/¼\]©P¯c;z~ì WŸÜ„ÿTÔVöx¹»PÌÝ/g+4’ §ÔŸ‹¹»PÔ:-ãÈMó sùÝ\ósÍýŒÈ1ç ßt õ fš‡ rµhóê}ÏËŽŠ�è˜xTÇ7ä3ª¶úˆJ]Æ1xåÂMuLšÆ¯_ÉùŸFñm§Ò8æ%út79q*VôåñNI-å+ø"] æL ÙÐäã1¬íðXÆð�ë!‰X»¹PD%X–<Ø,?<Âä%·h4 #Õ³.¯'\â‡é'¨þÉ»4°Ëò7ÉŽÚ�ßcp]çÔ 4$pãÈfÿ£¢n³Š¸ªÉžúMáðÖ]Š!EÖ|€õÿIÔn\' @�ÎZ�QcÔâVÔŽ„Ë׸$8€Å‹Ød<ÚõaÅ‚±ÌïáÍåUS鶸Љ�*´Úg¯^9>šˆäÂ8Úk3=Á·°·Ã69šˆ¸§-É&qþ—ÅL¿äÃÀ•°.KnmÖqzÝzv¹¶`h=Û,iaÇ—/cg¹žŒ®a“CʨçðŒ!øÔéCí/öcÛg4K:¦¿Ç*áÓaó[DòMïñ©Ý�€î«¸Z¯?3:¤%1_U³åôÆ l IB–Sxpa/s¶ßFCTx¸˜q‘+óÈ·:Í}T€š2½&plUÞö±B«±Æ¿EMªÈ!œº–Þ³ÉÄG<"Fe‰½�j$,]*0~Å"Ött~Üp% •K5z5uA H¶tkîEØÁÿ8oÔIJ6•ù¨G …µ)ݘ¡mÜ9pœ zÀʆß.âÓé=zÚ£E�}ÉúŒîìË•ßp:ý‰†ÊŽ¢zÎÞóᛯZSÏÛ{[{<œŒV¯Ed„0?"uø˜Bµ{±{í¦Ô7µíô)mÇÆî¿ÃñhÑž.¾…Q©­ lבw¼ŸÞV²Ó%Ö–bþ•ÇÀý-ÓlÒ¿†=ðw1Gý»3§»ÑoSq¦¿Åúß.ãк WvÀBRãØŠQ\¸¸ýgô C"¾7„ðˆsØ·íÆˆ:ž8YYáØ”o&äÓ¶èdA]‚m^¥Öb©‘@R¡µÐbi¡ÅÒâY¶|+¼pϳ~O5šWÃ]eM£fÐø›}1Ù?r}r\ÉŠL\èL]òQ¥jЪ¸’îåC$¡÷tÜݾ‰Í6�™>ë+V *OĆt_r™Dòš«H¸y»aõà¡:=Á‡O®�aïá¤è#¹§Á×ÇùqßïP‹Ï>ªJ©"…q hB×*‚¯¤ínê÷rANºÌ™Ç˜D 7ÍS.ø”ñÞ\öÄÌóïŸc¹Tj,,Ô�}§‹dßÂéŒ:æÉ§êâfÎqH47Í7Ìä÷ç6oÉëÜ/õZ±9[ä§.¡ùªyæá å çœ�lèôíb:ÿ®xæEÓè§½ú 4�óñ|•½+|ñµO §¦†(.�I¿u tš8’�¥Ò\üÊ"Çœ`ɦHê iôÄY6‰ç~cÔ_¥øúÇŠØK�í]Ô¼Ñk »Û>âÚ‰ýÌ\ò-}ôcXÕÅK’9µbý÷¹2nÅçtò+Llða&~9�® >gË ¬)L“ÁCùlâB>ïòÃ-4Ø•ªÃ�&eØö›So±= ÜÛüþÛU€��ÞU›0JÇŒ3äÈ‹¬œ¿…M§Ây˜*IGtŠ�fºôÞZÂ¥Qúý>‹o 䇊å¨[µ-šÖ ¶g¡L�œÚÃ�ÇsH ·¢ðàwô�>ê«‹{ã—ÑÚU+æ‚tÿ>az¨@8WBR85ÿS<çg.‰diG¨ŽÔó$jµ �êÕx#ë{pÈ ?¦ëÐÈ,k'üJšPš]ÛÑGz¼¼œw˜*|=žžR‰èʾ-‹Äü«Ž Ç&±¹¿?ZYGô�`¶®ZKÇþ¬˜×™šÖ’é8ÓÝáÊm(QÒÃh�SãëëŽt÷7“¡ra�ñ}J—n�ow#]E+Ô¦³‘Iæló ¯±Gÿf{\ _Õ/‚ØU¯MciëÄЦ•]šïMŒ+†,2²ž¤ |j4gáÈ”}=V|Ÿz’u2úòmù¾G¥Ôsµ<Þfj÷Ó4XóG>ô£¾‘´P®f„ÚËÝqnÝ� üX,MÞ®Åуg¹mÏíxgªÓBÚþµ§;>¾TQ¨�¢ôè@¸ß%G]´>-—¹`vã½Ù03 ´Ïa¼îå2"é&?~1…Q5™¶´+­=Í|âžN07-Pˆøý9Ì[žqî'>gË�üÔõšRà½à£Â»¸;q�¸Ÿ(ƒÅóM¥%+{œ-ˆx”‚eónl©žúûèQÄZÚSÔÚHb(k'Mcü…⌞÷9½üMínx–²È<<¸ŸÝúŠ|_7Ë{Iט=í†~M#[‰ìSƒA¢�£+~Ž®ø•ö£’Å=jÌÝÄÞƒi¥>ÏÊu×)Ów�ýmQ¥ê0ªË_T�»‡CÐÌ$ûOŸIÿø¢ …p°QqnáçPÔ÷’¨ªpjüû•æÑ_Ëè¹>þ.­Ò'z†Û,;‹%šö,_>–ÚÎZ¤¤èÛt^¦»HöåøbÑÇŸGÎràð¯ô^¶‘ÖãÇ1£‘ƒÑn›Ì[æô eö‰Jý”'ñé2’¤¡þsX÷¦ƒ‰˜‘°··6ñ„LD&DâG°…ɱíÈÈrV3 è ¹;`F¨-§ˆÅü«ŽÚÊžbî©»Çðp§l =g;,eÁþ6Ôhe“·y�3 cHÌ÷2Ye²`î6¯ðê ÇðÇïljˆOfÔÛï3&õ—$'$¢Úq”»-›à˜W2Éø¡•4Ø8:à\XY­yf$œíUØ89`“10HxzÅ"æ’s™«eAíê�¯v7!Áç»éK» åÑýº“C—JsGíF)wé‹6YÇû\#d««öi¹`®så¼c:fÀÌã}~”+™¿.cò­ª,_Ñ“¶ÏCSnrÓ‚ˆßµfž·<ëÜO¾.8gË ù©ëÕ'Wýåk÷õ(ÝMVOžÁÄ¿¢ŒÂJOðÕPRŠâme¾.DŽ‹àrp(·³n‡ÖøR5N� δµì¿ÁH~TH_ØN aÙ¨IL¼[“¥?£wÖFkö²$òÏÁs¤”ƒÚYö^¦\ø›ÿ]¹ÇæñÃ(Û¼/ešHÓWHº½ƒ÷Ú~ÆÄSzH>Ãí{Ñá§»™Þk¶Ôj@—B’�Ô¯Áè@¯Ï¼sB¯7 ˆŒ÷ªoþó;óö„‚•-N6ZTºPv¸‹k¥@J¾ YŽÚÆ�â^îT{ï#ÆU¸É76s6ýŒÄë¿"S­}«ÔDH¹q‹+Y·.’ˆMÒàæ_‰w{ö`îü©¬ê ³yÃ1îŸ;v—[Ud 4ôrQçL¿!<œ[zc™ûàꂇÐxàï —/ÜÌôÊ_ÊÄ'<­C‰•¼· ¡ø­Ã4²m_`ºí¨ñp†�Û÷3ž0¢çb6gçM…Â+€yŒÿQÑjÔöMeOÐTöMcÏ—u°>y€­w;:Çq%“ŒÅ=�•s¡r¢R #Ï]æšÑ8z;ô.)Eœp·D—ò�›DüžËyË3ù]`î'”s‹Ø“Ÿº^S”w9¡vÂ%å2‹§/bþ‘PÂFpfÏZFüt‡À·šP5Ç}J2)IIÄ%$—�D¢NFÖ§Ÿösr–ù^â¡•4ëú_ì�Ïœ‹«ŠÐ¾Kmؾš »oÁ™�«øz§šïÖÆM�Ä‘E3™\–oƵ§‚&ž¨˜8¢b∎KN¼…Ê’ ›õaœ¼œŒ�qì²ô×ÚÀwØöÛ,þ ú޽Aß±7h k»ûbáÖ€¹ËG3¤Œ,ühßБSAKøáï[ÜŽxHð‰=Œ]y†ÂÕ«R« õ£M}[NlXÏÆkqè0z”™®àX¯5´*T·�3sÊRfý{—BØ:{!‹î2¸‹?/|S‚Ê…Î#{Ò |#C_$@눧£Ìµ ׉–!ùþif¬>�Ê "Ŧ-b¥pè‡TûtG#S�‘Iy‰ñ8y»coTçú{‡Y´éÑ™ÄÐC,ØqïzU)“ž¯Ë2ú°X´%„˜4™ùÛïR¼~5ԀʃN�Ê‘´ë'&ýu—xƒž¨Gøú“Ïè0÷ñù\eBñ#T‡�ɶ} µOšÔ)Êí�›Xs%–äćùiÛ=ÝþgjËB1ÿê£Oˆ!ü^áwï|þ8 ¾]ÏŸÚ²´­‘Ígs³¢.F§Ž~<Üþ ÎÄ COä¹íLÙü�Êë¨F,†D|¯.F§7ýyøûOÌú÷>q)ÉÜ»°� “ƒøå¶{• ®\´y ;¬‚Ùw4œ{‘‘Ü ¾Êé°$eç¥CæöÞý²xƒwšze|9¥˜» %7 ¥í~ýãΓ‹µOWž#j*¿ÙŠªa[6÷0çïGqóøVƬ½E©v Só'¡\-T.”ò’9ö÷9œ«⪲¥VWŽí?C´§‡Ñ+J¦Ìè÷Ì…™û´œÉMErA�ñÞˆìó{b&—ãý3å1f+W::bÅð(:ñùœëÜT‹¥Fæá½Ä$§�”¬K;S.·2Ùa&¿çrÞòlù«é¹ŸPÎ-bO~êòEîæá/¹z=ê‡Uû^¯Ý6’ ->Åôy«™7~4SbÀÞ£$ÍÞÉèw½Éqþdavß/˜vÙ8ÝZL¥†‹A²¦óôEÌ®+2“(R·AÃørÑ$jÝIÂÚÃ�ŽŸ�dlÝ´×tWùm÷m’î…2°ÓÁLW«ì²zÛšhÊ’›õ ®E‹f|øbfôíÇøB®Ô~«+×»À±º\ì~hË’HÌ¿êx°}Õ·ƒ$©°°q tùê|;÷ºzˆV€Šoeeò*&�Ƭ(Þ4éþ³;{¤Æ…V,†Lû^…o§a郘÷5AŽù›÷»�¥û†4Qº”W™[ë&PoÆe¼{NbßÀ�4‘q%«ŒJ�•½+åk5bÄ ¶ÔuVžÑ=+&sÁ\æ+èÎ3¦Ódþë4õqÞ“�LȺñÔYáɪÍ}žoá^¯óýÀqÌvìËééõ±7þ›YrS3Úƒ@̘k¼ÏÇrɱ7øyÑZí¹Dp”k—bÔmÙ‘1ïWÔ%¾~"Õ§�Ë’ÿ§£¡ê�ØÜÍUlg�M]~ÜSƒîãÞ�Ƶ¼Êä†gõ»H¬Š`®¹–yϹóS—&|!,ó�«êù´g£çeG�EŽú�ÑŸ¬àjã�øe¬E"Ïðý¸´¼8{•"û|YææÆÙôú1–7?ÅœªÄ_ÚË—çÐGãÂî~%r¸6ó}ì]B÷Ùwh3j sªØñèäV†OúŽÏ즲¨™=™s�/YÆÆ‡–HÆQ©*Æ�—Óß`´¶¬¿GÐÈI¬/_™Rj€dþ]8…·;òÉ—YéoAØÁõ ûn*ã¾ã»šVHB2"e7‡ºB7þ˜Ù¯ŒžYB­µHkØf*{¾£Â¹ÕÇü>Э¬'æÎ%VÏZ΀á2Ww¥Š¹^$²�,¡Qå0™‘É–çíSsµS1]¦ãYÇñ%ßÑoO ¦Ï˜Ã[¾–ÄÿÍÈáóèipâÏÁ~f´§ ò¸ýhôIÜ>ÆÓÖÐ;Ö�&×&Ûu›gг— Ý•«œQ¶ù¼ZÂømûuJ•÷!dÏŽ÷-A�Lc…‰qE“EÆ�BÄ­³,ŸD�á)lYÚ‰rÊcºÈ”ïfó^ühö}ZV`ÑA¢hë¡üS'Ðo¡ë'©7y4—Nm–v޹xDBk¡•u¶Ã¿ˆŒ)Ìåw‘X³ÇÁ¾›i;�nòÓw©Û²'Åêô L§ Œü=„D㛢8°r-;|@‰ú=(Õj8]g"8c²–Âö¯zSzì¶ÎýŽÖ=>¥jë�4û;ÿÅfÝøÃÁ¥Óhت'Þ ûÓ|ÜNÅÉÈ1ü»n>:õ¥DýžøwEß%ÿª32'ìw:4É÷—°wáêµèŽg­÷(9æp†Ý"2¹!GŸŠÔaºèîð©Ñ�Ûâ2o‰m§‰·X3q •õ dËa¼3ó·tOQ”“.‘x–c9ñ¶ÕêÓÑ× 5jìKÖå�*…½|‹‡¯É~ÞôöãáîAźmè_¯ñ¡aÜI+¿Pœb8òsZL×ë‰ûQ|°8sL Å�ˆïå8Nn\ÂÛ�?¢DÝn”ló=æ&8)—ºL¶yû¿ë�Ï€„>ü“nuÓ¶{×Ëü¬¢ÂK…îÊ6Ü(Á{#ZS/ê0¿ž|rUÎä¸b,ãæF¹êM™<¸öÁGØyS‰�¼#� æ2_É@e‡¯·5Ñw¤æO™H&ìN…‹yàžž­«â94ƒ¦mzâÝà#}±…c1FŠô{¢˜Òe–>MÝÆ¿7„·çœBÛæc&5(üä¤ÖŒ¹©Yì‰s�÷ùX.ÝÕý,;nOŸÑЭ²^®®T¨×�±=?v†«Onæ*j+{¼Ü](€70 IDAT(æî‚—³I…�SêÏÅÜ](j�–ñ ä¦ù†¹ü.«"˜k®eijΣòM—PŸ ⯗ åëQ9!Çñï±[xVpæôÂïiýÎÇT{÷+®8EØÓ÷ô=F²¡ÉÇcXÛ7€Œކ‡\IÄÚÍ…"¢5¯»É‰ËP±¢ïãû ¥|_¤+Áœ1¶#á?L?AõOÞ¥��‰¢=<Âä%·h4 #Õ3–Åõè `¡Õ¶·¢v$\¾Æ%½ ŒPÙ DÇÄ£Š8θ!ŸQµÕGTê2ŽÁ+ÏžÞé?§²¿$ �T¨T çٌ̪ìÈðe‹¹²íÆûž$èp.·:ˆÄ³dOý&�pxë.Å�"ë‰ >Àúÿ$j7.�ÓË>â䙨›GXw$ÿ•)•ÖošŽ3×ÖÏ ç²43�‹û—óÏ·uHØ8“÷WÞL‹i‘ñ½LȦÙt]J•¡ã8ºk ¦6§Ðsé6çlÚYRæjóꎘÙ/«PÈ®>+öqóï nîO?OåÌË‹Žÿv"4°­KW¦}õ$¶ï³Ó%Ï>1¿E$ßôþŸÚÝ辊«õú3£ƒë ßA–?¸¿e�Múà×°þï.æ¨wæt7Úâm*Îô·XÿÛeZwáãÊXHj[1ªƒ ·àŒ„bHÄ÷†~Ùpû¶ÝQÇ'++Ü›òÍÄ�|ZÃ�,¨K°Í«ÔZ,5H*´Z,-´XZ<Ë–o…NâyÖFój¸«¬iÔ¬º³/&ûG®OŽ+Y‘‰ ý�©Kþ!ªT ZWÒ½<#� Šç+Y‘póvÃêÁ=Buz‚Ÿ \ÃÞÃ7HÑGrOƒ¯�óã¾ß¡Ÿ}T•RE ãЄ®U4_IÛÝ"Ôï傜t™3�1‰ ­Ö„´¹rSsÙ#4x^ãýs,—J�……ú±ït‘ì[8�QÇ<ùt@]ÜÌ9‰æ¦ù†™üž§X!os­ôkŸy•ŸºD|!$ór¡¼áœ#z’u2úòmù¾G¥Ô³<Þfj÷Ó4XóG>ô£�È‹¢†(.�I¿u tš8’�¥òVí*{W*øâkŸ„Æ)@â¹ßõW)¾þ±"öDçp9æK6ERoH£´³lÒ)L“ÁCùlâB>ïòÃ-4Ø•ªÃ�&eØö›šÔÝm"2e—lèôíb:Ëïüˆ`ý´—C”Æø%s•=0poówøoWRtxWmÂü)3Î�#/²rþ6� ça ¨$Ñ)šéÒ{k —Fè÷û,¼5�*–£nÕ ´hZƒÚž…2urjw¼�Þu+êpG飾º¸7~a§¢X1¤û÷ ÓC¹’©ùŸâ9?sI$K;Bu¤ž— ©P«UxT¯Æ…²)ºˆŒ">5]‡FfY;áWÒ„ÒìbUIè=ðòr~Üaª\ðõxzJ%¢+ûxNæÔŠiôßçʸŸÓɯ0±Á‡™øå<º.øœ-ƒ°6QŒ—ŽM>bs´²Žè;Ál]µ–Žý#X1¯35­%Óq¦»Ã•ÛP¢¤‡Ñ §Æ××éîn&CåÂ1$âû”0.Ýß.îFº$ŠV¨Mg#“ÌÙæ^-b�þÍö¸@¾ª_ °«^›ÆÒÖˆ¡M+»4ß›W Ydd=I)øÔhΑ(ûz¬ø>'Lç‚õ�¤sÊWž†ÚËÝqnÝ� üX,MÞ®Åуg¹mÏíxgªÓBÚþµ§;>¾TQ¨�¢ôè@¸ß%G]´>ÍL¹©Ù™?<‡ñþ¹—ˈ¤›üøÅfDÕdÚÒ®´ö4ó‰{:ÁÜ´@!â÷\ƪÏ0×jla¦yT~êzM)pá^ �lp¶Waãä€MF#’ðô*ŠEÌ#$ƒÉÓ½CY;iã/gô¼Ïé埻’•=Ζ D™Qo¿Ï˜Ô_’œ�ˆjÇQî¶l‚`r\É$ã‡VÒ`ãè€saeµæ™È…ú÷lP»zà«ÝMHð9ÂnúÒnByt¿îäÐ¥ÒÜQ»QÊ]Eú¢MÖñ>WÅÈÃÙê*€}ÚóËMóbŒÀü3�÷ùQ® dnüºŒÉ·ª²|EOØ>M¹ÉM ‚óFáXáçZÈןã<*?u½ú䪿|í¾¥r¢R #Ï]æñn‡Þ%¥ˆî¦éH aÙ¨IL¼[“¥?£w IŽ‹àrp(·³n‡ÖøR5N� δµì¿ÁH~TÐBÊ…¿ùß•{l?Œ²ÍûR¦ù‡4]p…¤Û;x¯ígLÎÌ)K™õï]<aëì…,ºÈà.þXË”]í„KÊeO_Äü#¡„?ŒàÌžµŒøé�o5I­[s—ýE r¡óÈž4ßÈ�ʼnÐ:âé(síÂu¢eH¾š«Ï£²‚ÈG±i‡ó¥pè‡TûtG#S�‘Iy‰ñ8y»coä;ý½Ã,Út‹hƒLbè!츋w½ªd]–чýâ-!ĤÉÌß~—âõ« TtêTޤ]?1鯻ÄôDÝ8Âן|F‡¹çˆÏç*ò©P>&Ûö%«ž4©S”Û;7±æJ,ɉ9òÓ&¶?zºýÏÒ–ÑúѦ¾-'6¬gãµ8tˆ =ÊÌ Wp¬Wƒ¯þ÷¾Ð'Ä~/‚ð»÷ >œß®çOmYÚÖÈæ³¹YQ£SG?nÿ…gbС'òÜv¦l~HåŽõ T#C"¾W£Ó›þ<üý'fý{Ÿ¸”dî]ØÇ„ÉAür[ƒ½JPW.Ú¼…� V Áì;νÈHn_åtX’²ŽóÒ!s{ï~Y¼Á;M½2¾œRÌÝ…’�ÐÒö ¿þqçÉÅÚ§�+ Ï�\P¤Ï• ¥¼dŽý}çª�¸ªl©UÅ•cûÏíéaôŠ’)3ú=saæ>-gdR’’ˆKH$.!‰D�Œ¬O!>íçd˜-75"û¼AÄ�˜ÉåxÿLyŒÙÊ•ŽŽ˜G1<ŠN|~ç:7Õb©‘yxï1É)$%ëÒΔ˭Lv˜ÉïB±ú˜gË_Mϵr;�ÊÖžüÔ%ä‹ÜÄóËA®^�úaÕ¾×n·�Ú»%‹§éøjÎj:üï!z;O굊>%žhX™Ð]å·Ý·IºÊÀN3ýIeß�ÕÛÐDh&Q¤n‚†ñå¢IÔº“„µ‡?ÉØºi¯ h­(êbet�ŒÎVƒ¤.Œ“‹öÆ^Ö?$ü¸-ò”CÎ$ŠuìÏìð%|óåpfÆ[àY¦£gt§{Æ—Id„ÊnC‹ÏG1}Þjæ�Í”°÷(I³÷G2ú]ï´·ÎÌ\ö„Ê¥ߎ8Aó¯æ3¡ò7L­]†�G´àÜôTÿÓwŸ >ŒqΓé7,=˪w<©Õo(ŸÏZ𮛸¯Gcí º°l` ÆÇxXTjH“° Ú´»Bhœ%¥ôd~Ÿ’oî¥è ØÔkIó�Õ´nw…ÐøB4îÂÞ%2êÙ«Ý`Ö$1qÎÊ�MFëèA­¦} ê[«'Jôœò©XšÌQ…bUͽ>f|øbfôíÇøB®Ô~«+×»À±º\ì~ˆgɆæŸ�fú¢5Ì<ˆáÑz4v®Tkü>kTK}?ú•ÇÀƒí³¨¾$I……�¥ËWçÛ¹ïÐÕC´T”x{(+“W1iì0fEé°pð¦I÷ϘÝÙ#5.´b1dÚ÷*|; #HÄä©£˜ž€ÚÁ‹ú톲öý çB—p›¯Ú–ÑMç1môpVè-(RÔ“V†ó�‡å˱…\!Ã6m¿‚M�vÔËÚÑZ–¡c{Öí<Èå÷ê—+•dNn]Ë$ý¼Ý°…žËÀ“ËÜTãEËÖ~l\9ÿe2²Ú‹¡Ë¦2*@�;™ì0—ß…æZ˜k®e®y””�ºD|Q;<ñür ¹Ù¹È+~YMãš>&…_ÇE…‚K LìOߨ^œš^ûmŽ‚‚‚‚‚‚‚‚‚‚‚‚‚Y)û^ ’/2wüŽå´—VS’¾_½EÝ\|áBAAAAAAAAAAAáUEY´QPPÈ,øxrÀ‹¶BAAAAAAAAAAAá¥!W¯G)((((((((((((((((äÊ×£ ¯GÍ;núäìGû×P¤~·çj�‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚‚²ÓFAAAAAAAAAAAAAAA¡@¢,Ú((((((((((((¼$szREFNÚ…îE›’ ú“ßú?’_´)Y�I<õ-S;vbÇ¥„ÌŠÛÄÒV~|ÒÄ�Oš”cÁÖû4ëŸ'º«‹˜Ý±9ÿ;úèµ*wAAùzTN.³s@Gv\}²ËSùâÓECñÌé­29’kë§°õ·}„5¹¡“çGŸéB Þnc軾O¬îæ‡9“ŸºŒ0á a…üCi?O¡¶9†ÐmSÙô¿]ܺ›€¶hyÊ¿=ŠöíÊQøÉ¡Gá)È1§8øã÷êñ…�¿ò ¥ý˜2¨`µ9œ›÷¢n¾˜ö Ñõ‡ÓþônmÚÆÃ½p|á‰mGÌõ‹q¸µû€Jþž¨ëÀwxk„Ì¡k®èeÀ £�7Ì•÷O‹¹*+gÝ<³™$&svr-þg9–ÎN°ëÀ¢#b)T¾ï|ö%ÒwÈÑÜÚ6�­ëws3<ɾ¥š¤C¯V¸X Öá¿cøvü5ý¸†�—Êåû?³¨ÏìFí kKÎL®ÉZç¼[ôoö¿EtdÖßçíOzác-)\žÙ�…[R_±YÜbCê�4oÐ~ÙO4JßÊ/à ’.qxöXvî¿D‚…>MSF¹›Q' Ø $\äÈ¢Éìýû±2…\+R±ûWtl^ú±Ïê9+rÔA6�Êÿoøi3ìU"e¬Cá*8Ê¡m—qm;•…rwé゘²Ùt¬n/gÁไ>íÝ6µ?Íf­¦±Çq�×Ló1c,+R»M6üÌÕ÷&âo*Q0¹Z´yÝ¿%?ÚŶ•—2_S�Y²§ÌGË)“é÷¸;Ë¢ž¹_HHü�]sþÄwàÏø… ÌbX4×O^Â!°¡Ë±fÿybÔ®ø4ìO»®F�º©ûˆØ,¤K‡Áj­Ö¨±[`ïâHÊñsÜÑ·§„ÚL÷‘ÉÏ¥IM:¬:Á[5�Ìù‹O‘1WŠ”K( $ÄÆ EîcÓÈ%\ ~€ÁÖ—ÒÍ?¦mçÚØ�y9Å�ù¨KÄ"2 ù‡Ò~LPÀÚOÊEnC±¶åŒ’ K¼‘v�æv28* ]Ψ=qõTsø¯ ÎÕF¹b6HHX•ïBÓòi2’€ŒáEà%Ç\yϳä|"1€�ˆ-Ÿðã/…i9îw–)BÒõÍüúÕ0–ªÖòI�²¨ɹ®V×9¿h4çlòÖì)³—IJ)Œ�*¿Me×MœØý-üª¥µÛníÚÌ×¶tªjc6]ù�J­"î樂ì7“A?–Bûh?Êú Ñ;"ÿ”ÅKã©5r =+¸ »¹•M?cq’#×ÄR¨»SÓ£3‡·Ÿ§îé;¨ôÜß³�kNíXÝHF­V“thç?YÎà�fŒ§ê q]¶ž Wtø—Söä¯ù‹²¹!…Ð_çrÎ¥;MkÉÃS‚Â~ËÎ+ehôn“OH³^{3èkΖM›ªvOê6Ü%ò~ Q,â„ug:·š>¬CÜæ!,Yq‚ÑûˆØ,¢KS–€*EÝ2�·�å$b/­ç�Ý×ÐÇ>$A6ã}Ddò5jS…¹Êž'žâS9�ä”Bhb“(Òr,ü°’]ü¹ûS¯8ù ñóòS—ˆ/„dò¥ýäHk?rB$qÉ6XÛY�üç`>kRŽwE¡¶sÀ2%’Øxe ˆI$wj|2•ZVÔ§&_öéÊŠ9‹8v&ì±?Ed0³õ>oV†áÍÊ0¼Yylº£™+ò˜÷ˆÜ';Dük¸ÊñmÇqj?‚:eœP£ÆÊ·mÞ äÞî-�ŸÈKNØI!ôAoŽì�Ÿ—…m�)âh�Úh+R½Y)¢þú�«‰i×$áß}a¸7­u¡­>šá?þF§Úy}eÝ@̶¾|ѲŸeü«ÈŒ Ë�×+%À£ÍZ”Â�ŠÔ¥\ –ׯ¦Ö£á*G7¦p‹´¬Y+[Š”éÂ[c¾£y•"�w¬™*—ÆŸš«ñh÷:®¤×¡îGw]Æ£u¼µ�표šQ»aêî ɶ*5—âÑ‘}„¥J&©-ÐjT ©Q[X¢±°D£5zõFĆkœ;tƒ"MúRÝÇIm�GË~T-–‡)žI›Õxt]ËW‹&Sµ˜-j�nMZâ#_&äº.Ãf¡zNCÖÝäèwƒØoñ1Žìˆsú€`š¬Cado^桦Åò˜ ·rŽUµ v®ž8º=埫 …4 ”/™k>–•Gî–÷¹sC9�8?Q–Ç‘cÿbÿïw)ݯ“‰³lžvqWW c寱T»˜Æ%rw qÊÅ…l8Xž7g×ÃJ’I|BB‡^gÀPö}ºti€µ¸ â�Îøî¿r­w%ü5"÷±YD— e>šAËi£ù_Ÿj¬Ój)\¢MTåô6 jÉœ÷‘)h˜«ì¹$;ŸJöT÷UŒe½ÇÒ=ò4S7ü�àžo ÍeüdG~êRxEQÚOAl?*Ûbó ÄÙ.=­(��o�DíÞœŽß7¥Õ½óÿwˆËÿî`óˆùìn6��Ûc/ ȠºÁ8úw¯˜öDNOÈÚ¾ürëE–î%â™ò‘ûd�Iÿêor÷v!K[2|iæk%KG"õ¤2.©Q©Õ8Ti†÷SWŠÔ¸5ztIÂIDATë„ÏOó8úïHüëÛ’xd§c«ÒªEêë˜M—ÑuVî¸ùš¬†PaÝ`{V2zãGBcï™éé³ÊÙ#m—FêßÕZ $èRvR®q'\Þ,at� ÛÀ6TËd¬©r©(Ò¸;V�䟃ŸàßÄÝ™ �¬M«æ>™íq/Ž“êñuv.E!"œhb¯.‰ø‚;<|Ž�u«EB’’IH1hH[>­gCæõç¿>t\Þwãú�C³a >úØxc�×gy¹°9ÇX5æš�e¹­Ê[{¸…Œrv]~¡,Ú!d#çôuèR+—Á™t•ÃS°éJYÚ~¿€Ú¥lryýYþ˜½ ¯?ão+ÁÓÖ4UE°±ÓPȱ(…2n®¢ˆ§êØb“½À}Dlѥɮ*M&î¢aüCdk¬­ÕÜ^Ö\ª¤vR’™îƒ˜L�Â\u˜r‡j}Š£‰¿Ot¢ †sâñ“kòS—ÂK�Ò~^ ®ÌH…�°±ˆ%6* MãÏ’¶š”¸'‚$K'lóõ@±—–EËQ¶e9ʶìK“}Ÿ2mÊlulB«RjÓ2%Ò$l=qóõËøzTœÝSÎ$Px3ä=&ïc’üë#�¤Åï“}ôoëbâž* Ûe¿ÃNrmC�*³øu÷^âêÖáüο Æ$*9§wŒæÓeNT6îõ.ñìŸÊ"}¢‰rYÕ§n‹¢ÌÛ¶•ÈFo¶}'r½)TxÊÁEÆ¿‘õzr· -à �œÚÍg*–Y/çòL›LZ3Èd³!˜?'~Â_š¾|0o%�,‘’~gEÇ‘OÞD¤žõW¹�Ü™7Šmä�%;)7ºöFì‹Ç¡¹�ŒþÏãõf°YèLo1çšk>–%/(_�"žàÃÿ¢/;šRÖ¹¸,é2�ïÃθ·è3ûürøl£ÎÝ»qXº”ÀÁ汜þò&އÿm3N§Ë&Ç¢K>ËÂ.û©=á7Ú•sÃ;À•¸S'¸¯¯…›@Ï£Û!èí±·ý‘ûhLÛ,™Öz"Žq*¾ ”Â@w‘³‡ob_±Fê!W˜ë>"2 ³Õác²‹À´OuùgÖÔü’¶uÒ%õÜ¿v½}œ KâñcÊžüÔ¥ðj¢´Ÿ‚Ó~´�÷ƒ?Ξ!¥q­´C(¸yú ”€W®¾­þz¢¿´Š5K¯Rnäx*g<ÞVa]¼vÒ âd!…gÀ,y�À}²AÈ¿j_ܽàÀ¥ ¤´uÉøT¯þQ±…ܰ/”UWÓEɉò-›°åÛ­œ¹ˉ“¶TüºÑãswÌ©+�1NkŠãê Ço\Ç€CÚz†�¨?s,¤UÛÕ4Z0€œË¥Á«mW¼7ýÂÑ… ý×�ªßÕ~â58ùÎ-" ¤íÜ0.eŸ|p�݇ˆ/$Wì�d®†ÝÆ@ÑÔr鯢ƒ’B5#nsâ9n\3à;¬Wê‚  ¿u‰»zpͨš\Ô³¶Í>û’jQÅX0dë¶•¥oÛ´ÝJ¹�C¡Å¸œPae_b#‰Õ“·m ¹n;ÙX"r¦�æš�eA~Hl4XÙçíPq…¼ñ/йÓ!e\IEND®B`‚someipy-2.1.2/docs/images/wireshark_paket.png000066400000000000000000002510701513043235100212710ustar00rootroot00000000000000‰PNG  IHDR%ûû%jsBIT|dˆtEXtSoftwaregnome-screenshotï¿> IDATxœìÝwxUÀáßlI#¤CB)ô^BïÒ¤©t¬ˆ‚�Ï." ‚E,(6DQš EEšôÞK(�Ð é[æû# Él²!Îû<×G’Ù¹eΜ»{wf¢*B!„È—}ûöÙ´ý™3g(W®Ü�?~œŽ;Ú»YB!„÷]Q7@!„¸—™Íf›ŠÅb¹íß÷5Å�2Õ›óPmôEÝ–â@çE…Æ­¨âŒRÔmɯûõ˜*øUkFëZeî¯~Ý‹äXa?÷À¼#‹BäÁ!¨9O Dïú¾rÂ<@ä¸ ­L&“MÅl6ßöïBat£Lh(¾ÎEýĿʵ©àš÷›!-m.¢~é¼êÓwÈ Ú… ´ Š"jê™Ë6ÅžöczoåRGÊT©CµÀ’wï�{±9O �¦óâ6±Ðãר/ƒ÷£‰¿á.Õiù;¦ÚÝ[yãpÌ;ö?#ÞåjS«¢?žN ©qÑÙ½›ã—ÓóuŸˆÞ5˜:Í"(u~+vÇb½YFϲT­Zž7œõ’¯^àľÝ¹”šY—Že*Q­bY|½Jà ˜Hºržû÷p4&íŽíÑ»—£QóZø¥`Õ߇H°Þa£|Ò6¢{£ ôwÈuª9Šÿmæ¼ÞÛD[œËµ SÍ4¶,ÜÄ;¶ñÎ w§J›¶TóÈš,DoYÂÆÓ¦B®¼¨)èôVc/cUuè€Ân{ÉùÜÑH1â^‹ZðpRH½z–£»÷äû\¾·§ã®àZ±5íkzgŸ˜­—Ù³b G­(Fjµ¨I€« Nz+iÉñÄž�äàá(âM…w´ –Ÿµlsoصk—MÛÇÄÄwãßçÎ�Ëö{�k*U­LˆŸ'.F•´Ä+\8¾—Ý‘W°åpêÜB¨U'€èOs1%?#j¯cd!1&šèÔ”<_£¥ÍïW~è(éçNúÉì�ÊiÞÓ²  ¦p9:š¤Ä{ù ­Ç´8åR-´Çª½M<ßMÏ‹Û<ÇB‡AM&6T½…{åžúüS­îµ¼qÈqÞQ0¸úV>”@_oÜœâÙ·b=‘©·Gba~FÎhIñÈ{ï½G—.]pssÃh4¢(÷ïj®B!„B!îŽì‹Š åÚö¡YÀ5NïØÂÔÙK¨T©Ò�ËK­V+V«U½7Öñ„B!„BQ|é²]ó óÄÛÝJõê Y¾õ!!!$$$�’’‚ÉdÂb±È‚„B!„B!ìÂPR�„ëë –s ìô}{>Jbb¢,@!„B!„¢Ðè\³\*1hÐ ô~¼III² !„B!„BˆB¥@5þþþ;vŒäää¢n“B!„B!7t¹mÛ6BCCå !„B!„BÜ:€àà`*T¨ B!„B!„¸ktÆ #==½¨Û"„B!„Bˆˆ mÛ¶EÝ!„B!„B<`t^^^EÝ!„B!„B<`tEÝ!„B!„B<` Š¢ÈC.…B!ÄÝ¥&sþðAŽ�¹ŠG�‡¨á£Øqß—Ù¿z-»£ îПæ:ûí»0ÜkíB;Ѳ !„B!nJ9Àœ·ž¦ÿó°<ÊRxõ˜0Üx¦Íü��±V;ïûÿ8‡ßWlæÄµ{཮�Ú«¦'páÔibÓìØ6!„(D†¢n€B!„( fö~5ˆÑ+¯  |Œ Sû®ÏaSK$s†¿Åog l¯�™Øä0»#H¶`Wd2‚KbÇkîMÖó¬üh ¿ì�áZš zÎ%}¯NãÝéPÇ—¢¾!ZM\Ë„�Ÿ²ÍNÿixTÓÕ®ìžË”i¿sØ¡£¿xŽªz[~_üX¯áïEKø{Û¢b’ÁŇàêÍy¬ÿãÔóÕðñÇtžÿ~þ–ykp!ÅßÊÍèñl?š:~ã…xÉ¢„B!Ä}IOhùPŒ«®`ºxŠÓÉ*á%Ô¸¿™0ü{¨áôÿ>�”Q å,Q—¬ ”$¼¼?Æ€¶<70…ÿâBhÓH$2¤KBšŠÎÁ+©ñ8¶ã<ÇwmåÐKñf«RE°“ I$sˆí{ãèTÆ kôIΚTC(B `>в6Õ¥f#ž®p‰�³få¾G²Å÷à ß�*Êö.™ÍÜUÛ‰¼b¡„_%w}’~­BpV,Äî˜Ï¬Ÿÿfß™xÌNnø6á©·ž¡žsfSÕXþžð +’Óqð §~—gx¶]9\€Töþü!³þ=MÌÕd,îøWlD·§úÑ"Ø ¬çïܶ1²‡ù,Ë?Á¬Ý×p®Ô›Q#{PÎ)?ãª#¼×GŒï€šp„…�å—ýWÙ±|Ñ-:qen.mP9þ×\~Y¶‰CçP]|©Ðé%ÞívK5wj¯1¯±Îd9ÎO¯<ÎO€¡Ê>ÿ ·=®ÃzžŸL`öQ zz“ Õ–ßç‡%�ö[N³ò³ïøëØ9b㯑”¦P·< º<Å“mÂ2âÁršUŸ}Çêcg¹x%�‹#žAUiܹ7=›‡à¢€Î¿o|Úo/œ•¤-ŸðòÄu$\º@Œ‚t9ÇdDÊ~[s «.ˆÎ£ÇóTh?¾ý‹Ï¬cášÇˆèZyÚ‡ö%ç”B!Ä}JW¦2•M¬ ºÀÊTt¿Ã7Á–³l_ýû£bIѹâæl%I.…³G3î§µ¹¢ÇËÛ™Ôè=,Ÿ1†Ï7^EÔ¸ùjʶœJ@_*˜ o/›ptÉR�j!5]G g…¤‹‡øç›�ø~wJæ/�è’c¸lrÄÝÇëU¢v-ç³É¿iÉ­mYÚ¯^cÏ“øaÏ5ô~­xåµÇó¹ ‘�Þ­Í"‚ÐêÕ+\Uóh+©�;š‘_.g×™x¬N®8¤Ç�¤¸fÿ¦ðŽíÍ{¬oPpó ÿR®w~ï+Cóî=èöü{Lyµ%%mý½Í4´ßz‰ÃÛöyþ2É8SÒÙJ¹}¬új³÷¦fìÆz‰CÛöy>ŽtCIÜ�Ì\>¹•%Ÿ¾Çø?Î�ñ=n^élüôÞ|m¯L]O‚Ñ�Fý»RÝ�[LBÒáýœ0«èüëÓ¬¢ Šsy×õC¯Z8yð(É÷ÀãI„¸×È•B!„÷+CU*8±"6…ÓÇN�fraÇžkèBkS-~{ng_rJ?…YÕáU© : §g[*¾t1�§+é0›­èãþbæÊ³˜ é÷ñ Ò»úC†}¹‹­«6q¥I<®\àbºŠâX�¾£ß¥��ÕbAÕ¦ÌýêJÓiäg<]á +Æ åë½WعõæÚ50 §ê³3˜ýŒ‰Äøk¤Äoâów¿gïùƒº¬îyç¶Ô�™¿H'jÙǬÙt‹G]¾ó ¼n_x±\ÚÆüŸ×p9¨ý­‰gWé«Ötâ£wóç†SX�w)¼=~¹´5̰ž¹KO�Š;Ç0¼]NÖ’ÍNè¸�k{ÕËëø5�±öºÞ8]0]FäõL ¯=x0ïÙœ�ßÛ6~ZÚï}£j_:¼;�§Ë_æÏ†ñÍÞËlÛrŒ5«ßüð¢øÒþ�é<]1…ÃsFóþÂH.\ž‡_¢Ž#@—£ŽqìdF0+ºDbÎ]&E ¤DŽ1©rþrfwOÜu:¼|èöžåZü5,€Áz™�s¦óõŸûˆIUo^ O!%íN_[g´íÆ‚‡õ »ÿ»JI?ó2ïð 'WýÈï뢱è/а:Ýsü@oáØìWè1;K�zoun޹·Õu˜ãi*Š[=:<„“è�qɺ@“C{ÍÆÚ‹¢’÷øii¿7·Ð{S¡¼7º½Ñ\»š�·n£¸R±}+*.‰dÿµD^´R'Xº²ôœ<ŸÇRã9»}.S¦¯æØ’™,jø)O–Í)&ípùŒÂfYèB!„¸_)xT¯AYÝ^Ž_ÚËâE Ä*þ´ˆ¡ÊåÚ¸ýµ†]«~åâY+ŠCEjUµñC™jÅ (!4~$‚2Y>‡*%+㣫ðÄØZ¼�?þÞÁ‘µs9²e=?ø�^Á·ïÒ`0ÜØ· $o›ÍôE{¹V¢"íŸkO%§“¬œµ”ƒé é!Š >Þ:.Ç&²eö,þ«4”&>·.8èð¯Õ€ð¿ÿ$&°>Uoû}¶¢è �FœJ–"°\ štèBÛj^¤l™–{[3Ç EAÉéMxNíÕ2Ö7³©¢ÞÕÛ 4ŒŸ–ößá¯Â ƯϱKcƇÕz˃>ôN”mÜ‘¦ ÿæ—“±D�IB­�SLŽ£“—z,ñWI°‚�ÞJÜå8Tô^Ès.…°?ƒ“œXB!„÷-�_Mj–ù…ãgO²c7èZP/X�“_j—\ÿûvqc•ZT/iÛCC`(Áúu6'`òiB·veqQÀ”p‰kÆRx)€%‘%ŒÖO¼Ië§ùuÔkürô[w^ Ç%²³þI*ÂZòx‡xZÜÙÿSæ}-7 ~‡9ãøýľø$œà÷»”í+w—jý™ð] ;ÔQ®ïÆw¸åY Vbòh«>0„ ý:Ž$ìàï ©ÚÒ#f’“-8_¿€#‡öjkG\Œ ¤Äu&5Ð,Ðë ù¯‚ä=~šbÅ&Ì–ŒUŒ˜m[9nÅ9€ÀÒzÔ+ÇÙŸPŠÊ!îPI>¹…Ýç­ ¸âééŒbI$þŽ1y‘ÇšT!D¿ƒcç¶°þXwBC¢Ø´ãEOx• ¸Èg'!ìN%„B!îgú"ê”fáÙóXÑãß°¡zÀ¹:�#ÜYûÏUTEOX½:xÛø¾PñkI÷2ñŸ‹lýz8Ïü䆋.•Ä$GZ¼û5/×1b‰ü�wG¬$ÅÇo1QVP\ðõsG¹ñ…œèð ÃSw”Ëû~äí7ÿÿDQ‰6¶Ó¹2½†öáÐ[?pðà\¾XZ‹1݃í|sÞmÕùµ k“eL^ËÆé/±ý[7œ¬I¤UÄÌ×\soo·¼ÇCyªWrfÃÎ6LÌ�9·ä½)ORAo×ÎÚLK¬ØÄËŸcže³›žÄ+×HGO™–í©ã¢·þ'ÆÎÜ%µç§F1°šãÍßYŽòe�Z·�ëÕ«W£v÷é6gngcª‰[˜Ð¥µ™ÌÞÂŒ“<ÆÙ^±êXéIF ô`٘ɬ�·^$'Üså~î»ä�‚Õs×òÆ]M±s7Ï óa~5…�Î�7{!Ë–.dÁÃiR’¢Ë¢.¦hÖ}ñ?ú´kDÝÚµiتƒ>\È‘$ãQ½ÆÁ_GólçfÔ«[—f�žâýyû¹V˜«mwã}TQôKŠ”bXŠÍíËø*¨*úÐ'˜ñY_B²,�(:¼�jFûï¸ f«ƒ¾8>›BÅ”ËÉ�+ùåËïYi/5K¿µnc/iìút0ÿ[âÇ ãf3½¢#ç×É{¼È$ÏŒh⊂‰½3^ⵕU5ãO:†;‘|ìƼüC,~ü>¼&F�}GÍR È|d/‡Ó®ï¯À»»?éüiе[ÆÿkóB=wÌŸ3•EæÎÌèWcÖöèÂ0{#OZ²üÌz–Þç�Í Õ« Ú‡Iìø|,^v[ãÄÆXÍcœí«Âz ã±_2íÇ^4z¹ŠÆsÏ’îE…Öw»ä„ëÇ7?ÇYòƽ‘7 �­ó×ÜÕó"õ8GN;Ðø¥giQÉ1ëÆ\>Ê.�}Ÿ¿ÄðÅ~¼ðþ·L®ìAÊñeLywCT–¼SǼw¨\^9Š—>Ž¢í¨/áMÂÎ5òEF»-`R{ å]¿Mq˜Ÿ\WDý¢*´+%-ZdÓöw\3q(I)ÿün–2eÿðiÚ5oI¿ëXóé :·lB»Wç”%s?êUvþ4‚':6§^D==Ü‹W?_G´É†5 Ó&=Ú�“7 ï2�7[—¸½ïZ¶ÉRRV §Nõº¼´8›¿1dõª³„÷{“g›„áã@õîïòzGË]K¼ ªÏáƒgqmØ™vá®è0àZ¾�ë»}ø(WU[×ÁâØòÕºµ¬O�ú­èùÖ/ìORQ�Ä ïÓºÞ“üpÆší5–‹óØ %ï¬IDÅÄ´¢î3?}eƒëT§ZõêT«Ý�ï¢,7_§åxYcÙüÍëôn×”z4hÙ�&­àdš�}²Æ±cvf]uëѨm/†ÍÈZW:ÿ¼Õˆ–£³fÆ0út„‡šµ¤Ë�YìˆWµÕ¡Æ0o`'ï%ý¶ß›9<ãQ"žú‰³V0ü”.µ3Ç¥zmúÌ:‰ù–×h:wìó×KÚNæ-8Nh÷^Ôq¾õ÷ Ggœ]\2‹WVL囘Gxs`õŒóÝÆ8LÚùãÖ×奾åÑÙÚV ±ª¢eœ5ƪ-qèXƒ�UäÔÂlµ5N%'ܽœ ^cßüÐ¥%õêÔ¡~«ÇxiÊÊìûÉcnRIçï7Òàõ_X9õeúöèÊÃ-ÛÐãõÙìI¼‡ZúžÎÚM©;t9IYö½vDSê¾²„{ç„Ô£,x¯5Œ ~‹Î<7é/ÎZl?ÉÅ+oÜ�9Nóøh©Ë~9!Ïó"ý_ÞnTƒj ß⟴D– �Èl{ujuý„ýf­ç»Æ¼a¯y9Ïýhg 9JM$ŧƒF¾Ç³Í+R¦”/a�ž OÓ’Äœ8ÁU«Æx¶^`åü1vy�áí«àçãK…‡‡2¼«#kæ® Újcÿ ‡Ø'×Ýå~I‘Rœ‹®°Và-Zdã„J¶o4]©0Â]N°öã÷˜~º!oÿ°’õëÿaÙ[MqPUPMüæ Æ®õ`À·³uË?|ÿ´;kF¿ÇœæŒýèt(gÖp¸òGü>¡5—¾“]ßà×ožÄ}݇ÉjâÚ±?XºU¡ÞC ð´ñ¸™·Ïaýøbùzþùqþ['òö—{1©*%ê÷æÑÀýüö[Ö15szé"v–z„ž�K€j Á[+X3¦Žn�ùô¿mlß¶�훿ã‰@]æk´¯¤§ðæ�þ'›¶meí¼7ß>ž‰‹Ïaµa Oÿò?^þêMG/`ö�,›Ü�ÔùÃyuÖáuéõ:âW}Ǫ2/3ë÷¥¬Z8’‡g0vöÌZêÁ�ÐbNž&õ¶ß§q22×ð0J+*†JƒY°yÛ7ÿÄsaº;î/ïsÇN1ŸYL‡×³)6ˆ¦MƒÑç±­zy5ŸÌ8BãWPÛézÿmˆÃä�|5n-µßx…Æ%É÷ù‘[¬¢jg-±jkêlÚœð¸�lØŸ.9¡Xæ Ñ ^çÅO�Qãß²bÝZ–Lë‰ÓŠ·yñãÍ$«*šæ&UÅ`Б²vë*¼Å÷ó±bñ‡D�ÊÛŸï"݆ÓRì“Lžõn(Å ŸþeÓ_?ñZè:~[Ÿš¯x”¼QòÆ]šã4��–ºì—òì�Å­6�u ãÂú9jÖc‹=r‚åëþ=‰_§§éî‚ÎP’ŠÝðHˆ’�x”¼Q,òÆ]›ã´��–ºì“4œ(Œ8õèPÑ2ërtÀÁ¨×þ^TKÞ°×¼lË~ò<¦yç¨ëç莉¨[·� _BÉ>gòã™±šw<«ÉWˆKsÆÓÝHêŠW©[½//ŽÇèîA‰ô+\¹fçç¥ä‡vÊuw½_R¤ãbp.䛕®/JtëÖ-ï�Õìÿo9ò½ê}�í~*cÍáüöM?tz z¾�ZSÕñ–×_ßMìNæMûŽ•»¢ˆ7ƒB:×Ò­´0«7ÇAq㤮1(.¸º(€½bÅb̧‰<�Î�i]¨5-ûþG/Ι¡F~žÎ‘õXäs¥„áá|o± IDATY¶µ‰+Í^�Ä‹ï�dtצ¼o4âZ¡ÛÖå¯úŒûNÕ4Ì›ñ¿_¦Ó©’+IÇV1õ�wôÉgÌV­Õ©  )Ï�÷—èñ € ç¸h�*z~úÐæ‹,øçewô"}ÇB–Ç4ä¥GÊ¢¿%>rMÇKÁ»ÍžXòo¶kÃWµРacZ¶kK½@í÷ð™£8uʆ‡`¸ÑeÃCà\ÑiP#³¿ºRe(}}½ £ÑÉ&,šŽ›‚{hžN•–FüŠ•˜Ý|ø{åN^ª™È‰hwÂB½Ði£¼Î»Æ¼•ø+ñP2Ïý¿3õÚz~úí þ×5Kœh‹Ã´}3÷O5ÞœÝ7T®å:¹È3V³o›k¹þ>q¨xáí‘q XUôwÚ&ß$'8'˜Nrü$÷ÍštøÔlO—,mÍsnº>>þÁó�š±ŸR¥KÃÅ ÄXàÆÁ·%sü™r‚þç.€`™›}× ·ý”¼Q<òÆ]›ãn‘[ÿµÖUàœZÞgæYÎw-yÃ^ó²Öýhg­9 #ÕžùŠù]b‰Ú±”™33Ô4“éý+à¨%ž³Œ­âH•Ê• v¿žW”|ä�r:®;庢ê—Å�!ÁZÔMÈ*K–CEÒƒÉSzg{Ð%NÞ”Ö©Ù¶wswË\m½…å?¾þ?žá“_fR¯”#JÚ †7~—ìYFA§»yæ+·­Š‚¢høÞJfö¼ÓCgì=ãÚ²MÁ(µ0})O&ÅqM-�‡«ŽÃŸ>¾µ3ÆÙ´�ùsR~ðÇt©ì�ð¨Ð�Wú/¦ÝÔl\›šžR”Ù½ƒ’ý8ßüÀµ1}ºyóì¯Ë9×®+‡®ÆÒvm|²l“íµw-ÇKñ¨Ï�VÒçÐV6nÚÌ–ÿ¾bÈ—3ióáwŒi[JãWr:Fquk,)ÜÚwíÇÖFYëN¢Ní fs:Œ˜ ï¬aç /NYCh–íÝxuäqî`Ϙ¿Ùg%×ש\]·˜µ–FŒjé�}[-qȾ÷U^ÿ‘Æn×ëÍç' -±zëöš>]ÜÎö8¼õ›û’œ`§œ ^?Nw ynÊx½.˘X¬æìã“gßïŸ*`E½Ãx('˜TÔë—bÞØ‡«ÅJÆ ’ä�Û¶/öyãîÍqÚëÕZWÁs‚–ó"÷6`Ûùž[ÞÐÜæ¼å½-ã¬5GY±Zu8úîHxÅšT7ž¡ý´Yl||­�4ij‹'ÞNI\¹šŠc‡W™Ý(cωËbIròħdÖúì)çØ²G®SЬ_B?:K!WЭ[7íWIÜro‰bô °l¡!YŠ_ÉŒ'pk))ÙsØJíîý¨ç〢ª˜Žá„Eãë¯]YÊ«D8LZ–Ÿ›.ŸãR²Å¶}Ù¹¨×Îyì8çòÓg7ÌæÛÇÁůFtéÇùwm¥êFPV§‚ՄŤb1›³×k¶€ÅlÃ}ÖÅzögM×ÿmæÜéhð-ƒß�gg¨üX/ªZÈâ-+X¸Î�.�×ÃåNû³Z v¼Ì)$¥ê)U¹)Ýž}�ñßüÊg�YY9ï®XµÆF0¡�*§Ž�Ìr߬‰ÓÇNB@ÁûkÅ-”0�KDýý[|šÑ¢Rš–ÞÊ¿ÿœä’Gán·ŸCù.v�yO7ˆ¿Bœ9·í’ØñïVÌ5šP¯Ä­Ç:ï84í_ÊÒÃgXñV'š7mJ³¦ÍéùÉÒÏÌá…‡º3u‡m÷Rç«6”œb5?qh½Â•8�’÷èÚµHN°GN R9}ìT–œ`!fó\fÍÝLŒEµin²FŸ&úÆycæ|T4”öÃ÷Ö8Ì1Æ@¯×ƒ) Óõ>Xã¹t)ŶØÐ2†øàë£}³ï¦“;™ŸùIòF±ÈwqŽ+”RМ`�¢å|×’7ìÕf;÷=וöcÛÔç©£²Í F£ÒÓH¿þº¼âÙP™•Unß—¥Í)ìݾ¥rMªÜí8´W®+ný’"¥K¡ýõ ›$2©ö.¾øy«œÚ�k*¤]ÚÄ—ßí@q�¸¸«X´îGBÇ^ H_>�)ÿœ!Ùj&þÄj&¿ø(OLÞJ²æ6©¤§¥�”œLRr ©f«9�ääd’RRH³hÝæfIÝ0‘Ý{2öŸDÛÿú:8»–¯>ËÌMgˆ�=Ϊ)ïóÃÅz<Û¯F@5Ö¢u+öÎû‚å‘×0a!1꾜··–m©å`K}*–s«øaÑq®YUR£Vðݲ3¶nM¸áævJ™NônËü÷f°­BºW6Þ¶/ƒ»;ÎÉذù41±—8s|/¢S2Æ@ÓñJcëGÝh÷Ò·ìŠMÇŠJú•ãì;‘ˆgp0®ŠÆ>ÊÑéñZÄ-ýœï÷ÄaÂÌ•}søô÷KT{¼3 ¶ŒO^u…^6‘­Ë7Q²Y3üŒ¾4n\’ î!%´Î¹Æj>âÐ|æ(GSKæ·¶;õ_ÞiV“Z]§±7?%Er‚}rB�:\]ú)_oŠ&É”FÌ�…Lõ1‹ÏqÕaÓÜd¹¸š~?še|Îâߪ%å ûŽžÀÐ ¬‡·°5ÎŠŠ™˜M?°è��O!Ò2††Pš6 àü²Yüv$ž´ÔvÌþŽ¿ãò‹’7îZÞÈ+žïÖg¯ùËn9ÁNEËù®%oØ«Ívî{®9Ê¡·ñåÀwcøâߣœ‹�áäŽ_?kN�ZQ×Yc<ë|x¸_{Ô?¦0iÅ!ÎÇ^àÀòI|¼Ì@»þí)¥ËÒ¦σâÐ^¹Î–~I‘rŸ—ü< A[$n6)ëÿgýYn¯Éa;cmž}»7GƧÝßîø†5æ©·'ñZéA¼öI_^æ¦VÖ2L þÝÇ3#}2S§ô¥Åë)½C©Ûþ=f n€s®mÌÂrŒYý{2ã°9ËGñPƒQ ¸ÑeúÆ5=�÷6-´�A®}Ÿ£?`Ú›]ù:É ¿ªmöùÿx<0óAÅ�–ï|ɨSøv`Þ�7cp ¢ÖÃïðÅ�Vx(ZëT1›Ì¸´èC‹¨Iô{hçR\(ßæ-&¬‚1kÛWšõêH‰‹¨óZt·×áPÿ)†´{›ÿëÊ<‹#î¾a´2�N(šŽ—¯Lä¥ISùø7œK4cpõ§ÚC/1õÕú8jKe{Äô´IL}㾎3áàUž¦OÊØ~!9<ô�~–Å�°0O.nsá±–AèÑÔ¬1Ο}…OëPÜL›÷ð`\Îr_ÖôîÔŸèJÓë댨oÔP¿�b>“¡RùÌfÃÆ(U ½óýÌÖK\ŒQ)UÚ+sܲ÷=Ï84–À§t‰¬;Ä\R�bpÁ«´7%�vŒUÍãœW¬Ú‡V¢7¬#Ò½êfÞô›…éðVv%:ñJOªjîoV’ì‘‚{Md†e2ŸŒëͷщè½ÊѰÛD>T'TMsÓô>€Š±nWšGOΟdgÂZ½Î„�Õ²�O^}zôU^Ü1š±]bZi?‚ê÷§Og?Þ?aÎø–ïÖ›¶ó� T{îC^;7š/û·d’s õz¼Ê3-·1îš «ä�b™7rwç8M㣽®‚ç[ú‘ËvšÎ÷мó†Ýæe-ûÑ2Î%÷åD½W¿`’Ëdf~ø³bRлS£õëÌÚ �öÜëÞâ-f¼=™�>H§s)”¬Mûwgðj ·l·mxÔxžÚ+×ií—÷;Pãââ4¿`Ë–-´k×ή ùåŸíÔ)d×}Š{•Ê•¯óèôRLþýMêjº?]ofŽÍìGßÅuøò·7©ëTÔí¹G¥íæãØØæG橚ñàÉ,œœõ�ÿ\Ži‹ÇÐ̵ˆÚX(Äœ�κ­ÿk¦w¡dQ7§HHÞ°‹\ó†ùUsÔý< q+ÔÛ7„°�ŠÙ”Bì¾y|0u•žîOíâÃǃÀ@¹¾ÃèÊB¦Î9Ž©¨›sO2qbîT¤v`È“Unÿ`¡^e÷Ž„õèO£ûæ�˜ä„›ä�‚Ë#oq?¹/çA! …vû†Í®?èB<¸ÔX½Ü‘ñû}©ßkcõÏx —¸/(%0tä£<9|$³ÌbPUùÚÓiG~`ÔÌX:ŽŸJKwnÏ—©{Ùq"‚~£Ëa¸_Λ:'¨d{ÔJòFÁä™7„È·b˜£îÇyPˆD±¹}cÞ?Û¨U.ЮûB!„B!DñUl®”¨W1�mGÎb•…M!„B!„â�Pl%¼J8Ó®Nù¢n†B!„B!îyÐ¥B!„B!ŠÄ}¾(‘ƪ—Â(Óg.ñEÝ! ,3žû/ ©¨›r_Icé€,%­¨›’'•„�#höv¦dùùƒRß‹>VS÷M¥}X=†ÿ}¹ÛR{S‰ßþÏ·­EX™RøøúS¶Ê@~¿RXg[NsŠy±O¬Êœ"®+ž‹–ã|Ò¶4žžž·ïŠÃø'ýæ¦êÕùô¯ö2«ÓsÞݽ¨àý2sà£f”ºm KÑhÜÌš·±5n;ß¼Ú•†ƒð-Uš€òt<ƒM±V;×d'·Ä¡—W)üB«Óªÿ–žH-êÖÝ“Ôkëy«~iJE¼ÏöÂøû~ÖX6}6ˆvµBñ+íGÙª-è;z ' 㜚Àžï_¥s½røû•!¼n'†|»‹ø¬³jÚI–�{š‡j†èHX�Öô½�cù 5a- ý——?exgÛw`¯öä5ΖƒLl~ç^ªñ‡ì³wr)«wŽ §ê/óép ŸÕq…ôòFîõÂËÇ�  uiÓï-¾Ûƒ%»»;ï4̧·Î)Þ¥ ¬PŸNƒ?eÝ…üô,C¡ÇªÙëX¤]À;�5 ¼¿/~¡µé8ä{ö&f‰G-1o/ö¬Ë¼ŸÏ‡Žâo—Þ|±r3;¶mfýò1<ä®V¢¾è€ïm1Vš6ÓŽåïÜÈmN±¥_){˜ØÆ¿ü~ ¨¥.»Œ³ýÇ0/«¹�ó]™SÄ=¡x.J £T�™lß³‡=YÊîFÒØáæVæ;Ø›ç›8¥pš¨Z0[ çÒ֯ܨ0èWvîÙÃιÏîÂ3sv°gÏN¾\9óa"Z¶±õ2‹^ëÃÈ­aüoî:~˜Ms^!pûôö+sÆBç¼é(Õs»`ÿ¾í¬ýå=^ü–�}>b{ñÿZÝ6Zƹ@Ç"‘ÿ&¼Îo±Î…tFZ9õý@ú|t˜jïüʦ=ÛY>¥‰³Ÿ§ÿÇ»±ï{u•˜Å¯Òkän*¿ý[÷î`ñÈšÕ›W^Ê\íOgû„Þ<»À‘ççïæô¹Sìš;ÇßÓwü6lOnæÐÌṈ̃ôaä ª8äý‚[Ø«=ÆY_™WW�âìÙ³7Ëé Œk^Š*ÛQ¾Ø<Í('«9dž‘ Ï�âI‡Œþb¯�Ûš•ŽR=¾bÛöõ,ÿ~$]Ý62ªKG^_}ÙæoÓ >Ÿj¡u>Í2§ìÙÌŸ_ ¦Ü�Iôî3…}ùÌÂŽUû²Ç±P¯¬ä�žo±£ÚnßÇö…oSnËžŸ¼#3VµÄ¼½Ø¹®ÔÃì?áDëç‡Ñ®F8eƒƒ )ƒ»ÀJ|\<ºú£Ø•%·ž=Å/•CosÛs›S´ôKÅ”x�«¿dX—¾Ì8’ßÕfmuÙgœí=†yôLbUÃ8ß­9Ew…¶(±hÑ¢ïCçZŠ à`‚³” /2þJy:ÿ¯„ß#39;‡ž¾™«p¥Û2ýÄ-k�ú¶ú Í+àç_‘&OMg[ÖeAõ [¾|‘uÊPÆŸ�ê­xjÂ*Îd93¬§¿ ƒs&î;Ë_c{Ò œ>Þ>XDÆIi,¾,•†þŠñOЦqUÃ+Ò°ß46ÅÙR— ýʃÑÝ� à`‚|Ý0(Ü|ƒ ÂÏÝÁ¦mìÂ|”­Û¯Q¥ÇKÿ�©â™3j&û¯�AžyÕ¶ù´ ó…ÖùôÆœFõVÏðÑè¸\ŸÇ,$­~…J¾ ù`wöm98‘æ¾yqŵl?Ï)VMÿ½EíFCøè�NÔ*W�‡Ç¯bÅØÇ©_1”ZOÎ&òz÷µÌ§v™ãìõÞÆÂ‰9“YXzŸ�ìL5ÿÒÖêÉ´ 'ùïýˆŒÖZb>‹å{Õ•¶‚Ae½ð zžå© ,è_ææÕe Æ°Ë  r5.ÅÇŸ€’%²äWœŒùX’ÊmNÑÒ/ÓŒh\›®#ÿÂØg&:¹æº0V e·cªq 5Ï;¹Õ%±ª9VïÒœ"Š7]a­¬/Z´È. 9s ùÄ=™Ñ'ÏÞ̉:Ïùóç9f/†fiÝö ³â{2kãö/†ÿcþåÁÌˇ¬œúî9ú|–@÷™›8y>ŠÝóžÇqþ³ôŸzsÅNW¦"KcåÈWÙŠ‰+öyâ;&¶Å1sƒAOÜ’é, Á’ÿ¶³oó4"öMàµ/dÞ ¡¥.íýº§èƒ©nàÐâoøóØ52rŸ‚G£§> �™]Ë{œ­Dýø=Ç&bì2öDcëOp^8ˆž#×Ý•{ÊPtèõ `fÏ´�¼¶Ê‡W—":ú0ˆxñ端ðÕ±›o´W¾ÏÀ™&žZ°‡¨óç8öï‡TÚô6ïÌ=ËõyÀhÔ“´r&«ªMdÙº-ìÙò�Žæ…‰[³Ý?núo&s”Aüºë‡V¾IІ¼0éúª»ýâYË6š%oaÒ+i0þ=ZyÜšu´�ažOÚŽú�o6ºù¡×z‘'®á„§.£®}Ÿ¼À—á�¿Žuh5c+®æÇ¿lœÓ÷³cŸB­†µ²|Àv¢fƒš(ûw°7P|hÙ¥ü3›_ö^Á¤š‰?´€yt4íÜo“¯iÿ_¬‰ £MÛð¿ÍÉ56ìÕMãœ�»”1Ðú½Wi�ã‚Ê�h‹ç<ûn ‰U ±¡'¤m;*^YÃ_»ïÒ÷ZJi:ölM‰ÈYw6#kæ�Wï�ùTQàú�%š÷çñÀ“ü6/kÞOgçÜù ìÁS­JÞ|an±j0 œú“}5¿aã7�pþ³ç™á6žu‹_Æsõw,‰´ m>µ×g§c¡^eóúƒ6dϸ'h[¯&5¶gà”5D_?ٵļ&ò�½êr|˜éGÏsþð4r*Íó£2Æçüyή‡Z†Œö$\M@wiï>Ö”+P¥~GMû—óù¸H!×9EK¿Œ ù`ûYŽoZÀ¤g#ðÎï)¥¥.;Ó¼ÇPû¼“+‰UbµæQìè ñz¿‚-LX¹ôcO‚ýüð»Qxèãƒ7îEÒq2ê@ÑcttÂÉÉ 'Gô·ôIõéÆÛow ¼·+>µž¦3#Ç÷g®ò[Žðë÷›ð>"Já€�*½ùBMŽÎ[ÀžŸâJQÚÛÌÞèj|ôù`Z”+…»GiJgYV€°žü¯OE\]©V´¯oäÄÁ#o.4Ö¥µ_÷]ý§|ÁÓ%—ñ|ÃòT¨ß‘§ß˜Ê¼Mg³Û’×8[3wÖzÜûŽâ­‡Ëããê†ÄS|ôÍç¼ÑÊ Ó-KÇNm?díkù¸£›].mM»´™S—pµRgÚ—Óª_ÎÞµÓéUÞ £Ñ�J=ºRO=ÀžC׃G%ùâE®éœqwwF�‚S™VŒýçóŸ¼y¹’¢ +Ó‰gºã(�xòñJD¯ZÁ�,I\qkÇ‹Cšàâˆgµ'Þ'”¨rÐŒ}ãYË6š¤°}Ò,¯7ž‘­=îðZ-cx“öcšÂ�¯†òÑžê¼<´-®–ã¬üó8=†Ð·¢+:ƒÕú §Wù;¿›Ê©.5)–Ë©®x{:dû6ÁèéMÉ´ËÄ&¨€Ž�§¾`æcÑŒiU?_B›¾ËñöÓùì©P/UI8|�³†ÊTËåÞ‡\cÃÆöhœ³Ig÷—±"àyþ×ÞëŽûʱ.­ñœgßµöKbUk¬êCªQÙéGÇݵ‡“‚ñãç.ZКWm™Oí=_äÍJÒÉULÿ;ñU»Ð©‚#èÛ«"ÍcCræf)øù·³TîÓŸˆ+ÂyÅ*@Eš·ðÅ9¤ÖÒD4 Å)$Œ²º.ÄX5Χö›ãìòÞÆrž3çL\˜?�…nO2mÁæŒjÉåoŸ¢×øm¤¢5æo*Hþ±[]è0::âè`Dè Žããä„£ƒ!c[5™d“3Žñ©ô›Àœ¥‹øzhŽNíC�ñÛm¼‚1÷9E[¿ô88hŸÉ ’£ì6ÎZÆÐ†y'׺$VmŠÕ¢˜SDñbp.ä™÷ú¢D·nÝl|¥ﮓYüV}ŒY~êèló=_ú�r„Üȹ:œ� Å”qõ‚9’#'ÒØ5¦>>c²¿Nqò!Ê F@Ñc0è hÕ‰Ú¹<_NW&�27¨ààh„$ëºOC:3nI'Þ9»‡�k×òï_KÙm“{}Å’i�ñÓ‘÷8›Žqø8„½P.Û=º¥ë?Jï;l®”  bå‚´ÚÊ¥Ÿz:OX0™�(Ûìi¾þaÕ3�•õÒff�ù”…›#‰3)è”4âÓ­´3_O« ¥º ãŹX«*“6§y‹ÖtèÖ…¦!%²%{}Ù0ÊÞˆ~þ~p!š ¸Þa}ù*T¸'z‚ÂáüÎY vŒg�1Ÿ—Ô“y}yƯl�‡¢’p‡mòÃ,ÍÒrL­1¬Ÿø,¾¼F�YóR5óòiK4gÎAPhàÍøÑZöÎYEK]Šg5kÕ Ìëú¯ÑTvMéËs„2fÍ/ô¨^’ă‹õÜ ÿ`.+ßoH‰<º‘¥CÄ]Ž�P¼syC®±a°­=ç,ÔøÕ|9û<-ÆôÍñY9ÖeCÎ̽ïÚú%±jC¬ê}(í G®\ÅJi»ß‹}GV VtèõmךWµ*ø|¡E–9E5“fr"¤å³Ìš2”ª=•z÷#bÚ$~ùk ­»¸‘°jKãñNŸ 7ÆYK¬¢óÀËCñFŒ:WÜJ* 1è­X¬ªæùÔžs\Á™H7Y±Ô{™O†¶ÅKʾÁ”—ÿ¡ñg?³éíz´Ì²uÎ1Ÿe›䟺öªK œߥGÖŸUøˆ¯.í¢é?²ñ�Ò|£¶9%£Ú¼û¥EÁr”�ÛäT—–1Ôú>*Ï~I¬Ú«E1§ˆbÅ�PLÿð€Þ=€råËçã�n·P”\ž¡ (´œ²‡ßŸñÍ#Õ*xxyäù Žœ÷aK]÷+%kóp¿Ú<ÜoÃ~Žfƒ'ðíÀ¼SýfrÌmœUõn­£êðé2�?Þ©ÇÕåoÐg* úh�Êf¶Õr”Ï<Ë—Æ!üô÷Bšú9¡¤.ä©�ÁÙö¢x5gÄŸûxnïzþ^³–uÿ|L¿‰“éüåLïâ—¥¯ÙcÕb±JöXÑ0Ü<×·±wF�®¥|)U"û·º GéßòCÞœû'±�Z³êçÕ¨BwÿÌi‰Õ̺t7/Å˼M$»<çS»Ïq¤ó¢”—×Ò¾¸Þ¼¬�€°²ã/›¦1æ5Ñ�{Õ•_z‚+„aL¸ÈÅdlºü9ç9Å~c¨¡êR(ÌöÜ2†.vz¯.±z‹¼bU®�xÐé ãÏßdÕ­[·|\%a£‚|@5”§r98¼{¶Ë‰L±g9Ÿ|§›œ´¶Öu×>x¾ô]_1àÑá,¸�µŸ:¼+UÂW‰çêm�(‡q6„S1 "Gfù“¥V.¬û–iß®ãÂ-è^‹æÈ¡#œ�Ïÿê›ÎÍ��°pê¿8�1õ÷1zð§ì»~Sö°m¿Jƒ'e¼YLGpôÖË’Bbª¿šmé7l,_-YÏ/O©,üöOb²tÝu‚Ó7^káÌÉ3àŸõê°FEfyØ]æë{^ IDAT6Áè)¤xÎÌ›vÍgÞþÓ,|!‚ráᄇ—§ÅÛI;5“Ǫ4aÔf“ö1Ì”ë1M=Ä×OveÔÙ®ü¸bÏÞúAY燿D�ÑÏÌÑ«Zh™Oí<Ç{o£ó§n]âvnãD–ó=úÄ)LÞþ”qB[ÌgmNAò�½êÒ´Ÿï‡>èeYÿR‚™ÈƒG0û”¥¬«-susŠ�ýÒ¢@9Ê^ã¬e m|•c]«¶ÅêÝžSD±S¨Ç½  ÖÄÎDE•µœ9O\–§þ==)‘´‹¿×FréÒyNÚÎîÓÉÚ×ÛôåèñlsÒŒfÔ²“$[Í\=º„‘=›Ðaäz’óÞƒv6ÔUà~¦ø œ‰ŠâÌÅ̪™„‹QDE�áB|ºMÛ�²‚ÁáÞ”j0šùøûâÆ�\ŽýÄ»/Œcáö\ˆ¹È©=Ë™2ò;Ž”~˜v55Þ·b¨Lϧ7÷¦üERz*—výĈ¡#øå”î·DtêêwhѸ¯-O(ø¬.ˆ>S>¤uÔÇ ž°™Dÿÿ³wßQQ\m‡»ìFé ,ˆT;Dì± Q»ˆ%–Øc‹1±¡ÆØ�5ÖÏ–bQ$&–X•Ä,¨ "Š]QQʲûý((Ê,,ˆÉ}ÎٜٽóνïÜ™¹w j�GòP) 0{áAä¥àÞÝ{™øJæÏ1uðî²€£·RС#õN4ÇÏ?ÄÚÍól}súõ­,ù!ЇZÉ—Bù6$ç–-©˜53ªÓ‘ÆâuÑ<Êü΢�—)תm>K ¬9†Ý‘Ç9Nxx8ááû ê�±º+Ë÷†2¢ºRb>÷ê6}Âái}˜]Ÿ™K‡RÍø‰‰‰$&&òðQrÆA·Âg®…Ìçû3÷IyzƒÃK²ínîs¯\–ÜŽv;ÀÆ &„žâÚ­kDnGPˆ‚ƒÛc/Œ}ù ¥%ÇVÍdóÙD4¤óøÒ6æ¬:ŠÅ{mðÓëi¡2̼*â¤9KÔ…WŒJä•zÆS z΢9ÏñSOqñ®’#Ï_ôÊeIÍç¼Ö]²D®ê—«é—£ˆ~ª¢¼—ÅËRÜ_dÉ8¸Ìùc»X1¬ _ü¡¢ÿÄ>¸�>ýªÔýiA÷’÷§”nÒ�vÖóÓ¤ D8ðaýç÷ÐIÊU)¤ìO ¼�+ø±�’š½âû-C&ýLTÂmbÿå‹ÅQxtïF-%Òr>›õ?†Z– GlS�°tô0þ~Ž„Û×86‰aK.Qù£^øêuûoûIë¥#-ù III$%=!9M‡N““¤$’ž¹úÚ}ŠðŸPhƒ¿BBËí�øx{ã�ýS½3�=Ÿ0i0„ íŒ ëíG¥ªµiÞýK¾;ž¨Ç$Ç©Ç ‚'W#j¢?ÎTï8—¸s þªz=(Þ€Ë*øzi8¿¬35¼½©¸’‹©±¬é^oï´ÿ6:óÄAÊw2¤�þ“#KPP_ªçc„\fÑ‚Ùa«èiΔÀúT­P™º'°»twþ:�¦¥ó.#ƒ®}WüyYÂG5ÁC]–šÝW‘Òi5!ãý(À£$‘ÛwdÖ¬÷¹¿ìc&칇θÃfõCõ[o¼+T§ñÀ_pµš)ÝÜ9ý•?�ÿ‹!Sê�[Ř²¿3¤¾;ö¸ÕÌž²ãø~bïG4®Û�æW&â_Ñ׆¹è7•ŸÕ|v SZZ:¥ÞÀ{—&Ь¢ ®�&Û`&+?«žùì•¢Ìg ŒÍ°µwÀÁáùÇÖ\‰LQk{;ÌMIu(AÚ16oŽ!åÚfú×,‡‹‹Ë³O¹j£ø#@I�‘Ë™Rÿ³›—Ç¥J¾yÀ°–eÐ¥¥½tRùj2,ZÌ$xf-ÎOkOÍ*>tœu‰ºs62³EæUfÁ{³7³Àÿ ÚWÁI¥¦B«iÄÖŸCÈ7­3î/Õƒ¢J3Û^dÏÞ˹ÖGž¹a¨x$Õs¦ô›\¿ *ûüÞ*-ŸóÞ.$¹ªGnh¹²gg-Ó´ÚË5\ÐýEÖ2n‡ À§š Ú eM| Ɔ†1©~Ö%ÒûÕ‚ïO¥�¾?•ÄÔ�jNüEåÝ©š½š¥äª$ö§ÞÇ¢-ŒÜû³ú§Ïp=<ž–Õ*Q¯_Êî«X7ªz曡$ä¼$RúC-K™-ç„0¯u*ë7Á»²/�¦ER~T0? «$½¯Ëôú}Š„õJ�f^sÔj5jµ+½B�²g8ÕjÔêJ ß“òR©¯X1 uh z–T‡†;޹*5W_¿Oþd€îþýû’päÈZ´haÐ@$ŸYÌй·è¸üÞËíž±¿òCìSÞ±OÞ´<÷)†¸}CAAA„7B¼uEAAA„7B J‚ ‚ ‚ ‚ðFˆA AAAAÞ1(!ü;=ÜH7•XX¨h¿æ–�ßIÿ†¥üL•-ÍæÇäò~qAAA„·C1”Ð5³6Y'•YêL�D£giºéQy»_÷ª©b¦À1§_`�¿í³º³´²EíéKëÁ 9p£pNc‹U=›uâ»+ $\ ¥¯c>žæ«»É�Õ8vXC‚öÅ¿Ýf}W'Ú®$þÅ¿E5úÌ�ËgþvÅf#Ö= çK_[l|&‘Våß�`制øy9agc‹£‡­/æÐ�7Õzxɬf¨ºn 1·?ŸßĨ޵ñp°CU®:­†®åÔãlÃh©qìœÞ‹&U\PÙ9àáÛžÑÁgyªoÚ;úv-ª•Ce«¢l¥Ft›¼•K)Ͼ@ÜҖؽÔ÷¾z,ÿí^”ËÊ&�¶�ü�‚xÖ?[bi­Âɳ&ͺÉš£·ó5ÈXd}ožù#ñ;Ùc/H›Šx OžËÒ;A}—ó™(ðÂñÈHŽo臛± }Ö#2ò8[†TÐû5cš¨cœzÅN¸@téhÒ gþÝ01˱ XÅɨ(ÎDfÇòÁ¸GÍ&°ë\N¿îà&ŸëUhõœ/r”&¦˜šc”Ÿ7 ÉliÕ¥ ÊC[Øv=çI¯îöNBáA@ ²$ŒÊÒ°[ZV2£x¼@é1g|Îæ;% 'Ý]ÂFu%è¨+Ÿm8Hô…³Z÷)êˆ)ôÂÍ×Uc!n§¯§#íñ ¢v/cx›n,>—ûpªîÞoŒø’c•dz%â4[Æà~d<¾9FÆ9f2G¦Ð{ícZÏßÅÉÓ‡Y?Ô‘Ÿ2nïC=®Ò»¶?]gž¥òØEF°}n ÿ0€sN’–ù�Äû‰È}'q(.žøø¬O,¿~âŽÑKe¤Ý‹rYRÚBZ{Ž›ÎËù;"œíkƒhkö“Ú´âóÝwõ¾ª«hú^iù“÷w²+Xþˆx �”eé»� ‚ ‚þ mP",,¬@¿Wš«prvÆÉÎ …L�™�3ÎÎN¨Ì�3¿‘Âöe)?l=;§H³º>Tró¯û|ÝÏ:¤KeßÈò¨Þ_ÁÕ;ë°Ëá·õgÑ¥lãûº{Yö1-k¸ãhï€K•Æô𱋫ÙöÚÚ+KiéÐ�Y§ãÙóuµÝUX[Y£îF²äx¤,KbÌÉKZbïà€ƒÚ•*�û0srgÌÿÙÊŽ˜t‰ëhïrxifÌ*\*7¦çô|Äœg9€.‘ãkFÒÖ×G;;Ôåë81Œ ÉèWN�ɰjÞÿ’úËUžKh¹±=ŒƒÊ¦tii“qðf�ü´·80¯/M«ºâho�“W:� ͱSð³Éc¦*Ïú‘˜«zH:4“Ñ»ë0n@ÅÂ9HÕœçhÄ#*vþ„Õ�°4·ÄÙ·'³Îà“Æ*Ò2HR=KɱLOC{¡²P¸þ�þ·ÿ¤d|Ýê´ Úƒ²ë f´.•ˉE:—Ö}ÃÛ¡, ú€Ê¶¨«0ÿÏËœèƒ1@Z$[Ž¥ÂÀé oê‰ÊÖŸ³™Ú)•е¿ñ@j`ºDbâdø ™ÎÔÊÙ«©ÔbÃß7çÒ_‡¹¡Ðñà~"2kK—¤dɬÏ;˜*_޾`í^„Ë’Ò’Ú˰ä¥lprñ Jݶ|ºd3óZ&²nÒ Îd�‡äÙ'è·¿(P>KÉI9ö\�ÚTÄSðx$-K¿íTAòC^X»”°°°LäE¡0âþÖE„9�gëÁNž�ÏéŒZ•y‹‡1 gErnñ{˜Z²..�„„®nããrY»]-±kúÑõÛ‡´_qˆË qœ €ÉÆ�è1ïÔ³Ù¹½^¥cø-èS¦^l̬�§¹xéÇfùc"9)Ë’sþÉd@¶Cí¼×+�‹+û8'ž¦‹þäRÂŽ}׉§k{Ósþ=b–RŽ–¸ïûðõY|¾ÞFäÅŽþØ—[t€$ÉåˆYSº´2çxèV.gßkضåï4ÀßR†!óçñoé¿"�^›"‰K¸N̾i”?4†±⟠Š(¼Çp >�„øÝŒ(Ÿ[>H«Ÿ¼sUOŽ0{ôoÔž>�Æe ©G1rÆÓMAôÏ+Ùó(³>d”©Ó›‘}¡Î¬Š¼ëYJŽˆÒ�)ñ\8´‰Ùù`•[sép8üÔµÕDNýÿZÞxû½Gÿ¹píÙ¥ø4é 4VfÛr�±w°&ùôI$OèË,ðŸʦ/ê`šõoÚ›\ºôˆRj',äZ>xˆüÖNÆu¬OU/O*ú¶bÐü}$¼¸œ·{.KJ[HùNa’ÙÒ*  %/îã@æ}ay÷ …»¿ÈŸ„ü‘”c™ Ú¦"ž‚Ç#iYzl§‚ ‚�Or“Bè.ô� àÀg]½x�Û4æ=_%—þ9GÖ•¬r… ¦J9ÈŒ2.ç7}á’þôs„¬=„K߉ôõ±Áe*v!h 7çƒ7ùì¬Ò[+ §®Ufæ’Á4r·Á¼Œ-޶ÙfÓòŠGâ²òŒ9_´$]ÞÅŒé¡$VjCkϬ³¸<ÖKóÁk�b8Ž¡õT˜È”XÕÈø�‰!R#1f)够eêpÌ»MâËæX—2ÃÁ§3W.atcKÒtÒã1Œw¨ß¹ ¶§·°õbæ•%ñ¿°åhÞïÒ˜Ò`ÀüÑñäæMÉK`n^#d˜Ú7æëßϱ±·úù%M2Æ&¦˜š˜ È-¤Ö�„mGš§DÌÍöZÓ jR¦ðf–åŽô˜»”Þ¥·1ÀÏOßVô=�àCñä¸À!¯z–’cÙ˜úOcÿÁýÌi•ŸÛdŒ06ÎãÄ0=�«×Ó¸±q>[Ìz2ÓVÖMz—»«{Ñeúß리JÓw-9µv6[.>A§Kæö‰˜·ñƒu¿„ñ¿a9?¯+�§Gd«k´{Q.KJ[HúNáR8:£â×o¦#µOÐgQ°|~Q.ù#ù;…ÑoˆxòOË’¼� ‚ Bþ)JòÕwYƒíÚµ+”òåöjìŸGÊ06QBRšôÙ^ÍEÎ]JáÄW¾X•óO2Skâ4à£dF(F86nMõùŒGê² FË­)l: )i¦¸¼û«æ£RÖƒ9òZ/Í%bbÁ­‚;ÏCSàVÞâ/q%|¤<äCJ9F1œ½®ݳ=7DŽ­o �D¦µhïô=[~>ÏÐϽˆÛº…ãvmW/³² –?2lÚ çã }é_­³ýÒ°QZ¶kC}—’ÒJõ¨Ÿo;@ò±oø|{ ¦ÿÖ„22õø­¾”.0ukkÆÆGò×þýìÛ³• v³ù¦Ër¶Îÿ•œ¼ë9MBŽe#+íˆW…ÂZ#€4RÓ´¤×‚aþXÊ€²£™;äwê~û‡ÆÔ¢±qiü'¯âË!Ÿ2ÂÏ•¡ÆJÌ*ufdÛºüò�‚|]A­½Mø¬�è»ì�W3´Ræmq2 :¯=OçìßõœÉò['¨¿ô{þíCSµ{Q.ëm¡MG‹##0XŸ��ÁòùUù#ñ;oSO¾ãÉsY·SAA(Å÷àÁõy)Ø¸Š ™Ì˜wçFÚÇ.�²d”±,“çƒ8^]†>Ë29ÖmæóëX_”rcJÙØaS2·Qië•ÛïdY‰çåètù}(¡¡âÉÆ¸�Ú»±ük–o g}/[Vïà¶ÔT(ÂúI;±‘à3WØ2Ðw77ÜܯÞÌ¢#-ù III$%=!9M‡N““¤$’ž°6/^9ýꘟpxZ&D×gæÒ¡T3~Dbb"‰‰‰<|”œ1H£pÄ6õKGcáïçH¸}�Sa“¶ä•?ê…¯RÏv]× wÒ—õú˜‹’nýVñSò8&õ­Å7wS1±©H³!?±d GŽW‡½>f)åáÚw5ÁéA|5ª âad]žw»¯&äs?JèÊò´ôeóÜæ¸ÌÑ¢Sx1r÷ŸL¨¦GÉ�h×Ù—)Ÿ¢Ö¬öä|¨½¡òÇ”zãV1füD†ÔŸÇÕGfNÔh=Žï'6Ìxzzê>FUíÌw·²Íˆ}]ǯ¹=}ÃN2§�±~õSÆfØÚ›eû-s%2Ei¬íí0Ïv°švúOŽ<,Aýñ}©ž�«5d-˜¶ ÕÔEL \Jüƒ4eœ©Ü ;ÿ EÓÒRK’’c’ͼæï2ýtö™ÍáTTYןei ŒÜû³ú§TÆ�§åÿn’^Æ“F=V±nTõÌ9Î=²4n$“û×á›Ç%PWÿ€ �_ÑËE�M;ÆæÍ1¤\?Gÿš›süInÙ� ÑßâolAË9!Ì›ÄÂÁM˜úÊ”­A‹QÁLT)ã !=ÚýµdE¸,)mÑ좤ö‚‚çsֺ܀Ï&9Æ%mpõiÉØÐ1ôó˚͖Ð'd*’ý…”ü‘IÉ1µ©ˆ§àñHZ–„íTA Hèîß¿/ùGŽ E‹ äÁƒ-O„â"�˜ù-h°¢?Y„¿äA(ŽD> ‚ ‚ ÒyN– ÿ!º{9xÏÞƒh,Nà„·�ÈgAAƒƒ‚ ®äcŒ©Ï ^ ï~1A(*"ŸAA Jܾ!‚ ‚ ‚ Â!®”AAAá�ƒ‚ ‚ ‚ ‚ ¼bPBAAA„7B JBqñp#ÝTXXX`a¡¢ýš[èÞtL‚ ‚ ‚ …¨xJ¤þÎp/Í¿½ŒöÙ?j¹¾² ª²ƒØ™òc{•ô ,ð·ÅÂÂKkNž5iÖýKÖ½Mz>ŠÓ=ØH�ÊCØ�jðH‹¯gu˜qbnie‹ÚÓ—ÖƒràF~j1oŪžÍ:ñÝ•®†Ò×QV¨‹ÒÝ�`制øy9agc‹£‡­/æÐmÞ?6´s»§^e×Ì>4­ê‚ÊÖçòué4zggnÒ=$rí>¨åŽƒÊ·š­ºú‰¯‘Ò= çK_[l|&‘–}YqìœÞ‹&U\PÙ9àáÛžÑÁgyšãÇú-+ߊ[(rìß—c‚ ‚ ükÏA‰â@—Ž&]ߣ(96�—ówD8Û×ÑÖì/&µiÅç»ïê=ã­‰:Æ©75ø’¯u796«8Å™ÈÃìX>÷¨Ùv�Ëé´×ü,Ÿ1¿Ñz~‰¥‰)¦&Æ昄î.a£ºtÔ•Ï6$úÂY­ûuÄz áæëª±Ðr#Ÿí.E.1M»§plf ½¾K¢õœ_ùûÔ v/í‚Ñ/#èþÕ_$gÇíŸGÐ%è$Ælæè©cüäMÔ¤@FlÉíJ™Çœñ9›ï” gŠ$sdj½×>¦õü]œ<}˜õC9ðY ãö>Ì,GßeTqëEŽýûrLA„ƒB” +¬¢ŸÓÞâÀ¼¾4­êŠ£½=N^uè4.” ÉÙ¾£»Ç‘eÓ²†;Žö¸TiL¯»¸ší T{e)-2ët<{¾ ¶» k+kÔ}ÃH~i¡¯'/eƒ“‹Uê¶åÓ%›™×2‘u“VpF“ù…¤3ü8²-¾žŽØÚÚãVóFn8›m9©ìYÕû+¸zgv™—óÛú³èR¶½<Ë’ÏòÓð÷¨ZÖµ§]¦í$ttU×ó@§Çºç±¬´ƒ_R½ÎPfŽnM5wOšOßÅί;áëUŽj=࢞‘ò’–Ø;8à v¥Jã>ÌœÜó¶²#&]zÌÚ»^šÙî*\*7¦çôìí.±žó,Ð%r|ÍHÚúzâhg‡º|}'†åÌC)åÍyŽF<¢bçOèPÝ KsKœ}{2ká >i¬"-ób Iõ,eÝ%ʫݥÔaÞ1Kl÷LOC{¡²P¸þ�þ'TºG<µkÁóæ2¼yeœTx5Ì€ffÜó¶-±kúÑõÛ‡´_qˆË qœ €ÉÆ�è1ïYÇ™r{/¼JÇð·~ý¥ IDAT[ЧL½Ø˜Y;OsñÒ9ŽÍòǤ ÊliЄ’÷q ^ hˆœßŸQ»¬±-šk×βm¨%;F|Êò¬ƒbŒi8+’s‹ßÃÔ"�uq $$$�pu—Ë:D”RN:Ñ‹óÙŽ2|úëY®DýÊÈß3}Ë-t % ™Ôu—°,…YìN{¯ä¯•ï“ðí›MçÀÏC°Ø½†­úŽJ¼X�2 Ûœ]Þ1§sqeçÄÓtÑŸ\J¸Â±ï:ñtmozÎ?“ÙîRêYJ9Zâ¾ïGÀ×gñùz‘c8úc_JlD@Ð’$—S„ŒœñtSýóJvÄ<ÊÜVd”©Ó›‘}¡Î\ý¼ëYʺç_Îv—V‡yÇ,¥Ý DfMýA o¡ÎýMÄåß±d· ;4ÅN¤žáØiÕüªaú쇦x×öFvæ§²_úÿä³GÿFíéh\æÅž[ƒ&”ÆÊl[Š1öÖ$Ÿ>É9�žË* /õ‡RúðÂm/‘cÿ²Aá­$7)ÄËÄ w`BÇ“›7y$/�¹y Œ�ajߘ¯?ÇÆÞYhçY{—¾éëcƒ1 ÊTìBÐ@oÎo"òÙQ¦ ¶VN]«ÌÌ%ƒiänƒy[mKQÐêQ8:£â×o¦ *�ÜΩý‹èâa†RiNùÎm©¥‹"2úù©©\a‚©R2£ŒËùM_¼¤_B9é±ìÞ�u»OéUÅ#¥5µ‡Œ¦�U::²�âç¹îÒb/6²£„‹;ŽZ[|ê•ÃÔÅ•²òÛܸ�ßé1-I—w1cz(‰•ÚÐÚ3ël9�˜5ÿ¼ö(–�ãZO…‰L‰UÍ�ŒÿЙèà"5ëYJ9égÙ°*ón“ø²¹Ö¥ÌpðéÅÌ•KÝØ’4�ôxŠŒÜ‘s—Ò»ô6øyàéÛŠÞ£ç|(>ç•6yÕ³”uÏ—\Ú]jJØ–óÞ¾ž3õŸÆþƒû™Óʬ}AÇÖ@eWŸ^0ÂÚ^.È]Òî&—ÂÊÂ8ÇŒ¹ÒŠÒ)w¹ó0«Ÿ1{4ÛkM'¨I™—cQV¥é»–œZ;›-Ÿ Ó%sûÄÌÛxž´÷x ÕgY…'g(¡G¿ö’NäØ¿5ÇAAxûÈKîóô q`B†M›á|ìô;ý«U¢~ûþŒ�¿žðؤç—Àj.rîR '¾òÅÚ"ë­VTùò )ׯ—u�)3B¡0ÂÑ¿5ÕK8Lm:ZäežOkofÕèŽøUòÄÃÓ ¯ê#Ù•ª%]£ßÁZžåhˆOµ‹EÖ�”åñ®ôµÖ]RÌò2X–‘ƒR‰R^ ³Ò2�)QiI×ê³nZnýH9GGì)ëÛŸ_Ìú°ê»aTÊZ‘¼bÖ\"&Ü*¸£|ö� ÜÊ»Cü%®H½Ï[J9i1œ½®åÝŸ×3rl};ز2edŒÇ€”.0uk$1‘;X2¬9·!¨�/ ‡þÂ�¬1¤¼êYʺK–G»K­Co˲ҎxUðBm^�;ݔԾ™ýûvðÄúÄÍèL�eQ/Ý&³pÁ»ZU\-Ÿ%ú³¿%û†Ï·×`zP“WÔkiü'¯âKÏ£ŒðsE­ö á§ðm[¥B�ò…ß¼nY…*G(¡7ìÂEŽýrLA„·Žâa±¼ÇSŽ\ºôô§�Šg³M2ˆŒßqš~§ÂÙûÇ~ü>‡î³¾áƒe¿²¨� 92d2cÞ�Ih»<‰d”±,cð‡l$_‰å:Ž8;Aúy–ôýˆeÊ¡ü¸w õU¦È’·ÐËe°~…J)G§E›kÛæv¸ÿšu—³ù³d™—Eç‡ë6óùu¬/J¹1¥lì°)©Ìå{ùm¯‚Ä–{9:]~O£ O~È)©®NóîÕiÞ}(ÃCûÑ`ð V÷oÉØ*ÏO$^WÏ[÷œ±Hk÷ܼX‡…³-ç�­VŽ©m9¼lËáUÙ—šÆW¨6y{{­ uIlJ<æÎ½L;Næ·Æ¿zr›G%¬±3“Aò æ~þ ÞSwÒ¤ŒŒÜ·a�YÖaøO|òø.‰ÚRXšqúëàà‡½Ȥ,«�åè‘Ò‡’ȱÿBŽ ‚ ‚ðö‘ÎËОk×®íÚµÓïGrkl¬t$ÄßÈöú8 q—®¢³µÇ6ëH0ý)�“•¨¼ýé>ük–o g}/[Vïà¶PxPÁΞ<“cÆ(íN< Or;c7ð“ö¿nüƒÔ*Íx×NO#ùûŒŽÚÊ8¹ÒÎEqþU�ðª“=)åÙao7²×¡æê)�#ó®�·1¤�ØHð™+l胻›nn4šAJì :V¬Ç¤Ãi€†Ø½ËXvJYamf‚<í,;~»Œª^}ÜŒ¤-«P½ØBÞ}xvü9–å_šc‚ ‚ ¼• u¢'_ Oš7/Ç�-³™³ý$1—αe*SCnãñAk**’ùsL¼»,àè­tèH½Íñó±vsÅ\¹Óù£†¤nšÌ¤m—y¢ÕðàüV‚êÑ2(œ'^_íãÛ\�»Ìùc»X1¬ _ü¡¢ÿÄ>™l¨mt\<ÉC¤$üÁì…‘—‚{wïå8¨TZXP2é{÷_äÖ­b£#8yåIÆü•”rŒ\y÷]g®‡-'äÂtš{D,[À¶»z>hM�˜‹ Ezùr/x:‹ÿ¾‹ w�-cê�7¨Ù+�*Ïï5x}=K)GQ�€Þ~Üß0…¹ûâHJMæÖ‰?l<ëc�1—ëOLŒuÜ»~•GÉÉ$§¤’ãîž§;ìf…MíÉËǃã”..¼ó#ãNeKÄ%nܾIlävæ­áœmsZxKœ=–²î†¢w¾ÞkÛ=›äÝciT·£¶?Ôÿ–_Ú}à@䢑ÌÚEü­\8¸–/çíã�Æ­¨÷ ·£ÝÀ°1ˆ ¡§¸v둛Ƣ ÃàöØËAYs »#�s(<œððpÂÃ÷2ÔcuW–ï eDu% G»“oF~Æ7\æöÍh¶ eÉõú X;㌖õLs,ËkûC)}x&©íU "ÇŠ6ÇAA2Ú!B¾$0¦æèµ,è`ÄÏ#ZS¯vC:ŒûóžËøndµÌû}M©7ncÊþÎ�úî8Ø;àVo0{ÊŽãû‰ 3Ÿü-Ç©Ç ‚'W#j¢?ÎTï8—¸s þªïh]ŸÓr;d>Õ|hÐn(kâk064ŒIõKgÌ©×aج~¨~ë�w…ê4ø .£V3¥›;§¿ò'ð1Ï®j0i0„ íŒ ëíG¥ªµiÞýK¾;ž˜9(!¥%5F,a¢o “ºáRµ- ÓºóI“w�ÉdÒ¯ Ñ#æâ÷~«øi¨-ÛûÖÂÅÑß¾[±òkzäxÍÝkëYR9F¸ö]Mðçe ÕuYjv_EJ§Õ„Œ÷£„žñ ,Oë@_î|Û{{ìÕ ™žíi˜i§ÿäÈÃÔÔ—êù˜y”Y´`vØ*zZ…3%°>U+T¦nÇ ì.Ý�ÿ…N£iiéõœ÷ºŠžu˜‡×·»¡¼CýI›XÕ³4»>o�O¥ª4곌õ¦¼( ãÍȰh1“à™µ8?­=5«øÐqÖ%êÎÙÈÌ™ý†¶ö88<ÿØš+‘)Jcmo‡yÆÙ Î=²ôCSBûס¢w+&ž¬LÐÆ•ôrɪ ËÊTÐË�G(©ÏP4í%r¬(sLA!‹ ÐÝ¿_òŽ9@‹- ȃ Zž�%û»6ÙØ½"ã­¿çÌ‚¦ˆ+ißFéÄÌoAƒøáÈ"ü% ‚T"ÇAA„¢#.¦üK=:™ºÎ~ ÿ%–'é©Üúk1«þ,E£f5�úx7¡˜ÑÝãÈÁóxöDcq²(‘c‚ ‚ BƒÿbƵ>eîçU83¶åTÎÔ¸õˆÕL_\FûÖJ>ÆÁ˜ú êU=oqiDŽ ‚ ‚ EHܾ!‚ ‚ ‚ Â!®”AAAá�ƒ‚ ‚ ‚ ‚ ¼bPBAAA„7B Jä›–+«ÚS®ÖX>}Ó±üÇ<ÜH7•XX¨h¿æº¨ãá_ã©çÚ”Çß’ÆLù™>*[šÍ�!ýMÇò¯¥#1b)ü«ájoƒµ�e+ö'ôžî }çm’®O\±ïº�ÄB(û—¾Ž8öý…ƒ—-ùU˜9_¸’OÏã=×ZŒÜ{¯€ûRAAÈŸb;(¡»ÁÊmñórÂÎÆGZ ^Ì¡;Úì_"bå0Þ÷qÇAe�[�– Yv”»º¬?ÿD€Êëš8ššùí–·Va©êÄ÷·u�~�þ¶™'¸9?V^Ãù=õ¥Ð2Ê~°›Ùó¢¨ÿùpê”Ð5³6/•cC�©‘hà¥eYZÙ¢öô¥õà…¸¡Ç©¥¡ÊуîÁFzTÂîWÔG‘2ëÄwWH¸J_Ç‚¿GD÷p?S†}Ç;C2²F‰œ“’‡o‚¢}æÎå3»7¸ë“ó–XZ«pò¬I³î_²æèíÂLÑ=$rí>¨•Ù'ÔlÍÐÕ'HÌÏ‘¶æ K†Mbï;�,ýí0Çþ>Løö¯hj.{3ß) Iý¡>å§>!Oÿâ\M¹Ìö©½iêíŠÚA�kÕ&ô˜¼…˜ä\¾û4’YÍPåvâ,%Cn_yH EEU#æDŸa×âšóºGá|ék‹�ÏD"Ò²ýAbn˜V‘Öl9‘Ý÷Ű„ ‚PôŠç „î.a£ºtÔ•Ï6$úÂY­ûuÄz ᦠ�ËkûÑy|86ýVð[øV¬æÈ¤Îô^“q� 3ÇìþÏÊØ §_ %ä| Ìrë˱鼂ˆÈH"³}NþD]ãÜLåÔÒ©lµÄØö¶™¯×Tà9(„ã‘‘ßÐ7cú¬;Fdäq¶ ©�íÕzrlVq2*Š3‘‡Ù±|0îQ³ ì:—Ói¹-ëUòYŽ.Mºþš¨cœ*6Ó’r”&¦˜šcTàs6 Ñ+&³.½+Aƒ*‘£¹%åaä³-0*KÃn=hYÉì ¾ÞU�œï¼œ¿#ÂÙ¾6ˆ¶f1©M+>ß}×À³r:nÿ<‚.A'©0f3GOãç o¢&2bK>®¦I>Ë™K¦40œUÝ(ë쌳‹=æFoè;† ©?”FZŸP\^>üoÍÕT"fòÑ&l<ɕ뱜ØÐ“ÐÁt›þ7©™ËJ{|ƒ¨ÝËÞ¦‹Ïir)GJ<Þ¾ÞBÅ3çspÆçl¾Sâ…%KÉ�,J<ûM¢§ñ&&/=…^‡"‚ ‚`…6(–ÿkÎs4â;B‡êNXš[âìÛ“Y gðIciZ í8k¾ ǸãtjB�J4ê·€YÝJsdÉJg8(ÜiÚ¸;6î' Q7s߯!î/ìËKÙàäìŒs¶�“£%¦¹„§½ÌÔ•‰tן Êçÿ®4Wáä쌓� ™3;gœ��P™çÙ�—´ÄÞÁµ+U÷aæäΘÿ³•1úÍåUŽöÊRZ:4dÖéxö|@mwÖVÖ¨û†ñl¢D{—ÃK?¦e wU¸TnLÏ黸úì¨$•}#Ë£zWï¬#À.s†ÑÖŸE—²Å›g9€.‘ãkFÒÖ×G;;Ôåë81Œ Ùgm¤”cHɇXó]4^=úR÷�þ&%t÷8²,3f{\ª4¦×Œœ1çÕI»?¥¼�SNæêå_™«ºœ‰¼‚Y£.´÷2Ãæ;Ø $WOGñ@¤d|Ýê´ Úƒ²ë f´.õòi³”x¤|§¨å™«)lP–òÃÖ³sú‡4«ëC%7/üºÏçPö+’ÏòÓð÷¨ZÖµ§]¦í$ttU×gÔ¡!s>S�ò'›¤C3½»ãT$Ça�”ÜÈÎÔ‡>=+sñǵ„çv•� ‚ "ya�釅…å`ÂÈO7Ñ?¯dGÌ#2Žud”©Ó›‘}¡6íµ£‰WàÛ¤.¥Ÿýðüׯôæßü}%ó@A'§Òïc±{#»occX Í[V-À\Æ#ö}ó 5>ã³wKçýu d20ÄìÊ‹åÈí½ð*ÃoAŸ2õbcfí<ÍÅKç86ËÒ¹¸²�sâiºèO.%\áØw�xº¶7=çŸÉœ-1¦á¬HÎ-~S‹@ÖÅ%���@ÂÕm|\.ëHJ9Zâ¾ïGÀ×gñùz‘c8úc_JlD@Ð’$—cXigöðÇmWšù»ñÒ¤´„<-±kúÑõÛ‡´_qˆË qœ €ÉÆ�è1ïùŒS^mQ²a:©/³9øh¶ûäS9¾a#çÔ�éÕ8#×Þc8Ÿ@BünF”Ïm]J=K‹¹ÐÈliЄ’÷q Þ€g2©g8vZF5¿jÙMñ®í�ìÌ1N¥&¼t*U÷�æóM×Ñ’NܺŒ=âËŒ%ð4Lš³è| gçÓÔÔ–7Æeä|Bñác©¦(âïRžý¡”Ü�Ò'd–ö÷JV%°ê¯sœÙ>‡ƒ_3rÙ?™iR¶w § dô^{Fï‰!.z7_{íæû=EtÖTÜsUfÍ»mÀï?°þÔ=Òt£7ü§œú4ÂJ(ý˜Ï…C›˜ý‘V¹uRâ‘ò�"%­S(Œ¸¿uaNãÙz0‚Ó‡çãsz£–Ee^Q™NôâÁ|¶£ Ÿþz–+Q¿2²Ä÷Lßr �B‰B†Ëy{r„Ù££öô 4.óÂ1„”ÜÈÁÿxÝûƒ='ŵ‚ BÑ’›╆ù˜�;ÒcîRz—ÞÆ?<}[Ñ{ô<‚Å?›áO¿s‹»º2ØÙ˜äø©ÂÖ+ÝmnÜ~6��Q¥Ntt 'lQ0»”mèäóâ=Zn}€³J…êÙÇ‘¦s^>�HûgSCJÓo\ ޾ÎDKÒå]̘Jb¥6´öÌïµÚ¯(Gnƒ­•†S×*3sÉ`¹Û`^ÆGÛÌ™2Í?¯=Šeà8†ÖSa"SbUs ã?t&:8„ÈÌ™A¹ÂS¥dF·M˜¾pë„”rÒϲaU8æÝ&ñes¬K™áàÓ‹™+—0º±%i:éñŽŽ‡gÿ!^Q�ʹœýIÈCÒϲö.}'Ò×Çc”©Ø… �ÞœÞDä³Q‰<ÚÂćn]¼¸ÌŸO2óôO~ÚO…®=ðÉJs™cSLML2–_ ¥ž¥Æ\ˆŽÎ¨¸Åõ›9·0Sÿiì?¸Ÿ9­ô¿-E—t‡»É¥°²0Î1 ©´°¢tÊ]î<̘4rîÊ‚ùÍ8=~ßíýæ\¤õ¢ytz¶AËQš˜`b¬D)L2rÞÔcEf\EùCÊ£?”˜yö YK³nǘ1-ñ°*…uµÞôh ä™³Û�¤~ã¿í¸€cç¡tó*…\Q†ÊÝGÒÅÃÐ÷µ¼ZqÏU—^KYÑñ_5vGemG¹úã¸ðÞ"¾íU.s Õcã××—”x¤Æ\d¤öc2À5€Ïºzñ ·iÌ{¾J.ýs.c8=–Ý;£±n÷)½ª˜c¤´¦ö�Ñ´±JGÇóa~ƒä|6ÉŸ O‰˜=šíµ¦Ô¤L.eHÉ�œŒ\*SÁôçÎÞÿOÜŽ#‚ ò…|ûc~&”.0uk$1‘;X2¬9·!¨�/ ‡þ mÖ�‚.—§²Ì«2¹Ó¡“;¿¯æ��¨òÒù§«¶óø=<œðgŸ}¬éóÂì¹ö&¡Ó–qãý1 öÎõah¹õc åqt°§¬o~1ëêï†QI¯YQ åÈŒP(ŒpôoMõ¹¡¹DL,¸Upçù]( ÜÊ»Cü%®H}†„”rÒb8{\Ë»ç¸ÛÖ·�-+SFfÀx$Órÿî}(c…Õ+ê>¯Ô.ÙrLYïJ9'<¤zmÎgSÐüI>ö Ÿo¯Áô &¼x‘Dæ7ôÏ #kl­àÞ½¼áG9 ‚ ÿ1ЇÅzÏ#§¤º:Í»W§y÷¡ íGƒÁ3XÝ¿%_Úª°•= áÆSÈöx´7¸+³ÃÞVž£çöéöÇ>ªuòÂH»ç¥%™;âîáÁ높ÎeVx†í{‹|ƒÉ±n3Ÿ_Çú¢”SÊÆ›’ʼ–ïrd”±,“�‡‡¼0°“oÏËÑèò;ÿb¨x^.÷ù_åÕy8ÖS†LfÌ»s# íc—G9¯o ¹Sz¼;�/6ìàNë&ìúi7ºæ hï _ëå]ÏúÄ\8’¯ÄrGœ wr)+iƒM‰Çܹ—‚iÇÉüÖ8ã߆ܿQ kì²?ÍQû€ØË÷0)iÌíó1ÜM÷á�"<Ï}³^×87d²|>¸([¿¡ƒœ£ÏéhÓu`è[[^¡Xçjê_¬YvŠŠ_¬¥kU+ä€e¥NŒ´�ª“¾ãÏ/üh‘Ûƒ‘ò� =b.úåê+ÿ®Ó¢Íõ8(Ÿûª|ç¼’O0÷ó_𞺓&edäk¾rC\!‚ ¼òÂ~ÙV»víh×®�^¿I=±œ¾F²éFö#9VåËc'KäA¢¹Cmj—M'box¶×‘=áðþäªëP÷…™4¹ª-36Î#Ð%Ÿ‡ é1¬ž²E¯ñô,W°C¹™ WWʹ¨ó9 ¡o9¯8S¸áY.D_Èö ¢cÀÅ×Gh^u¢+¥…^®pñìÅl3FZnXÍüÕ2®:Ð7ž“cimîr7—`)yˆÂƒ îpöä™—ç¦Ý‰'áInGº¯9t–ÙкG+LlbÛÉŸÙø§m?ÔsLR=ë³�ioðëÆ?H­ÒŒwírnKºG×8}ŽøÄ|ÄaìM­jpòÐñlëõ”ˆƒÇ‘y׿ùÅM©œ[þ οÏê½Ëð�ÏÇËÎRÌÞòW¨^Ùê›ùdDÚö.Wá ‚¸ËWŸç³&†ô|(p¾÷\ÕiÐh ==g}hÓÓA›.ý9Râ‘s1T?fd‡½܈¿ñ¼¾4ç9ýª÷�æÄ½ ù“vb#Ág®°e înn¸¹yÐhJ)±+èX±“§å/7´w¹},­ò3‘!‚ ùW¨û�ü H(]\x'æGÆ œÊ–ˆKܸ}“ØÈíÌ ZÃ9Ûæ´ðV‚¢}†¼KzØx†.ý�31ÿ¾f$_®O¦á°¾ÔÔó\_ûø6WãâˆËþ¹šÀýÈxÚt¾�mÆŸÖÊõ�i‰7¸ÇÕ›Ñè4<¼G\ÜUn$ÓÓEzùr/x:‹ÿ¾‹ w�-cê�7¨Ù+0ÇeÝJ J&�`ïþ‹Üº•@lt'¯<ɘW‘RŽ¢½ý¸¿a s÷Å‘”šÌ­?2~ØxÖÇc.×/ž &˜ë¸wý*�’“INIE£×ñ¢ 3¯Š8iÎuáåQ IyhäNç�’ºi2“¶]æ‰VÃó[ ¨GË pžä²Ô×)ݤ;í¬ÿæ§Iˆp àÃúÙïõТII!99™ä”4:Ц§‘’õÿZ‰õlÀ˜¥æ|Æöu™óÇv±bX¾øCEÿ‰}p{aò9y÷XÕmĨíõŸ³“ÛÑn`ØÄ„ÐS\»u�ÈMã QÐap{ì3{»'³4û.šLS÷÷˜º0€Û³2óïü\ì^„žîd°›6µ's¬°º=rãµ}‚’ú Oüý�¹2ŸïÏÜ'åé /Yȶ»úÏÊÿ+sÕØ—ZZrlÕL6ŸMDC:�/mcΪ£X¼×?iÉOHJJ")é Éi:tšž$%‘ôä )éã‘3`¸\Õ¥ò áÅýò-’Ò1\?fäÊ»ï:s=l9!ž ÓÜ#bÙ¶Ý}ùʘç|6ÉeÍ1ìŽ<Ρg·›î'd¨7Æê®,ßʈêJ‰¹‘Súå(¢Ÿª(ïeñß¹�MA( mP"¿2‹Ì[EO«p¦Ö§j…«Â¥î IDATÊÔí8�Ý¥»ó¿Ði4- ÇùÄLkÄ�UýhV¿)½ÇSwê&V~XVÏÓr;d>ÞÞxgÿToÁÌci�|”E3vSö“1´±yÕ®ZÃùe�©áíM�À•\L�eM÷šx{× ý·Ñ/ÝOZ<áÖo? µe{ßZ¸8ºàÛw+–C~bí@�Ï10i0„ íŒ ëíG¥ªµiÞýK¾;ž˜y0%¥#\û®&øó²„�j‚‡º,5»¯"¥ÓjBÆûQBÏxP–§u /w¾mŽ‹½=öê†L×ói˜Š*Íhl{‘={/¿4s$5�z¬ xr5¢&úãáàLõŽs‰k0—à¯ñâ[FódêG�5'þŠ¢r�îTÍ>¸–º�QU°··Ç^íϼ³ÉœøºŽööØ;TçË¿R‘VφŠYjÎgn_Õ|hÐn(kâk064ŒIõKøÀW†E‹™ϬÅùií©YŇ޳.QwÎFf¶È8ÈÖÝÿ� �ÿ‡â“%|Q»$ ìÁ¾ cÅ ñì¹[|/_N;ý'G– þ ¾T/´Yié¹ñú>A )Û»’#—3¥þ5f7/�K•6|ó(€a-Ë KKÓã¾÷i®Ê,xoöføßbAû*8©ÔTh5�Øúsù¦5–2 =šyÍ]P«Õ¨Õ®ô y@ÊžáTT«Q«+1|OФx¤}'ƒÁrUs–ÅkäÜ/×ÀÆÛ: ×�)©1b }c˜ÜÐ —ªmY˜Ö�Oš¼ƒL&˱^Ïy16ÃÖÞ‡ç[s%2Ei¬íí07AZnä åÊž]œµhLÓjù¿‚SAò#ãØçþ}É?8rä-Z´0h <0hy‚ �†æøÓl½›þœNÝ\B)oZ:1ó[Ð`E~8²ü�X ÁÛš«Ùßµ‘ÈÆîoý=g4}í³¦þ5’�2¡aö¶ÙÁ¾ñÕÿë,‚ â¶Aá?NA…éÆ:&-�þO=W@x‹èîqäày<{¢ñ[s’'ü'½…¹šzt2u�ýþK,OÒS¹õ×bVýYŠFÍjð߸f �ó+'ñÝÓŽLø¸š�AŠœ”þódf�˜0ÿC/ÊüOßt8‚ð²äcŒ©Ï ^‹ê¥‚�?oa®×ú”¹ŸWáÌØF”S9Skà^Ô#V3ýýÿƳ’Ï,fèÜ[tœûï½|_‡ ‚ :qû† ‚ ‚ ‚ o„¸RBAAA„7B J‚ ‚ ‚ ‚ðFˆA AAAAÞ1(‘oZ®¬jO¹Zc9(ž�ø\ÊÏôQÙÒl~ éo:©ÞƘ…7ïáFº©,°°°ÀÂBEû5·Ð½é˜AAá-Sl%t÷#X9¢-~^NØÙØâèáC«Á‹9tG›ýKD¬Æû>î8¨ìq«Ñ’!ËŽrW—õçŸPY`]sG³Þõ¨½ÂòÖ*,U�øþ¶Ò/°Àß6óÄ"çÇÊk8¿¿â‘º»™=/ŠúŸ§N Q3`óR96Ô™‰^Z–¥•-jO_Z^È�ú�KªŸ7AQ�>sçò™¿Ý›K®gõl‰¥µ 'Ïš4ëþ%kŽÞÎ}С8Äü62`>K¥{°‘•‡°»8¼»Õ¬ß]I áj(}ÅëAA!?Šç9˜î.a£ºtÔ•Ï6$úÂY­ûuÄz ᦠ�ËkûÑy|86ýVð[øV¬æÈ¤Îô^“1 3ÇìÿìÝgxÅÀñï•\îR �JB-š¤‰( ]4 Mz—*¢ˆ "UTE:R”?  ‚´„*�P„Òïnþ/’À…b.Èïó<û‚ÍìììÌÜqóÛÙÙ¸,ú+ËñYrÄD�lc-ž-§³32’H›-bÃjÜñ…Ýiì�ú +½{1¬™Wæ+Ãô”굄ݑ‘ì^Ø�↠ºÌßEdän~êWÆæÕhZ<[Í âÀöGncÍ´Þ”8ð9m^›À¾ô¼¬Ÿû ,˜-÷˜‰.�ZmÛÓ¨l�|~•šÏ–ÓØ±s ¿ÌÁ+þàƒ—óÎo—o¿›ýÈ”ùºŸ6ýW÷ØŸï±<æ»Ø›zï¥Í[Z� èþ³G!„BˆëÑ J˜�ð÷ÎB[ö¥ùÓþ.X˜€*ûÅúÖö!Ý ¤ïfæ—[0¼:š/zÕ¡|ɲ<ß}2cÛº²ýëïØ–5pÑ— nmkÿN"f,^F\µZ”Ðe?¥ÖÅÿ€l6¿ÂïP<ë¹E|ò]<-†÷ ŒÃÍý}ðÀß»z�žÞøãS0{dCë\˜"¾¾ø-FùÚ]øìÖ<¸’5Gí¼»lOý¨+lÿ¦�ÂJàWÄ— òµé4æWÎØ ­QSiä[‹±ûβ~T+ª–ðÁÃ݃¢Ý–“$þÖŸÒÞÕø8œ­–ƒc©åBŸµ EŠø˜jžY³Cîò(„Šg÷Ì·x¥J)ü¼½)Zº&mF.çXŠmšœËl/­‹'þA%)_ãú½Œ‰�â™ÿÁtög^Š]e¶^dóÄnÔ­P ¿"Eð©N‹á?ÞRf;®Ëz™mS3¯ËÇ— rµé8úæuÙ[ÏyѦ×׿A¨o#¾>™}V�õüLš ¡÷/×rWÏ9ôçœÊcOý@›Þ*�ÏKÓ9si>­¼3ÛÍ«SNØ´ZŽùäM{ !„B!ò†ö‘¼Á§  Tq=‡V|Çš£ d �4¸UïÌ[Ýž§¨¬çþfûY=UêÔÀõÆ�NT«]cÌvDeT”–²M_¢Ðo‹ù-v‹—§R¿Q…û¸#žÀ¦ñãÙö6o¿àšsr;h4@nJdGý€•S3»óÚ—×h6ý/N^8MÄ¢ž8.îJû‰{É[i‹„âz”u#úóÉñÚŒ]»�ã'³kl=çZíiQô$ËýÍÍÔiì^¸˜ÃE[Ò©vFè+eóÙ \8ûKßñ!£<§çt§Õ¨¨e¿:¼L‹Ê·>“aåâœVøøàscó£î¸ƒ·Ý9O?8�O–¸Ò}xüî{ž‰•Ä“¿2fô�Ä—}™&¥î<0¾�õƒå0KfýEP·‘t«ì‰=n¡­ñzEŽ,ZJä�¬'^îföž+Çg_÷æùžtóÂÏË%cXéX™¶­Cˆ^¾ˆ­I™Ç$oeÁ²³”y­=•³ª_£ÇàhÄèèˆþN}Êò gl¡`ÛR¿$.ð­Ü‰Ï¾ûšÁµ “®rQæ{¤÷ À‡‹œ�±ØWfI11$hM,hB‡c‘ÚŒÚp˜Å�‹fL3²çºÌY4ëo ·ÎÏúà¨qÀ½Òë¼×!€C‹–i¶³žóªMÊÒ±û³œ_4‡ÍYçJßË P®CG²¤rá.ý9§òØS?€VïˆÑA ]ÆcÆ[�°'Ÿ¼j/!„B!DžÐšò8(Nxx¸ÝûïÆ!¨)Ÿ¬Œähä¾PߨŸ^…ZoüL´5ë>¬ºÃj÷ …&ónm&] š·(Á†é‹pjÞ‚òú[�ÑâþÊD6lÙ–Û&fv)N¶0�5†?ý†è—†Ò»â›°ƒ•‹óÚì營o«ôàç]˜1{eo+×ÝåT?˜�søD*{>ª‚Ç�E7Ý)?äORÏGq:k`¥Ñ¡×ëð«×„§Mw:“ŽÒmÚQ9~5?¬�G¡ˆÿu>?ÇW§ãk¥°3ŒéGùç+]"Ûú^UšÓ¦Q9Ü4¹(ó½²Z°¢Egw¡5x¾ü&}ü7Ð㩲ÔlÖƒa“~`˩ěýήë:ÁÑSP¼L n>í£§xépöQ©`W=çY›jñkу¦ÖÌþå Hùk>Kc^ [›âö·)`WΩX}’$«™«GV2¢Õ³4±…¤œO“�k�v„{ì`Á Ùéߊ5mçá[1§¦’’’BJj*fVK:©Yÿ¶ú2´ê\�¸…3aÓiÓR¸¸gï x�N(¨%ϘѦ'9²ëW¦hÍ»}è1² Åuv–™¶­NÅÖ“ùûb* EÚ¥Cì>r �âÅ(¨±óºôehÕ© W�æ«—1cæò®oød^4•:µÉö8Ñ¿Ös×�¶hKz4¼È¬~£ù³lg:T¼×;÷)õãP¨Ή{øßïǹxñ§í$"*)cöƒ=ùäq{epÄÑ ¸rþ ))¤¤¦a~o_B!„â?(«<<šB ø|ù |>™ÂÇm¦röj:z·Ê=׎oD]W-¦³$}$ïÝ�?LÆÙ¿M?YʇoN«·‹•Ø%=©¼ä–Ý:^_¹‹1a»™2æ7ûnàeÏ»Ý}6sä›–¼0fÿ�;°ÇÛUb&zJZÏ–áó¬²í­ÿöÓY”:‚FÖ£d·$ ž¥¨Ñ|‹Þ}§ÜžÔX�ö­Šòý¸„}4� ¶ã×´M ªÐ’ÙmîÖ�z¿Q€¶Ý–G0î9ź}Ï"Ë>T‡É§Ðy”æ…vß³ä�jd ½ó²Ì™mºT‹ÁÙ“b•1ìÇ¡t¯æšq¿Þ®2yvø †¾7’~5'r&ÁŒ¾€?aM†3gd­Ìà”ÎŽëÒQ¼û ¤ çƒnÏ0þrŽž¡¼Øo_¿^2ûÿVÏyݦš‚ÔëÖ—ŸæSíãæÛ ‚í¯Ççúñ~x/Fw®Æ ‹‰B¾¥hòþ\Æ:¡±+ŸØJ…·ÖSMB!„Bˆ|�o¶…ùD]d~Û’Th9�äÖßðUÇ@ù"B!„Bä ™)!Ä“FãM§¥çè”ßåB!„B<ñä©B!„B!òÅ#3SÂÍÍ-¿‹ „B!„Bˆ‡HfJ!„B!„"_HPÂVü<^1iÐh4h4FêM‹Fåw™Ä–Êê.î85[Àõü.J^“þ ©Kie2Põ³ÃXò»,‹´»B!„xŒ¨?m_¶²iϪ9æœC~0ïý›=y7y2ûs.é‚©Ó98¿KH» !„Bq'�Ím´åË—ß&7|ƒ‚²Ù<0å&�ë‘|ß».e¼]0œð(Y›Þs�l›&ù³zÖ$ÈÍ Wï²¼4âgõ¹élâ²f XcØ0º U‚Üqqr¢€O9½µˆ#w´$-j�Ic¤éì¸ÜOöžañÔ•:ŽãóÖax¥b‹Ñ|ÞÉÈÏ_/$Ê ¤îgüó… ìð#17ÊwŽZùáQw2‡²î쪫ì˜Ö‹º¥½qqtÄÕ·"M/áHr.ΕÇt.ø-JQÿ`Bk¶ç³O^ÃãøÖþcÎ,óeþ˜Ü™çJxââäL¡ÀÊ´ø`5Qé·æt‰�‡SÞÇ£‹/•ÛÉΛڶ^bë¤Ì|LÎ ¨Ì«#oÉ'Ç4i¬ïí‹ñ…)DÅΤ‰cæ�nCuÆ»‡‡ ¥þüФ²¢½¾=fóóÈæT-_ ʆ�aË•›…1ïNY‡¬™wy|#§þ öÕOŽŸeiw!„B!îFû¸ÜH[¾|yÞ&ݟµ£Ïj/†l>Gbây~ìÎÊ^ݘr8kpaaÿ„NôYYˆA›Îsõì&†š¾cÄ¢”Þ}f…'¬L»/Ó鹿$ñI‰\Ü5‘Ð-o2pÎiòtìžÉß*=[ ã��FÂj„¡‰ü›=©€c9Þœ=�§ÿן¾ ÎbÅ©™½øgu&ÏêO€•Sßµ¥ñðƒTÿ;'/]äÐO½1-î@ãÁ2Öc°ç\˜Fh´ètÀʉo^ãåññ´š€+IñœXÕã¼64½ÛxBÚæ)ÌÔ à—ã—9ÿÇ7½Mû�·“�±pô«V4uš3"¹œt•£KÛ’<­¯Ž‰ÌÌÇž4êL9Iô̦˜ wdy|2ÉÉÉ$'üÎÀâ:¾¼ëÏ“^¯ãò²q, ņ}Gˆ:8�ªÐwò^ÌYiÂ>dÏõd’¶1´ì�&„ÙÑŸíª{>ËÒîB!„BÜ�Öñ1úq™ÿ� =†næÔîïèR7ʶmA5µ�]û3‡¸–¬YuÏVƒèù”:Ož4‚žfd>¾ HŒ¾À5­nnNèÐ`ô«ÇøXÝ3à¶é+¦FÙµo7_½R0×�?¨ë±\JqÅÃÝ1ÛŒ ƒ»Rc‰½–qËSÔ‰o§5$bP/¦¯û’ÃŽÐì»i´Íz&Ýr€9_oÀ­ó>hROׂ­Ú“/ÌbD=wÒ•ýçzPR£·2~ôRâÊ6§iˆ,™?}+Åz�¦OU/ è)T¾Ÿ¾Æ?s°Ë&*¡)øׯßّ»3¬S N­ú™}fÀ¼�¹ÓÿĽãÇ ~ÞG�UÞ`T÷ öÏ�Ïn{ÓZ½#F-ht8��FŒŽù5Í>¯úóC¦J´cX§Pœ­W}šÖ0plßAnLNÐè181ï<€¶£?ÛU?v~–¥Ý…B!„¸3­é1ûuy?� óÞ�©ìœ9 ÈÜ Ôþ‚“¹˜š`�ÙÊÔ~ )ëï�—·>Å{óKª‹93ë9NŸƒ€b7ìp%¬¼Ñ& Þ¯a`à:Ú÷§b½v 3›�'®ßññ MBË…àvOÛh #¬R%Ü3J¦² -4x¾4‘™í¢Ød(±Ýf3®¡ûÍi‡9pJ– ±YˆD‹O�6t|¹"…néGÿ~®¼b%zFS »¸àâbÂ5°)³ô]˜¿tO9æ£:–ÂÎaelÔ8`3)çNf{ôB_º{6²î·ÿ±aÝ(Â?þ„æs61ãUß<[ìCãâ…—)�ØK)_Ëõ2öÇÏ¿H‚É Ÿ6Ák'Ž_ÆÑÅÀÅC‡¹d©†³M])u÷¡V®Î•'´x¶˜Æ¦�ª·¢/�†_|BxpÖ0*c=�¿9ɯ¯ù÷°ˆN‡;ê;B)šŒGFî;Mî=Jý9ohÑiÁj±dËÝl6ƒ^Û¬‚û­Òœú³]õÃÃû,gùïµ»B!„x’iïa™µ|Nxxø=«qô ¸tiJÛl!…lîlç i7ÛöZy¶Û€Œò@ú¡½üc{{V烯�âüéó7Ö3"òÀ- *X’HH6àÖ˜.ïŽgî†VöP,žºòæb“™Ôµ3Ü�ÓWï!‚d£z%صu‡Í"vIlß¼MX Ân¬ØŸÆÁ/º0èP3ý=‡F{ߦóäÜx{¡CIBKÀ‘GlîF[9¿a*c¦nà¼57çÊ;º‚¾/Q’§óy�†vKDÖ¬}eKÁÁ�‘ÙðK�=͹Äìui9u”“7.ÌBÔñ(ðÂ_—qíeŠÃáý‡mÖ¡0säÀaT±Ò”t´3�­ Ûé‘êÏyA뉗Ç-çÂÌ©cQ(?|òrtoO¶§~ WŸeiw!„B!²{lÞ¾÷�ÈG ŠËgOs-%…”Ô4Ì p,J€—âÈŽÝÄ+H=÷¾­+\޽œ±¨�®$õêsvÉÌ?’ˆ2_fûä±,¿d» ] ›Þ,GðKŸñgL* EZìvŠÇ³TIÜn¹œ¼f •ʇÑwE|îïSj‹Ðò�Ö0ïÞY¸‡31gؽà-ÞY §õ›­ñËì‰Û?¦ãÇ—é6ã3”jÊ„ïÚsñ£|øWÆ’èËѾgM®ÌΧëOq=-™è�ß3¨Ç æœ0঵ÿ\$ýL'¡Cù;íÖBßm �¦N¤þ©Oè4r+ ºÚõ®KêC²ü8‰V3q‡–ñNã <7x#‰YÇ*…åÔb&ÌÜÏ5«"ùØBÆÍ;FñW^¡œ>óÚ{ÔàòÜ‘ŒÿëfÌ\ú{2ïÏ8OÕyÊÞ4™ … ã|}'ëÖ%:æ'öog×ÉÄxúA÷çL÷Û¦ú24iR‚‹‹>fÔŠ]>vˆm‹ßãýù)Ý<œòv¿ÀØŠ95•””RRR1+°šÓ2þ�šŠÙŠ}ýÙžúÉÅgù?ÛîB!„BÜ'g÷¶víZµvíZõ°ýôÓO÷qtšÚòf�r|êCµ×lOúkjëGµUQ“Vi@¡UÃv¦+¥,êÌŠ�ªV€›r+RL•«ÝKÍÜwN­XA¹¹ú©ÆS)³RÊzu›šÐ²¢òv2©‚~UóOש™ +S³êzæ¬qÛÕ—]ŸW!^®Êd2)WïÒªÎëÓÔΫÖÛJ“¸ðUeÄQ½4늺ý¯ö¸®öÎê£ê”tWFƒIy„ÔUýfï¿Y–ËëTŸ7UíãÝ*Ùæ˜mï…)×=Õ/±™gµ^RL/顜 ÊÕïiÕ콕êdªýçÊ’öÇ[ª¸ÞE½85JYîå’̇ÕgUU‘^¿©›§·ªè¥íTQÇâªç/—2êÊzEmû²›z¾¤‡r6:©Baê•w¨7 ”¢~j[@|mŠZôNU¦HAåäꧪtž®"m m‰Q›Æ¶SÕ +gå\]µÿ|“бä2�RJ¥ìWÓÛ‡©"Îz¥7P^Å«¨ž‹Î梽þ¬T´©RJ%îWsúÕSe¼�•ƒÞQð«¨^zg±:r£c¦¨U� +Sø|• nÙ×t¶ŠSJ©Ôuª‡·V‘ñ¬AöMë§úlÈì19ög;ëÇÞÏò´Ý…B!„¸šÌ „ÝŒíÛ·РAƒ¼�ü§Ø®Q•yáEyÛsg¾m€!?‹õH°pø³TœRŽΠq�ü.�ÈYNýYÚô¿I¾Ç„B!qº¤| IDATăõX=¾ñ¸Hûs(å –¥ç�'H´¤ýû¦nráÅFÏØÿÜ÷™ºÌ›ÿ¡LÏÔ—Áë#Ï®þ,múŸ#ßcB!„âa� Ä`¨>ˆ©ï?EäÀ0  PºÃZü‡.bR³ÂäŘ��äílþçô(�Ýˈ|cW–6ýÏ‘ï1!„Bñ0ÈãB!„B!„È2SB!„B!„ùB‚B!„B!„È”B!„B!D¾� Ä)•_sÁåµIÍï¢!„B!„xb=A ËÆV3 ÑhÐh4hµ˜ R¹Ù0~<–’ߥûoQñìžþ:µC¬>«ê¨ŠôúM¥ÚìNYß[ù*¨‘é;¬—ÔÖI�TÍâÊÙä¤Ü*©WG®R§Òl²D«ÿ}ÚZ=XX9›LÊÕ»¬j8p¡:œl“ÆŽ|,'&ªšNO©÷D©_†7Ve<ŒJ§A[,RIJ©„Õ]UC¨¶3=û¥ìýP=eðQ�VÆÛ_æÄHõm—ªª¨«I¹x–RuÎWã^uVÎm–©”[ª*qá«Êˆ£ziÖeÍm=[¢Ô”ÚN*°ßFu³:’Õ¦þAÊTk’:iQJ¥ìSãjRí—©è¬XΪ-}•{�Iê`ª�ù<Ži„B!„Bd£ÕäwH$i4€F‹N§¬œøæ5^O«ù¸’ωUý1ÎkC³Ñ{HÏ<&aÕ`Ú}™NÏ5'‰OJä⮉„ny“�sNc»óÑú…RÆõ0«ÞéÆûGê1å�(.]ŽæÈ”F—º]y-à?ÌýÓf݇4þž3�ƒméQ¿€�ç21¶ý×ù1b[ ñç·1>t ß®MÎû M‹äï •ž­„ñÆN#a5ÂÐDþÍžTÀ±oΞÀÓÿëOßg±báÔÌ^ ü³:“gõ§ŒÁÎ|Ç4B!„B!²Ñ:>¡Q‰Ôè­Œ½”¸²Íi¢ËAæOßJ±Þ£éSÕ z •ïÀ§o„ñÏÜìJP$F_àšÖ 77'th0úÕcüŽ ¬î�ñ,Œ]ùZ/|<ÓÙs¶"_Ìz“º¥¼p+ä�¿�+ÇjtîÊù%sÙ˜˜yLÒ&f-�o!„B!„ ¿fÍï"<,Z<[LcÓGÕ‰[Ñ�—GÀ/>!üÆà\ƒFcàÅoNòëëEî:ŒÔ¸×aÔ–(úìÙȺßþdžu£ÿøšÏÙÄŒW}ÑÚ™OV™ ¹ºëj£ÚÀ6t}qoÌYIlx}VÏúÕø[ZÍ:ÂŽs¥)”‚ì+-Z°X8ükárMãâ…—)�ØK)_Ëõ2öÇÏ¿H‚É Ÿ6%´Æqâøe] \7üË`UãEx×W0nø�å»–2oSAZt‰ÂY‡Øs.­/E}§ŽGaÎJ`>ÌþÃfîD];ÃÁý9}õ¢U†0ªW‚][wØ”'‰í›w  «A˜cÖ¾4~Ñ…A‡š±èï94Úû6�' -7ù<Ži„B!„BÜæ‰|û†åì|Õ¢ˆ“ª0x‹º–±G�ú®±rw~Jõÿ阺nIWW.U*TÁ}Ö«ëJ)¥’ÕÆ~Áʽö'ê�èeUV•zq»ú¼¾§ ì½^%Ù��RʼW}ø”I…�: ÌÿVöä�ªpAUý…g”sèPµÃö­v�+MmRZм¢¾Š¸¬RÏ©-c[ª2ʹu¿}CYÕ埻ª€O«¾?ìV§£O«]ó_W\Uן/ßÈïú¶÷T¥BÔ»[”RVuuÃZði5ìÏ„\äó8¦B!„Baë‰ J(eUÑKÛ©¢ŽÅUÏ_.e ­WÔ¶/»©çKz(g£“*¦^yg�:pýfVÖ¸íêˮϫ/We2™”«wiUçõijçU›a§ùØ”PéjÏûå•^ã¨jŒ;r{Z{Ê¿C}ñZ˜*âdP&�ÒªÑ{+ÔÌ®^Ê©ùB•xKv÷”PJ©ëjï¬>ªNIwe4˜”GH]ÕoöþÁëåuªOˆ›ªöñn›Wg^WÛÞ S®%zª_b­våóø¦B!„B‘E“”°{ZÅöíÛhРÁ™¶!„B!„Bˆ'Ãý½bA!„B!„âIPB!„B!„ùB‚B!„B!„È”B!„B!D¾� „B!„B!ò…%„B!„B‘/$(ñÈJeuwœ^žÃÕ‡vNÅÕm“h_½îNè�q+ÚŽ…—ÕC+Á“º”V&U?;Œ%¿Ë"„B!„x‚‚iûRÔƨý�Î�TÅÍ£Y@W~IËï’d2G2±ç»¬uêÈì?rôð"6�¥¡›Æ¾ã-G[Í€F£¹mÓùôä×\^gžÖ�¾½¦~ÃðF>�@§·rròó˜´„Û‰9¿‹ó°%íæ£ªÎ˜îpK:´€� BñrvÄT¸8µºOgO 0&„B!„¸�>¿ ð$3ïý›=)9¥²3 �’yÌDƒ�Þ奧M÷˜‰¯vóØ:êYlöjt®xr—“}õs eÁlÕ¢×ÝRoº`êtÎefˆå0 çí&¤úSœZ¼€m#+SÓ1‡cîv]¹M“oé 8´e _~4ŽÅ‡ÒÁû©.¯¢“üÓb¿Í¨A¡˜õ|Ô¡7í?©Èž1UÉeB!„B<âòÿ¦ñ£D]æ�É�y®„'.NÎ ¬L‹V•ž• •íÝðí1›ŸG6§jùRø{øP6| [®ØÜÉM>À¬ž5 rsÂÕ»,/�ø™Eýƒpn:›8�ÆúÞ¾_˜BTìLš8fÎ(0Tgܱ[frèâÙöy+žöuÁèìC…ãøëj.ï[/±uRæu™œ)P™WGÚ\WêÏttÓ¢)ОÉñ,hætc†ƒCè0væòV¾ÎÕ›À  ‚l¶@wŒvס}õc=9‰çœŸæ£ˆÓ¬y¯ ¡ž&ô:=®m–�œ™Æ¼k8e²flÜåñ�۰ưatª¹ãâäDŸr4zkGr4Ì‘ ˜¨]§  î•¥Ìß’œíïö\—=i¸É÷½ëRÆÛƒÁ �’µé=çÀ�¿'¬éNQçç˜xÜšýüg§Qßµ�VÄgÛŸ´¨&�‘¦³ãÈõ¼…ôͼ]¾u¯ÅÐi“Ã]ïn³plæ§,ö̬ÑÍ©XÔ‡€Jí™y…}�B!„â?Iû(ÞSÍVN|ó/��§Õü\IŠçĪþ絡Ùè=d�Oõz——�cIà(6ì;BÔÁéT�ø€¾“÷fN÷°B'ú¬,Ä Mç¹zvCMß1bQ Jï€^` Î”“DÏlŠ©pG–Ç'“œœLrÂï ,®ËV*Ë__3õj{~Ø{�3›‡PtópzOÞ—‹u,ýªMG�¦ÁŒH.']åèÒ¶$OkÅ«c"3®Ë± 3b’I:?�†&oº­ŽÏ(Or2×#>¢Rϧɹí«­_(e\³ê�n¼¤SþˆâÒåhŽLi”}؇칞LrÂ6†–½Ó…Ø×î «ÓîËtz®9I|R"wM$tË› œsër½»4¶Ï_HTÕV4«Ø„V/&²|þÿ¸n“žëÊ9�™ÝŸµ£Ïj/†l>Gbây~ìÎÊ^ݘr8£÷¸¾Ø�nÅwòÝŒÝÜŒ¿X8:&[}ÛÓ«aÁ\]Ù¿r¨É¸# Äî_×½«á¡»CÇÖ�û¨À®÷›S-$˜à²5i÷鯜yTqB!„Bä)­£D%2X2úVŠõMŸª^ÐS¨|>}#Œæ.`WÖ¨M”hǰN¡8Z¯ú4­aàØ¾ƒ¤XN°fÕ<[ ¢çSnèüðeJ{¸âY©']k8yónwŽÌû˜;ýOÜ;~Ìàç}qÔ8àQå FubÿÜùì6hqptÄèè€ :‡Ìò�8ô¹|€ÄJô·�)`¼™‡ÑèB•Q6�”œêÐÞúÑzáã™Îž³ùbÖ›Ô-å…[!oü}lîÂkô��Ž™¡[ØÕîŠÄè \Ó:áææ„ F¿zŒßq�Õ=r7Ý(éwæ.‰¡ækÍ(ª+DÃÖõ1¯šÏZÛÙ/ö\WŽiôTº™S»¿£CHAÜ(Û¶ÕÔ>víÏìÌèÞ·gç~ˆÄÌ|Ó÷0{Î>*vïA•[)15šÈ®}»ùê•‚÷ðP‘ƒáN‘–sD�Mãü¼1,.Ø�ék7°|Ì‹ÄNmÉK#ÿ²¿Ï !„B!Z“%2˜�rèX ;‡•Ac�F�6“rîd¶©ü:¿ünŒ¯4Àœžq—ßzŽÓç  XÀÍ;B +oä^è‹•¢Ø�Œt˜œ 7Ïe�ôcüsJ• ±YãAOÉÐRhÎãÄ=<~ðï´x´œÆŽˆ"nl»XÜ«¶CÒ­C{itèõ:ü…óŒÓ=×®v×àýꮣmq*ÖkÇÀ1³Ùxâz®cHX?�å×êÐö4@Áz­i¨Y˼U—næeÏuّƳ•©ýRÖß/o|Š÷æ—T+sÖÜ-þ¯õ£¹u)ÓWÄ¢€ä-3YpáEzw,É­!MBË…àö žúJ'-ÝŠ¥úÛ|;¸1‚ƒ©Øtß zŠ£³f±UfK!„BñŸ£½–»¹çÿak¼øÍy¬J¡l6kÒRZ;Ýšú.”ëmuª�Ü?…Ÿy¨æ.ü¡Aó‚Rz7BJ—¦ô�-„ �ÛWrÌ›Sk)ä^è>êȾv׸×aÔ–(Nm�Á›/úpé×Q„—£ë²óö?¾¡.³zîÏÄ^_Gß’…pssÃ- #ËââY?o9²u{®ë_ÒX1¡M&Ÿ«Ã×Û£ˆ‰‰&úä4šÜÚ Ò·s~�þ§,ñ¬ý~–W{ÓÜ;¢•Zw¼Üõ¸úÁõæ”üKc¸ÃÅ<  !„B!ò›öÑyAf>Ó‡P¶Ü™mšxzìiÎ%æ"r£óÁ×Gqþôù›�+˜y õÎéÕ~Õ¡CIʇÃûÛ¬`æÈ�èb¥)™Ó[ò›]õsh{ÛÝ’DB²ß°Ætywm{oÌ"ÙËžï_ÃeË|–FÝÚÏì¹®»¤IÚͶ½Vží6€|�h€ôC{ùç¶©(„õìM•ˆ™ÌÞ°„ïñ ãëuq¹Sù¯�áàþƒœ¾ú€"™Ú¢T©âÇ•¿ÿâè�rZ8sìéEñ»×Â!„B!YOÖÛ7TqçOqê”ÍÃu   ¡]ﺤþ0”!Ë�“h5whï4®Àsƒ7’˜cæ™t%©W/˜³K¾`þ‘D”ù2Û'�eù¥ÛŸ§7.Œóõ�¬[”è˜sœØ¿�]'ïuNÅ�éËѾG .ÏÉø¿.aÆÌ¥¿'óþŒóTíÑ‘§ÀKa- 1D�ºµžÏqå.q™»¹ÿú±bNM%%%…””TÌ ¬æ´Œ§¦b¶bg»§°éÍr¿ôƤ¢P¤Å`Ç¡xÜžžóá6î»~ÒÖÓ'Ð “Ʉɵ£$³ó½ ¸˜L˜œŠ3à÷4ìkw#ϼ�ƒ¥kOœ�œñ(߉5Á£X6ºvÝÀ·cѼm¸6iM]×[þfªE›p/",ä`^E% Ï1xJ_|Wµ$د8•;üH±á ×¹êÓôËlu£qﶸĤP¿W[‚Ä·‚e?£kÂÕÕWWwZÌ�#eMOŠººâêêOÏ5+]©~,Z1œ’[ßæ¹bE©Ðv>]~`ù{•yÔ'õ!„B!rO¨¸¸8»ؾ}; 4x@Eú¯°}ׯUæ…åmÏeœù¶†ü,–·QÄ.lM¹÷}Y²wµä1 !„B!ÄCòdÍ”xHÒþJù‚eéùã -iDÿ>�©›\x±Ñ3È tñèP˜Ó‰þûkz ÙDØ;¨) !„B!ÄC$A‰ÀP}SߊÈ�a6 t‡µø]Ĥf…óè�BäÍÌ—½ nôÉæò}÷`ùBB!„B†-WTfi¬ïí‹ñ…)DÅΤ‰cæŒ CuÆ»ùð…õä$žs~š�"N³æ½&„zšÐëô¸¶YBrfó®á”uÈš±q—Ç7Ôeþ˜Ü™çJxââäL¡ÀÊ´ø`5Qé6i¬1l݆*Aî¸89QÀ§�ÞZÄ‘ÜMsäæªD×)¨{e)ó·$gû»=×eO®Gò}ﺔñvÁ`p£dmzÏ9pãï kºSÔù9&·f?ÿÙiÔw-B§ñ¹¿8!„B!„�­Ü»¾I¯×qyÙ8–Žbþ#DœNÕˆè;yoæ£ êL9Iô̦˜ wdy|2ÉÉÉ$'üÎÀâºùhýB)ãz˜Uïtãý#õ˜òG—.GsdJ£ÌèÃ>dÏõd’¶1´ì�&¬X9ñÍk¼<>žVóp%)ž«úcœ×†f£÷�—HX5˜v_¦ÓsÍI⓹¸k"¡[ÞdàœÓXï�ëÝ¥±}þB¢ª¶¢YÅ&´z1‘åóÿÇu›ö\WÎiÌìþ¬}V{1dó9Ïóû`wVöêÆ”Ãa×ûÑ­øN¾›±››ñ GçÏd«o{z5,˜«+B!„BñhÒ;>âQ‰åË—³|ùò;þ-<<œððp;s²ýmc Ì´�¢§Â{ñ×{åÑh€íÖ)g¯ú4­a`ᾃ¤P@«wÄè �£ã�ýÐzáã™Îž³ù}Å›ÔpÊØíf›F£Çà¨�#ú;µ�å ó§o¥XïÝô©ê…0”ïÀ§o|Oé) Ø5ôiª9(£/pMë�››:4èüê1~Ç;ëÄFÒïÌ]CÍÍ(ª+DÃÖõ1÷šÏÚ«MhᦱÿºrL£§ÂÐÍœàˆ—‡3Z lÛT{£»ö§Cˆ*нo-&�ú– Ã+ÓÀHßÃì9û¨Ø}Urz¤D!„B!ÄcAkzăw <ä.  Å£å4vDDqcÛÅâ^¥ÐÙ¤Òùàwc‡ƒ£˜Ós·è£F‡^¯Ã¿Q8Ï8åæ@æ£:–ÂÎaeÐßX˜SGà€Í¤œ;™ù‡ïW‡00pm‹ûS±^;Ž™ÍÆ×Q9å‹„õóX~­m_ñA¬×š†šµÌ[uéf^ö\—i¬1[™Ú¯!eý½ñòöÁ§xo~Iµb1gÍíÐâÿZ?š[—2}E, HÞ2“^¤wÇ’ÙÚK!„B!ÄãK{-wsüóÅ­ˆÜ$2èÝü )]šÒ7¶‚\úuáåÃèºì¼ý�o¨Ë¬žû3±××Ñ·d!ÜÜÜp èȲ¸xÖÏ[Î…l{®ë_ÒX1¡M&Ÿ«Ã×Û£ˆ‰‰&úä4šÜÚ Ò·s~�þ§,ñ¬ý~–W{ÓÜû�¢ !„B!„°›ö¶ÅQY�ˆ{ Hä9eÏ\„û@ëC([ îŒÄv¹ÉôØÓœK´ 7X’HH6àÖ˜.ïŽgî†VöP,žº’;§K¨˜ÌýUKø´]ì½1‹d/{¾ —-óYukxÞëºKš¤ÝlÛkåÙnxÁ׈H?´—n›Šâ@XÏÞT‰˜Éì Køþ:¾^û.I!„B!Äcà±zûÆý$, 1D�:Å)Û-êWRs—�¡paœ¯ïdÝú£DÇœãÄþíì:™˜‹G&¬˜SSIII!%%³«9-ãß©©˜­€.„v½ë’úÃP†,?N¢ÕLÜ¡e¼Ó¸Ï ÞH")lz³Á/}ÆŸ1©(i±Øq(ÏR%q³+&båôÒ¹lrlDÇV¡ÙÞLÒ¢¯Ú΂ÅÇn3Ƚr,J€—âÈŽÝÄ+H=÷¾­+\޽œmv‡6 ýšÆ0½ëH6WèI·0‡»f+„B!„âñóX%î�•‹óÛS*8˜`Û­ø³|¸==çÃm8Öy›O[XÒ*ÿ Pª‡¿ÁôWíJ¤­§O &“ “k5FHfç{p1™09gÀïi€–À®óXýY%ö®†·sAŠ7ü”Sµ§²jlÝŒ…81òüÇ ù0øWºVðÄÙÉ�ò�X<Še£ë`²§,–c,š· ×&­©ëzËßLµhîEÄ‚…Ì«¨„á9Oé‹ïª–û§r‡)6|!ã:—"bXuš~ùÏ͈Æ�ƽÛâ“Bý^m ~‚z«B!„B< 4€Š‹‹³û€íÛ·РAƒT$!²(b¶¦Üû¾,Ù;‰ZvEY„B!„B<.ôù]!n§0§%q)b}‡l"lØvjJ@B!„B!þsdB¼xô¨hf¾ìMp£/Hî0—ï»KGB!„Bˆÿ ™)!=š"ôX{�ù]!„B!„”Ü€B!„B!D¾� „B!„B!ò…%„B!„B‘/$(ñÀ)®n›DûêÅpwr@ïèŒ[Ñv,¼¬r™æ —º”V&U?;Œ%¿ËòŸ¦ˆÿým*¸WáƒIù]ûHßBˆ‡ï ýîM‰MM÷z¯½ŒüJBˆ¼!A‰{¥®°ý«¼PÊg£%ž£ëä?¹tëÿPæH&ö|—µN™ýÇAŽ>@Äæ±4tÓä.ÍC¢®lç«×ëR¶H ¸x•¢V§ l‰µ>ô²d£¯D¯©ß0¼‘OþuZËÆV3 ÑhnÛt>=ù5-wÙ©¸y4 èÊ/¹<îARñÿcx�oqzû;†=ã”ýoÒ7þ…™½>…Ãm}Ã�rïïÆ 6ýG‹Vo¤€wIª†à›?/æþ½Šg÷ôש’ùýSòyºOÝÉÕ{ý…œ´›�ª:czyWoý›5–-ã;òl±Â FÜüÃxeÈ2Ž¥Ú¤I‹bõ‡­¨T£Á‘‚¾åiØ&‘ w.�º¶‘¥ 8”̶ô{,ó]ÙÑyìQü,ߟDZ?[95é9o+óíƒæ¤C Ø /gGL…‹S«ûtödõUË>>zúÎßóåG‘Õ�R�³âý–T vÇÕÙ÷ gh6d1‡“s{ñÿB]`FcW\êOãÜ­_³ê"³Iœ— IDAT_.€sݯ8�__Á�Äw¯�û³‡�ýÐøÔ ¾æÅ‚Þƒù劄%„"¯¨¸¸8»·µkתµkת'›Y›Z_r,®ZNZ§öŠTë¿l«J ª&ý£Òm“^›§^1TmJº{vö¤¹V³J7[s‘>V-jí©œÊ÷TóvœR—â.©“LWíJ9*÷ð9ê|.²Ê“òA%$dm×URÚÍ\¬—~V]ƒ=T�w–©ˆ3TÔιª[úî6•šYž´¤ë6Ç'¨„«‘jB/õôðí*ãéTõ×»e”±X{5çÀUeVé*nï÷ªM�£*õΟ*ïº�UÅÎo®ÜLµÕ—Q–ì¹ð�jä⪚|!ut§S<îß½ö|�Ù—O®úaÒVõV)“*ÿþ.õ¾Â„â‰#A‰{‘ö§TÂAùtþYÅߨy]ýÚË_9öWS”R)+U‡‚ܶéË U;ÒíL£”RÖKjë¤NªfqålrRn•Ô«#W©S6ÿZNLT5�žRî‰R¿ o¬Êx•Nƒ2¶X¤ìu¤mV‚ŒªÊ˜ÃÊ|c§U]ÙV±iKZš²Üõ‹:9½‘ò,ó¶Ú’¬µ^PÓê•W�u6ÿ¤ªÕ]Ü•±Þ4u!/ÇøW—©¶&õÜÄ6e´¨³Óê+çB-Ô—2O–W¿rìóv~÷ZbÕ–‰™å1:)7ÿJªùÛòØÙçsbÏ÷˜=ìé‡Ù˜Õ‘Ï«)£_Oµ.�ï' !Ä“�%rÍr|¼ªapRÍdÿ铸¬�*`¨¬>=hVJYTZJŠJ:?]54y«n«ãUrr²JNNV)©é™QwûÒÿºž*쮾أRUºº²w–jWÜE=ýáî›úÔuª‡·I=ó⋪Rˉjýáw%Z�¾pÍþ»(–Ójj=å\é õã?ñwù‘–GåIÙªÞ*aPÁ~W)7òNU*© %ÞR[³vZÓUjJ²JNئ†–5ÝáÇOÆF÷çÔ°U‡þÏÞ�‡ÇtýßÉLV!‘ BEPÑÖVº¨ZJK«–Ú×RÕV-EWºèf§–jíK[ZÔÚ_K«ö5‚¤"D,A²gfÎï�DL4˜‰¾ý¼žg<�™3ç~î½çÞÌùÜsÏUñW’Õ™]3ÕËþªÊ먫¶Ä|;V&%ÖöôPöî!ªûwGUªRÊtqµêíï j}–?ŠÆ”“©âçµUN=Ôª”Ü}ž‘™¥ \°ºÝ6Ì>¨>¨å¨‚GïµX£úçóúÊ©Úpµ#SÙ${çä¢Þ;PHoBÚ†ÕlêÄ)¥ÒWwW�Ô„7ï�±FuwwQ/.»Ràí+Ë^TÎe^Q?çý@6ÆÌS/øøª—ŸQ&eT1sÛ(ï /©Å§¯-Ǩ²²®m±Lµ¶—•?æM§Ôô§œ•W×_Ô•Â>7¦¨èMŸ¨g}¼Uë9' ¶•Ômjd�‡ÔÀ�‰êää&%š”°æ8½²º‡*ïû¢ú6"E•YeœýM½ýHyÕzöõÌí�åµÿ½šÊ¡Rg5ÿŸd•�}Y™ó’òuª¯¾øÇhC<ÒžoÝž3Õ/¯¸ªRõ;«¾ÏÖVþÞåT…‡š¨îãÿO�ÍOð'¨ï[—RÁÖ«e£Û«úÕT@pcÕù£µêÔMNêæøŸTß ªÛωKMêÄìVªœÿËjÎ�D•mÎQ—ÏS]˪³¢ÿÝA¿#©j}_åØà«ë‰Ói5ýigU¶Ûª¼LñýN°¦ÍßþÜkTQSŸRnžO©�ÿ<§2ÍÙ*a÷ÕÊÛYÕ–?ÂÊšcðöŠx»‘•í°À’�|¬ê:ª·þ–±Bq§pÔþ[I‰_~ùEõìÙ³Ð×/¿übUÙ;G¨ CõÚÅdo{[U6ø©!^ÿeNš§Z;•W~»y7ö–eŒ‡Õ¸‡�Ô#ŸEZüÑ7©Ø)M•SÕá×ÐçTï‡è•þ¡aj{šU«Qøº�X©†>å§œuÊë¡&ªÃ럩…[c¯_E)¶xŒ*|ìÃÊÁ·ŸÚpíêSÚ&5 ¢ƒ ýøÈ¿ÔåTï‡òãÇ®Æ>ì ªÛnñƒÛ¤Îo_¦¬S—Ì6Ä|;Æcê‹ú¥Ù”ƒƒƒÅËE=úqx^ݹ?Šì¯"ó–¡~î⪜Ú/Íë8亲øåäy‹!߷݆&uzÖ³ªtÅjãµm˜½W�vV ¾jMû)ádæ}š±ç3^_ý(“Æ·ÈÝö÷�[§Þ/�b¨ÿ&^©R‰:Í»2ôól9™jóŒûæ‹Û˜ùzKjVò¦œwyÊWÄú,3&cÁ o�´ç[·g̓®?]$ñŸU|ØùI®Q‹'zOeÑ;!ü3w.eä��cÆÔpߎlMíÀ@ê´ý€YÃæøüùl»a¢R•¼ž)sÏÑìõÞ<¤·ü$ƒ}Ÿ½@—Ÿ«ðÕ¾x2Œ$œFÝ?zÐjÌ6Rm_õ[rlÜ•Ž~GøqE$&ÌĬü‘½å;Ðõ‰¼h±�{‹©ÍçDóÏI¨R�ëNôWC;ÍÉÌëE‹åoe1»u;´`Wo/HJ¼D O÷,„<Ý•ÿà™ôÆ„- �·/åµËœ‹+øÈÄìóq$jå©P¾8ç¡Î�=ü™Yq˜•BY¼Ìé+èTà‡…wO÷b˜[G)¿Gx®÷;Lúq7a Ú�¼è#f…‹5�gú<“Ãú…kH0]ä—ùëQ­ûÓ©¢mk�;3Ê­~2ÙóíéÝ*Qý¡‡x(ÿU�/‡B–Zn³OK·dp/~›³ŒS¦6~¿ÓKƒxÑ»(K×,þ½y<Ò6ŠWFÌ ÎR‰€ŠÖõâ´Rå(çt•„ÄL›Éö};˜ÔÆ•Ìøx®:•£|i‹=h¾ÌÉI8”²'>ò‰E}n_zß½Ò˜öKÊòÑæ-Llåsþ3c6ƒ“w‚ë4æ…!³Xýi-¶�ý’�é@Æ>Æþ™Ð ãiq¿d$òÜ*Íói>ù;–SÛ¾ã­gÊ“øÛ'´«JŸ•qÖwBL‘LìÜ™)çžæ›Ý±\¼x� 1³yîß§ŒÛÆ#íÙÖölG`� ì¯\àBš�'å<õ¸–÷Á5¿Z•ªbŸ|‘øLËï*’Ö-d­ñYºµõ.¸_²ÿbÖ”ƒÔzc<=ëza¯ÙãYû>}ó1¢æ|ËŸê)ö�ðJ§ þùéGgE³ò§ƒtîJÃü6T|çÞbió·ôï 7÷ÃÁ¦v˜Ož¼!„ÅE÷_z¶´¥k‰[ºŠ�ihdצ-�ŠJcûïÛÉòkB“À"\"º}ujVƒˆ}‡°|ÒXNÂiÎ¥ö¡èÞ³÷M¥Ë³YgY¯Ž²5kâ£%s9Yoûý©Ù\Ø÷=ÃûgáI{Üt{̦«‰=uŠS–¯Øs\ʲ­{\R÷±é÷ã\¸xŽ“Gv³?&Íæk/:¿®¼Þö"sú|ÈÖÚèZ”¨Q&8¿œ£þÝ[’¶q{9ÉqÄž:Eìùr”‘+çOqêT,qÉÓ¹íç‘{Ö1­Þø?_�• ks™:^~£,Áˆå9sñ –¾Íˆ¥z:½Õ‰ ygõ´ÝÓãã$ú~÷-ªµeâÜnÄ�ëÎØ�×—+r2ÒHMM%55�Ì…2f‘–šJjZY&€4¶}ЉGždê‚Ô³¿Brr2ÉÉɤ\ÉÈí;4äå+°ÿ«�Œû5œÓâˆÚ:‡7ÇÿŽsóx õDz3æ8Gòoy:Àú¡8øõdÑžMŒ~ԢͦÿJO/; Á£ÙcsŶ}qk™üùV�m¾`ÇÅ,Šì„£ì�L¡lµ Ü,úu·<–*âWNµ÷) ²Îýµ�+$%$YõYÚó­Û³¾ÞÙ;˜<¤?_ýÁ¹ø3üéLЦÎÀþ42¨ÿê4<9�>ï¬ ü\<'·Là�‰áTïÝ‹†–§Nã?ì=˜AåЇ ìkìñâó^ìùf,ËŽ&cÄÄÕèU|:s'žm_âqËl1´g»ê�éúH4KFKXí®t ¶³ü°˜ö»5mÞÊsoÿF$-ú� ;1b$qÏÞÿ.Žúý{ð°þ6aØÄšóØu†R¯V(ƒW§ü[ke;´dŠçHº5kxÜ£=„âA÷Ÿšè²Ø˜/©=3ú©¦U=”£½“ò zBõÿf¯º|ÃlGw<ÑeÞ²vM﫞Ê}´–»_¨zaÄRuÔr9c¸û°“ -ìqŽ6H�Z©ÞëØPUñrV;½röªª¾ü®Zaù̹b�'G|¿–ÒkªÑ×QËfmRý½u…>2]õÚæ¼íeNTÛ§ôVOy)gƒ½r­PWµo�Š±ÜœÖÄ|;y]��¿zã¯l•?ÑV»%uÝdò­Ì#jN·Påã¢WzÇÒª\•ÇÔ€Î^Ÿ φ}š¹}˜ 2x¨ËŠ>áVæõº¿£zt|d¡Ë“¶qëX}TGéÿ�^Õ|oîLò–íGÓ){WUó™jÊߊp̦ªðù¯©§ƒ<•£½“òªÞL½¾àHþÄ’æ¤MêµênªÁÇ,o—ªv½ª\«PëÌyûá&íYsW=~ÍT*{³\±ðí¬³œØ1ó„úå½Õ#~nÊAoP.Þ5ÔÓf¨]7}´ßÍ'ºÌÞþ¶ª¢/¥ž™{“§¼ÜŽûÂÊãÔ|y·šÞç U½œ«rrrR®Þ©§_�­ö%ß°^·<–MêÌꡪ©Ÿ›ró©¬Bž¨æ>§6 ­­Ü\+¨ÖÓ"•ÑÚó†´ç›·g¥”ùê!5ïõgU°·‹2Ø»¨rÕŸT}&ü©.ȤâÿúJu}ÌO•¶7(—òµÕócV܆J)•¹Zu+ãpÓI ÍW«…C[«Ú¾¥•“ƒ“rõ Q-†ÌSaW –¾óö|=î³³š+gÍI==½�ºŠéÜ{Û6oí¹×tQýùeWÕÀßC•r)¥<ªn_ý©.ænÃßÊ[±æ*’wM¦[ÃÊx:Ð;¸àV±+Ë“”�eþã²VÐÑÉžú_Ãt“6žÇ=«3hc²õ…B!„¸û$)QâÌœ�ñ4š†VèË�FN`.é0‹J¥p`Ϋª-¯þxц+ÑÖԣȹGøú) xú&FæÜaìFŽLŪ5/O=†Ñ²hÆQE;ÑbÈ;´©D`@•+àfgc™¢P&Œ&:Ö*‘Ÿ^kËÈ�UóëaâÎsdÕüv�¡ý€%œ¿Ó>º­ñX² äé^}x¾vînªÆ@�×>§Ÿý2FO>È�¶"!„B!Ä­=˜}Ýÿ1v®Þø€¿O šžÒ>¹ÿð§|i=W7ô£¢K&�(xÅÚ|v6ϺúÐsu �Ū®e(Óe:+ÞiKƒºÁøT¢^—ÉìN±è ª$¶OéE“ªe)åì‚»ÿ#tøh±…ôÀÒ耓æHÛ—mÎn>Ã�3×`ßãk¾êŠŸwEêtÏW=ùõ›åÄš�¬#LxÂÿî?sñÚÌçXÖ±^ͦ™me=9[V«*ÍFnľçb¦´s½³ÎkæßÌþö5ú ¢©Ë ŸåìaÖ„-8t™ÌÜ7Ÿåá‡jÓlð¦÷*ÍöI3Ø–dýJ7Zén¬ÎHai{çüÑ/†à1ì3ZY¬Ú_æ˜É4q©Ë¸°Ólxï9‚Ë:¡·ÓãÚù'2¬]gc$;v_%¤ë0:?â�§›'�ú1mîTÞnîKε¦W ñ¤®ï‹¯CMÞÝ_ …ƒéð8ê:øÐë×+¹!í—š†k£†nrû†Jfïì�4{È›R¸úÖ¡íÈŸˆ²\qÚ¨^w8Ê 'l¿] ¢UëjÜX•ùÌNvœ6ÐðÙ¦”Î×…ÆÍãt~';OšÀá9¾»˜AzÜZ:yÓw] ddd�6Žzz¬+cåþÒU¦†ë1ÖŽèËûQÍ™¶=–Ĥ DMke±ÍnÃ.€‡‚ôýikŽ]É»eHÃ½ÉÆ¼Ö ?»â‹§T³>tñ‹fÙ¢kí ›= á÷ ýŸÍݲúбLÍ ãê.F×Ô´™Ss_¡õ»4˜ð1‰ñDþ2§»ÓzäfR±>f‹ AåVÏQ#ñÿذ_ÆJ!„Bq7é$+ñ`0Ô¦ßজ]ô-›ÓòÞË9È‚…‡©Ó¯?�9ä½§iè|Û1°cö€æÞ„~]‚9»n-áFÀÁ’9Û¨hîI޲!f vUêâtžˆˆK2á¥B!„w‘ÎI’•º¼Î‹æÌY�€2þžÇÒóÏ0¨GP�«ùúÀ í®Ï·¢/œ?Cœ 0'2:“}cj ÏŸLÓÿ7·’y.æ_ÃÙµÒ• ÆÏíÎîôÑyT&´^(U=s;ùª@WY£l›IÌëËÐçF“Ðw_·ô,´3}ëzŠ‹™K‰I(÷²xþý©¦å.ùß�U…BËû¼˜X»¿4;ôz;*µjÇ�srÚÂPùE&nŽábÌ6æ�|ŽŠfÄ35¨ÛïgâÌÅ�5{ô¦Aò*nLF¡H^?�Ÿ“›Ð¯g��N¹©ìc�‚ šÕ¹ž>ÒQ¾Qgz<_w͆˜ „Wo/HJ¼ôàN2+„B!Ä@wE~q?8J·dp/~›³ŒS¦6~¿ÓKƒxÑû†^°¦˜.†­ IDAT,Äd2Z^÷=÷ÞügfÅaV eñ2§¯ Ótho¤•*G9§«$$fâØüK¶ïÛÁ¤6®dÆÇsÕ©åK[Äm¾ÌÉI8”²'>ò‰¦"ÖS|Ñ[ü[�ÎÛ—òÚeÎÅ|Lhöù8µòT(_œSµØ²¿t¸{ºÃD1:Jù=Âs½ßaÒ�» [ІäE1+ÜX¬ñèü;Óç™Ö/\C‚é"¿Ì_�jÝŸNm[ n5ž¡(m^ÆG!„Bq/èþ5iœ¸�0ˆÇÂæ±`óO|¿Þ‹¯6£Ô ¥L1ÑÄäïX±'bQý¨`è«S³Dì;T`Äœ„ÓœKûw†J]9CÄ‘N'!{eJÃz°Û^‹e¥³{ë^´ÐF„^¢O6S{3<²=?ìYH«ðaôšr”l›ë).:<Ëz¢]N ±�«èºŠ�ihdצ-�$McûïÛÉòkB“Àâº�›÷Wáiëdï›J—g²4β^ekÖÄGKær²*Þx´r´ëóŽ›—±jÿ ÿY†ýÚàaË*‚® QG£,žzb&nóL>Ÿ¹9wt‡Í1æDâ“À³¬‡Ì,„B!Ä]$¿·0:¿®¼Þö"sú|ÈÖÚèúïû LçV0in8)fEFôr&,9A`Ûç©¥ìªÓuP3²–�fÔª¤™�\Ž\Ɉֵi2r i7Ô•±a(õj…2xuŠí׎u>¼üF'X<‚Ëræâ,}›Kõtz«òZ_Úî�éñq}¿û‚ÕÚ2qn7âÇugìÎTêQäd¤‘ššJjj™9 eÌ"-5•Ô´4²lʾi” Á/'‚ð(ã¿?Ö×ãÕáÍ1ý8Œ~“ãбÃl™5ˆ7fÐì�ר_È-Efãþº†Ê•q>ö=owŸwGž“VóÙÈÙD”oM›PC±ÇSºEo:–ÝÉüw²Û¿ýž´¶`Ƙ•Eff&™™Y˜�Ù¹ÿÏÊÂhô!tð8—¾Ëg¿Ÿ"5;ƒ û¾gxÿá,’Õ]¨§¸–%„B!„ÿa’”¸/è©ñæz¢cbˆþu0Aö•¸ê811Ñü6,}I‡WdŠœ«q„¯ŸÂ€§_`bdÎ]]VüŠ�´±Ÿ�q›ˆŒ�â�ñ¡„�jË«?^Äú\�5õײ„B!„â¿M’÷ ƒ›/þøû”Á é)í@@€?¾nöy%²XÝÍ ßþ øõé_«•¼ÊS³Ýçü}É¢œÎÜ> ¨TÚ×rÕyæí•Äܘ PIlŸÒ‹&UËRÊÙwÿGèðÑ:b¯•Ë:„'<ðïþ3¯Um>DzŽðj6…Èl+W*g+ÃjU¥ÙÈ�Ø÷\Ì”v®h·(žþCœ4GÚ.¸l{ÇÞ|†g®Á¾Ç×|Õ)?ïŠÔé0ž¯z:òë7ˉ5[¹^ÖÔcM!„B!„·¥»U'QÜ_ôz;’V~ÍOþŸ°ùp±s¨öƒ§„çÝâa$ìËî ÙT�v]$%n‚7ðíÆ ‹ZÌœœÕ…ç'¤ÐqÉQ.¥§príw¦ýøƒä8„ðÖ‚‰Ôýcƒ—žÅŒ‰Só2tGC¦ÌB û¢+„áq¾ŽºJ‘ LÔ/»bÞ –²±'L£^ãz8æ¿éHh£P´C{8˜…uëeM=Ö”B!„Bq[:ÉJ<84 jWÆô ÆЕ{–¶�ì‰>A&€ék×DQñ•ô vE§w§NïÑt¯n‘ 0E°dÎ6*ÏkõËa�÷ZÝùì�PþY´”ýy£%ìzòíì–„ ÈœMÓé?&ŠösgóJ%[רaoo}&©Õ$ö>ÀŒÊÜrDEaTj‰™®xy:qaïéE鬮(«ÖËšz¬]–B!„Bˆ[Ó;IRâ�bWÁ� ùý| {¤æäŽ”0�%ö,øWñ»>…]U-f¥0'2:“}cj S°nÍ©,±9ÐÀ�[wÙ6“˜×µ1Ï>7šê#7³ª¥§ÍÉ[h¥+rçõè<*Z/”ªž¹ë­ DmýzݺëË!„B!„(œþŠÜÿþÀ¹y·W¡œ�Á„ɤÀpýÛšfÏ3³bøíUŸ[w¡Í—9y" ‡RöÄG#ÑÔ—»y ÆÐJ•£œÓU3qìò%ۛ羟²$ž«Nå(_ÚbMo±^ÖÔ£i6,K!„B!ÄMéL%�(>:_*ú*N�ˆ½þQã1޳x¨¨¾:5«AľCXÎ4‘“pšsi–ªl"¦öfxd{~س�VáÃè5å(ÖÎqYêÊ"ŽDp:¹™2ûPÖƒýÛöZ¬W:»·îE mD¨Ãµ÷n³^ÖÔcõ²„B!„BÜŠ<}ã>‘“Gì©SÄžO!G¹rþ§NÅ—lC@_ƒÖ­9³ô ¾=t‰¬ô8¶Mú’U ÚõÑvÕé:¨YËF3jÕ ÒÌF.G®dDëÚ4¹…´¼bi»?¦ÇÇIôýî ZTkËĹ݈×�±;SmX+ENF©©©¤¦¦‘™£PÆ,ÒRSIMK#놌XƆ¡Ô«ÊàÕ)¶?}CçÃËot‚Å#±ü g.žáÀÒ·±TO§·:QAgåzYS�•ËB!„BqkÒ}º/‰œÒšª��Tm;ƒãÙ'™Õ.ˆÀÀª<;áÆÛW�ÇÀ££ñõ“gø¤‘îþÍøìJ7F>ïŽÊÉ!7 Ã¿ÏbÖ}Q�ð‘ ðv)C•–Ÿqê©™¬ý².€ºô#{NÇðö|>j\ Ð(óÔ§|?DcZ�alH´2e`:ÂøFºâêêI‡%—ÉÜ0€Š®®¸ºVbÀ†â|L…†G›©¬�Ú�ÈšSͯ:-ÆEÓtÆ:¦¶ñ@³z½n_�ue„B!„BÜŽ¨Ë—/[ý…Ý»wТE‹»’B!„B!þ d¤„B!„B!J„$%„B!„BQ"$)!„B!„Bˆ!I !„B!„B”IJ!„B!„¢DHRB!„B!„%B’ÿó²ø¹K)Juù™¬’E!„B!„° I‰û‚‘ð±cÐ4´/!ïÀXÒáÝ sOèAãÊ8Ú;âV)”F­$úndHT æ¼ÊSÕËââèŒWÐô›¹�duê)®e !„B!Ę$%î zj¼¹žè˜¢L�}e®:NLL4¿ A_Òá™™“³_áù±G©3n=Gc¢Ø:³ W¿ëJûOö“S¬ËRįH›û ·‰ÈØ(þJø¨¶¼úãE¬ÏXSOq-K!„B!þÛ$)qŸ0¸ù‿O šžÒ>øãëfŸW"‹ÕÝÜðí¿€_?|‘úµªQÉ«<5Û}Îß—,ºÁéáÌíÓ€J¥�q-W�gÞ^IÌ�½•Äö)½hRµ,¥œ]p÷„­#öZ¹¬#LxÂÿî?sñZÕæs,ëX¯fSˆÌ¶r¥T2ÿœÒh0l2»5 J?j·y�Qí݈þkqæ‚ÅÓ耓æHÛ—mïØ›ÏðãÌ5Ø÷øš¯:…âç]‘:ÆóUOG~ýf9±f+×Ëšz¬)#„B!„â¶tZIG ¬¦×Û‘´òk~òÿ„͇£ˆ�˜Cý°�<%<ï#a_vgȦ |°ë")q»˜¼�o7fXÔbæä¬.µ?c<Ìð‘­q½áS§V“Øø3^(ƒ­ÍR¥&�˜éŠ—§C�öž^”ÎJ ኲj½¬©ÇÚe !„B!„¸5½“$%(vü¨�Ÿcаw0@jNîH ÓYbÏ‚¿ëóPØP5ÐbV ãq"£3Ù7¦ú1ë֜ʛ ¹u—m3‰y]óìs£©>r3«ZzÚœ,ÈgŽg˸Ntžr…®ËÖ2¢ö¿‡[h¥+RÔ\§ó¨Lh½Pªzæ®·*µõëuëz¬/#„B!„¢pú+rÿûçæÝ^…RPpB&“Ãõokš=ÏÌŠá·W}nÝ…6_æä‰$JÙyŒDS\ìnõ…›H�à»>/0l]Æo^ÍÀº¥‹½ë®•*G9§«$$fâØåK¶7Ï}?eI:_*ú*N�ˆ½þQã1޳x¨¨¾:5«AľCXÎ4‘“pšsi–ªl"¦öfxd{~س�VáÃè5å(ÖÎq™/ãÓ;<Ã;g^fåöå ºEBB]9CÄ‘N'!SfJÃz°Û^‹õJg÷Ö½h¡�u°r½¬©Çêe !„B!„¸yúÆ}"'9ŽØS§ˆ=ŸBŽ2råü)N�Š%.Ù†4€¾­[rfé|{èYéql›ô%«´ë£'ìªÓuP3²–�fÔª¤™�\Ž\Ɉֵi2r iyÅÒvL��“èûÝ´¨Ö–‰s»?®;cw¦Ú°Vilû #Ž<ÉÔ#¨g…ääd’““I¹’�ñ†Ò†R¯V(ƒW§Øþô �/¿Ñ �`Äòƒœ¹x†KßfÄR=�ÞêD�•ëeM=V.K!„B!Ä­I÷é¾`$rJkªRµí ŽgŸdV» «òì„#ÿê¼ßœ�GG/âë'ÏðI#Üý›ñÙ•nŒ|Þ•“Cî¨þ}³î‹z„�l€·Kª´üŒSOÍdí—ÍpÔ¥ßÙs:†·çóQãR€F™§>åû!Óz cC¢•)ƒœ=,_þ™g–Ñ5Èww÷ü—GåÁüfó°‹[Ñðh3•µSùAsªùU§Å¸hšÎXÇÔ6hV¯×íë±®ŒB!„BˆÛÑuùòe«¿°{÷nZ´hq—BB!„B!Ä�Œ”B!„B!D‰�¤„B!„B!J„$%„B!„BQ"$)!„B!„Bˆ!I !„B!„B”IJ!„B!„¢DHRBˆûZëz{âÜ~)©%ŠÍÉ»&Ó­ae<� è\p«Ø•åIª¤B!„BÜ'$)q¿P)˜ó*OU/‹‹£3^AOÐoæ>’Õ](sMúÆÕwÁéù…$ßåÕûŸbŠâËöèÊ´fî9sÞ›fNMiŠKÝq6•ht÷ã!& x‡�Î=X°=‚ãÇŽ¶õKZºiÖס.±{Fž¬–מ«6¡Ï”$!¯¡./¦½_ÖgÛþÝ"¹Ç—-Ç»5äœ „B!î1IJÜñ+ÒfÄ~BÆm"26Š?Ƈ>ª-¯þxUÌer®Æ¾~ ž~�‰‘9%¶Ö6 CÖ_L�ƽ• £é.�\È8Ê¡h'Z y‡6uƒ   rÜ쬭ÀĉÙ]h5l å/a{Ø.~êÇöQ­yyê1Œ6†c ßÃÁL¿d³{y|Ys¼ßo1 !„BQ�$%îæ3ü8s ö=¾æ«N¡øyW¤N‡ñ|ÕÓ‘_¿YN¬¹ËäleX­ª4¹ûž‹™Òή[?ÐLÇ'ñtY7ÜÜ yy5å«H[†8¨÷Ü3$?™u…^–.ì¶‹¼÷ò®Bçl}“*!ý;ä *—õ¦Ñ‡ëøõ½–Ôðñ òKßq¼@8‰lù¸µÊ—±”/�t›Î¾«ËUIlŸÒ‹&UËRÊÙwÿGèðÑ:b-ú—æ˜É4q©Ë¸°Ólxï9‚Ë:¡·ÓãÚù'2lXs̉l›œ·,'Üýá¥-–•õ+=Üth¥»±:#…¥í�Ñ4 MÓ0�aŸµÙ„œ=Ìš°‡.“™ûæ³<üPmš žÃô^¥Ù>iÛ²r·éª®e(Óe:+ÞiKƒºÁøT¢^—ÉìN¹¶}²ù}�/ŽON#6aÏ9䯢Ù7äëh‹�l¾Èæñ�y,À“RÎΔ.B«· Ê–D†�ÇWúpÒi»à² I„kñZq¼gaÂøwÿ™‹×`>DzŽðj6…ÈlÛcB!„¢8éäÇç} û{Â4ê5®‡cþ›Ž„6 E;´‡ƒYÅXÆð8_G]%áȦj€—ÕW­|v�}Y²/Œ°°B^û`@UÛ6†®~_úù¬aÒ‚Ì·/þoz=ÚÉ5„….%|Ù‹œ›Ð�‰e&sð÷axl˜ÅЍëæì­Ó˜§½ÉúIÄmÿÿ?‡ÑíãÝäÞ‰`æä¬.Û”ÒùïºÐ¸ycœÎïdçÉÜíc0Ø‘ºvëêLcëÁb"Ñôðhº�ÛAö<=-† óÚâäуU)¹±d\ý‹¡U®ïó«kGÒuz6Ä�’žFüþIÿýCž¶~ÿÞËãËšãÝ!„·L¤îC¼ô,fLœš7�¡;2eþjØß㘅B!„¸�ÎA²%N¥&�˜éŠ—§C�+§öž^”ÎJ áŠ*¶2`‡½ý´×¡/��…¼ü}(c°¥2…Ù®ýÞ|’£3¦³£È·ót3œ+W£’Ù›úOTűr�ºxÎÇ_ï keÚ0täSTrqÀ£N?Æô¬Ê©µ¿rؘ"X2g•�çµúå°G�{­î|öF(ÿ,ZÊþü¬D9Ê—ÍáàÙ:L�ÿͪ•ÃÍÝ›Jåm¸2n<Ì¢9;ðìñ1#ŸðÅA3àõØ|Ò/€#‹–pÀ Ãàà€£ƒvGs_öz«—eŠ¿@‚rÇÇ»`ÊÄàí‹—²Ø>š†Î·;`hîMè×%˜³ëÖž7*C§wÀÑ ÍC^,ŽöØå£H»pž+:gÜÜœ±CñBs&ì=Ϻ~6 )³íørj5‰ý‡0ã…26�N°îx»€ž|;»%aÃ2gÓtú�‰¢ýÜÙ¼RéÚZý‡Ï B!„¢Äéœ$)q_ÑyT&´^(U=s/'«Bº*ÅUFÜ)ÞÞâó"&­Œ·}ø=€ÎOw t®”qÕ@gÀ`gÆd¾^£þ¡ZÔÈOšØP5í\,gM€ñ8‘Ñ™ìS}Þmšf‡ÿ›[É<sý¶ ͽގJ­Úñ¨sW9'šNBµ�ê\Ïáè ®†v&š“Å8gƒ¦¨B¶«B¡å}žA`�ùýj¾}áü⬾#GÃû¥Q õßÄ+U*Q§yW†~¾€-'S‹¶_­]jéJ‡ãçvgwÒÝúx×(ÛfóºÆ2ô¹Ñ$ô]À×-=åŒ „B!î º+Ew.Š“Vª圮’�˜‰có/Ù¾o“Ú¸’ÏU§r”/­[™ÿ²â�S"—æÔ„×Vã÷ÉsùÇlEÇRÝØÉÖ¡ËÿZÁŽvvzôÿúLËëXjhš=Ï̊ìÊâeN_A§ îžîwi2™[Ä_:o_Êk—9—^àýìóq$jå©PÞb-4­À:™L&®oëhžOóÉß±œÚöo=SžÄß>¡]­Pú¬Œ+Úí9w™MÇ»ù2'O$áPÊžøÈc$Êb„B!Ä}B'¿Mïö¡4¬û·íµ˜p0�Ý[÷¢…6"Ô¡ËÜêÊ"ŽDp:ùæ]·{YæfŠ{N‰¼Z êý­ÎÌáÛ]&‹N°†^¯‡œl²¯e!T2qçÓ ¯æ6L§Ž“?A¤‰Ø±P)€Jv€¾:5«AľC&¬ÌI8͹´Â¶Ód AԨǎ³xꈑ¨£ÇP•"¨Û˜®bcÙµi‹Å#.ÓØþûv²üšÐäúÐL1ÑÄäŸÌr·�ªèG…w©ºÅ¸S:W3ìñ mMïw&°hskú+~œ¹æú$‘ÅìNÚ³õÇ{6S{3<²=?ìYH«ðaôšr”{õdT!„B!nEž¾q?Ðùðò�`ñF,?È™‹g8°ômF,ÕÓé­NTÐc9i¤¦¦’ššFfŽB³HKM%5-�¬"d©26 ¥^­P¯N¹éP÷{Y榊uN‰ë4Ïçy«‡ ›~ÝgÑQ×S塪¨°?ø3Ñ ¹ø_3ÿ@9¥0�ú‘‰óŽpŬȈ^Î׋£©ò „è»êtÔŒ¬e£µêif#—#W2¢umšŒÜBZÑV«púºõoDÒ¢™°3#F÷Láýïâ¨ß¿[9‰¥u˪ǫÛcúqý&ÿÆ¡c‡Ù2ko.Ì Ù;¯Qßb™Î­`ÒÜpRò¶Ï„%'lû<µ,â±÷ðÀ%u›~?Î…‹ç8yd7ûcÒòÚQ&¾B`›/Øq1 …";á({#S([-7«ó8¶_wÔž­:Þ!m÷Çôø8‰¾ß}A‹jm™8·ñãº3vçµçÂÿ9A!„BkIRâ¾ áÑf*k§6$òƒæTó«N‹qÑ4�±Ž©m<ò‡èKÓÆ7rÇÕÕWWO:,¹Læ†TtuÅÕµ6d•Üfx`9ðØk¯Ó@—eѱÔQ¥ï—|ôÈA^«Q‰juÓ{}]w¯„ÎhÄhC4'Ç„kÛ!´=>œÝñ ʼn§¦±tÌ#yó:èðﳘu_Ô#|d¼]ÊP¥ågœzj&k¿l†K±®«Aƒ—³zdyÖt©Ž{)wê¼Ïá«ùé�êït‰:ú.fäf$|Ó…µëóòÄÓ4™°‘¥} œ¼šö¦uÌHVtÇ«î;D=>‘Åï>†½e™§‡ñYG{~êL¥€`¶{ƒ9{“óö™#O|¼œ±�¿Ñ§vY\œ]ðªÕ“ �Ÿ°rüÓ8Yò==¾n¼«K¿1²çt oÏç£Æ¥�2O}Ê÷C4¦õƆD%ç!„BQ¢4@]¾|Ùê/ìÞ½€-ZÜ¥�„ÂZY¬ëíËËI“ˆ[Ó·’G!„Ba)!„B!„Bˆ!I !„B!„B”ˆâœ–N!î1ž›—DÑži"„B!„(i2RB!„B!„%B’B!„B!„(’”B!„B!D‰�¤„÷µ,ÖõöĹýRRK:›)’wM¦[ÃÊx:Ð;¸àV±+Ë“TI&„B!„¸OHRB�JáÀœWyªzY\�ñ z‚~3÷‘¬J¨Ì½bŠâËöèÊ´fî9sÞ›fNMiŠKÝq6•@L÷#ã!& x‡�Î=X°=‚ãÇŽ¶õKZºiÖס.±{Fž¬–·ß«6¡Ï”$a¿«Ë‹iïׇõÙ¶×&æþžÐƒÆ•=p´wÄ­R(/ŒZItÖ]XVq÷Óñ%„B!þS$)!ŠH¿b mFì'dÜ&"c£øc|(á£Úòê�ÔB­ IDATQ÷¼Ì½¦aÈú‹©³ÂÈ)‘åeÂhºK[0ã(‡¢�h1äÚÔ "0 €€Êp³³¶'fw¡Õ°-”¼„ía»øa¨ÛGµæå©Ç0ÚŽ1|3mü’ÍÌœœý Ï�=J�që9ÅÖ™m¸ú]WÚ²¿˜ÛJq÷ãñ%„B!þKÔåË—­~mܸQmܸQ‰ÿ8S¬šö”³ò}‹ÊÈ3Cý9$@95�¬bL÷¸ŒŒQÕS^eT™2…¼<›¨/#ŒVVtL}QßE5|ñyUÉ·»úå²Y)eR1“›(ç‡Çªp£RJeªµ½<”S»%êjþóÞk»@]VJeÿõ†ª\³¯úèõ¦*ЫœjøÁZµæÝê¡òî*ðŹ*ª@=SÔšq/¨oåàâ£êu�¦ö^1_�Éœ¨¶Mâ¥\œœ•›_=õÒ‡kÕ©ìëEL''©Ç�Vcƪõï¶V5¼•�†rìðƒJ·nÍó*JPOÊ[–£³r«TO½ø�Ų2רîe4ü륯1Zíͱr9Ù;ÔðªU¾×¯*%ÿÍTõÛÀJÊà?DmÉÌÝ>¿¼RZ•îÏñè«”òóÇ£8ǦYs\8„ðÖ‚‰Ôýcƒ—žÅŒ‰Só2tGC¦ÌB {+ëB!„â.Ñ9HVB�JM 1Ó/OÒ耓æHÛ—±÷ô¢tV WÔ=-c}i|ü(äåïCƒM[³] ú½ù$GgLgG‘o æéf>8W®F%³7õŸ¨Šcå uñœ�¿ÞÖÊ´aèȧ¨äâ€G�~ŒéY•Skå°0E°dÎ6*ÏkõËa�÷ZÝùì�PþY´”ýùY‰r”/›ÃÁ³u˜:ÿ-šU+‡›»7•Ê»bõiÀx˜EsvàÙãcF>ዃfÀë±7ø¤_G-á€@‡ÁÁG:4ì Ž8:æ¾ìõV/Ë�åŽ�wÁ”‰ÁÛ/e±}4 �o;v ÀÐܛЯK0g×­%<ï�ÞGƒ4; y±8:Øc—Œ"íÂy®èœqssÆ Ç Í™°÷<ëøÝÁ}né„OíÏØ3|dk\oøÔ©Õ$ö>ÀŒÊX¿®ElåqaГog·$lø@ælšNÿ1Q´Ÿ;›W*élªG!„Bˆ»Aç$I q‡t• ­JUÏÜKàª�îÕ½,sïèðîð¯˜1ie|Ñî½×¹ã鮃ƒÎ•2®è ì̘Ì×kÔ?T‹ùI;ª �‹å¬ 0'2:“}cj ×44MCÓìðs+™çbˆ½–”ÐìÐëí¨Ôª�:q•s¢ùç$T ©ÎõŽž àjhg¢9YŒs6h€*d»*ZÞçy˜?èA‡oE_8†8«'Õð~iCý7ñJ•JÔiÞ•¡Ÿ/`ËÉԢϩ`ŽgËGÏÑ|l]—­`Dmû/µt%‚C‚ñs»³!·>.4ʶ™Ä¼®± }n4 }ðuKÏB�œûëøBˆÿgïÎ㢪÷?Ž¿f†M$qKìæRfi澕¹áRšæ’¦¥f{–7³RS+ÍÛâžk?5—ìvµÜrß…DÑD�†9¿?@³ÓÐz?�óxäÌ9ßóù~Ï �¾Ÿù.""òO`¹tSãÎåŸÎT—dâÏgàÜý}¶4Ï}=iþ9’]|ð+iÂdúëÎ)Œœ£“iÞh,{®·Ú ¥6¯nÚÀ¨êE›ÂariÌs«ñ¯�>ç—…èX×v²Í˜¯\V°£]€ƒËoÞ3åuM˜LV�Í÷Ï–½A7ÒŒ§—çmZáöâ¿ fßrø™8›\íÐg�‰å¼É�ò~f ßh‰|׿ääpµ} ÇäÕ”q›b¼wëþû?Ö¯GÇwþÍãs~ä‹'Ê­ÍÒÂù¢o^Ü]—ñëW0°nÉ[Þ½/Ìwð {Ç�]À©„•sG8ŸÓ7‡›(GDDDDä3k÷Â;‹qéá‡Â9™øûÙ¢¿òœße ¥a=ؽy'éW^LcûÆ�˜BêôŸS·zM‰¼R zz8­NÍä?Ûròu‹Â0Wx€*ÙØ¶nC¾­)SÙòÃ2ÓøêÐr¢£ˆ¾òÇ,·}Œ ”¿ö‘0î!'�ät+åB[óôK™»~+û,ž¾’¸¢ —H?ÄÇ�å¥SO²lËBýABâ¶È"|êÓŒŒèÄ¢shuàEžšr˜¬"—#""""rëiKÐ;LúÚÔ«Ê�I¿;lü¯<çw™Ëòä°®0o£îåTÜ)ö,x�Q ,tÞ•òæ¿øœÂ¸¥kJ\eòjÏðÞn¬ûvW¾Žº…*÷TÅØ÷?~œE•¨i‚ Ԍ̯_fÌòc¤Úm$D,cTëÚ4½�Ô›«ÖõYjÒ³#.Ì}“‰?ŸÇ†�ó;¦ðú±Ôïß›{ ¹ˆeáîU�gG6'gñ‹<óÑ÷ì?r� 3ñüœtš½4˜úùžWÎé¥LþüIyí3qþ1*µkO­|ñXK—Æ-eë~8ÊÙ¸Ó?´�ÝÑ©yŸý ~^“Jm'°5.ƒ¬øÃìŒH¢Lµ < �ÇIeó]uèa¦ÎE=ë%ILL$éRúo¶1½íßA uû;ô~çý¾˜@‹jí˜ôyOν݋±?§©‘ÛAÿ»)7ÉDé¶SY5µ!o4§Z@0-ÞŽâ¡OV3µmé+Ó þºsŠ“÷~ŽæÌ|K3Uú½Ï[÷íepuªÕy€§×ÔeH/Ì6¶"ô@³³spo7”vGGÒ ‚'Þ¡c8öÈ4¼r_Þºf*ö�Çê õ80º¾n¥¨Òò]N<2�Uï7Ãí–ÖÕ� ! Y1Ú�•݃ñ,áÉ=Ý–á5rK†s3cM~Ÿ™À~óX;¹ñŸv§Aíú<9é$�'~Ç‚~• üñrzèiZG�¦aO¼ë¾D䃓˜÷êýä_ÅÁ©é‹¼ÛÅÊ’.!ø†Ð°ã0fîLÌ{fÎ4yg!c+}OßÚepsuûVÖVDzñMq)lÈÙ;X¸ð2N}MXPi<==¯¥+áû¬Qx7þ^¿gtŸ�q|ao=P0Qê‘óåPÓz¿ÈÚóF¡Ê¹]L€‘��Pè ¶oß@‹-nSH""…•Éê§Ëñä…ÉÄ®ì�Gq‡#"""""E¢‘"""""""R,””‘bq+—¥ù‹9Ñæ« ÜÜž&"""""RÜ4RBDDDDDDDŠ…’"""""""R,””‘b¡¤„ü±Ì¥tq±RÂrŠ;ù[QRâa\ÜÎ'Ï6£FÙ’89Z)áS�‡úLbS¼½x³Ôcàô¼Úʯ?,6Œ½G“ S�Ñš¯ïÁ�Éû ¬˜LfÌgJúQ¿ãóÌØzîö$SŒ$öÌ|–G‚ËàæìŠwPž™¾‹Dã&ËKÛÃÛõÝpi?‡Äk߳dzibo¨\g«3þ¡t³Œ¨Ì|çdŰzlîôÄÙêD©rµh9ô+ö'_? ãÒž¿ÇŠcµÑl˾ɘEDDDDDþ$%%îÆy– nÇ蟫òÊ·‰�?á壨ö �ÌçÌÍvt¯”Ÿƒ-ç& q¨DÓ§úÒ¾v)L2Œ›g¡úókˆŠŽ&êÛ!Y+3pùQ¢££øþÅšù¶�1ã6—#‘ûÙ¸d£;í'&Ñeþa.¦%q|ÕPœçu£Óø½\îã›Ë‡PÝý«FõãõÈæLÛÃù g‰œÖ g D³¾tˆâë¹[¹:ú?‹sæЃþ�•À:–½)é¤'oãå×ëºÚ9ñyZ¿Nƒ‰?}þÿ7—Žh=z=)>æÛÆäK‡ž-(ùëOÞÂi0YûÙ±ÏD½êá|åEgB…bÚ¿ƒ½™€SM†ÏžDÝÿ eÈ‚_±“ɯ2bkC¦ÌJu+àø F&h-j€·ÃõêPšÖ¾gí›�¯ÞË~†£QÉ”¨Hi3`*ÃÃCßeLÛ€Ü,cÎ%Ž}ÿ“×:д[KÊæO=¦ná�¡«yà£wiî©o¿ˆˆˆˆˆ/³“ú%ÅÏìO¿³Pr9=C|ð­þOÏÜM'¹2è 'œù37SyÐx×÷ÁŠÏZ½xwX(¿Ì]Àî+Y üÊd³÷×:L�5œfÕ|ððôÅß/ïWx§<Õ+„Ø%sÙ�šwMÚ�ÌZx’š}úÒÀ)ï5“«“3ÎÎNX®÷É9ÌœO×ãñÔ{¼Õæʸ—¢BýL]0‹7š{‘m!æÛÈÑ?�rœå×3Çy¸´šÌîƒ{ø¤Cѧ¥)ñœÏpÇÛË©Àˆ «—7%3㉿”;4Â!°ÿù¬%ûFdæº�éÿJ$�>ÿŒþ—³X­×ËDü‘4LíÏØ=÷2rtkÜ ¼—ÍÆUqqò Zç9”zu-‹ûWÎ7*�mㆲ²ÁdÞ}ÌSS7DDDDD¤Ø™]Ô3¹#8V~œI룉‹Þ̬Ñm¨÷ £­NÝg¾É¢o;JDT»^©ŽåÊB�T|~#§£¯N‡09`±8àߪ#ÿr½Þ�¨Ñûi$.gÎw‰$®ùŠoóLŸêº‹œu„ÑT#¸Àš~�ºÑ»}'Žÿ›µ£uºV(ZÝ0þhE†¢Ä|{¤GãWü ¬PÔ ¿ÏT—dâÏgàÜü}¶ìÚÊä¶îdœ;G²‹~%óõøí ?v§VÎEáüÍn’Î= Óü2¼µ~“Z•½æùÚ±ÛÁÅ· !u ÃЬøw-6�}ŸïÒ€ô]Œò ¡ÇÓB ¹C˜oËv‰R$Y»¦Òý±�,ˆÍŸ!2S¦F ÊšIH4ÀL�j¾k?ùב̎?ÉéÔëe–þ ãiò¡cß8¯ÿšå»—2ïÇRt~¦-¥‹ÒWu "¤*DŽäê’vb×Oç½éësGw9æ[ÌËÿÍû/Yu[ѼlÁ.¼qéá‡Â9™xqXCiXvoÞ™¯^il߸Sh#B/O�!‹ð©O32¢‹vÌ¡Õ�yjÊa²Šz¿ôC|ÜùQ^:õ$˶,dPÝ’Ÿnæ p§ñäcä¯�““de�‘Ù»æ1w4‹{U£Œ·7ÞÞ>„¾º�ŒãÓ²|m^Ú¬}AEDDDD䯧Ý7+ãzäK^èõ:‹·G{î Ç÷¬àÝÑŸîך¶¡ŽàLØ fd~ý2c–#Õn#!b£Zצñè ¤Þø6”lñ4]Êü̬—æ°½bOžy8ÿ°;¶ÌL222ÈÈÈÄf€Ý–•ûïÌLlvÀR“žäâœWy÷‡¤d¥sv×—Œì?’9Ç­x˜¹¥1g'Æsâ1g’È6l\:s‚'bˆM,ØÅÏIŽ#æÄ1"v¬fZÿ¶ ûo9†Œ– kJ¤¯A½Z¡ Y‘TôÝ7ÌeyrXW˜7ŠQ ÷r*î{¼À¨ºïJù¼oUêöwèýÎú}1�ÕÚ1éóžœ{»cNÉ+È ;=•””RRRÉÈ60l™¤¦¤�’šJf@*›ßèʨC3uö(êY/‘˜˜Hbb"I—ÒsBN yòñòìþ` o{€“gc‰Ü8“çÇÿ€kó4qÇúcù9ú(‡öícß¾}ìÛ·‡5£Bq èÃÜëxù_ŽEm‘[ÂHHH(ôñÝwßß}÷�!·VZä2ãµ. �*Þ®†£ƒÅpõ®j4|òUcé‘´«'Ù/Û>îg4 ò6Üœ] Ï€P£Ã¨Æá”|Ùcïu1BÇ6lxÇlcïëµ ‹ÉÉhôadÁs3×ý}͹34 æòÆàõ™yñœ7¶LyÚhäm¸:Z ÷òu�N¯­4¢3ó•U˜˜o(ÛØÿVÃò›x,F�×vÙ†a¶#Æ„ú޹¯›Ì†Õ½¬QãÑÆ”Mg¯Û© Ÿ0œq2ÚκhØ‹Ê)Æ�Yƒ�¦A^†³ÕÅðnf<7û�q¹Zö ëŒÁÁFƒwöéù®ÙöZ¨á^u€±&Þž÷¬¯ßÎ&O£÷·†‘µÞRáúÏÂìõ´±úr[g3þïµÇ�û< '‹£áæ[Ýh:àcÛ…ß«]ŽýQcÃ%h”ñsÖM5€ˆˆˆˆˆÈŸfÊKJ:ƒ±}ûvZ´hq+""""""""ò¥é"""""""R,””‘b¡¤„ˆˆˆˆˆˆˆ %%DDDDDDD¤X()!"""""""ÅBI )JJˆˆˆˆˆˆˆH±PRâŽ`ãÀØ{q4™08©ùúl·áŽFÂ<:ôeMÖm(¼X¢ s"y¿�“ÉŒÙâLIß êw|ž[Ï‘s;B2’Ø3óY .ƒ›³+ÞAMxfú.�¢bçÄG�qúM½¬ÔŸp¤@Üi Ñ"7'\JWá¡gf²79ïf9y»®õš2rÇZo°ïò‡,ó+^’û+yáîæŽWà¿è4f1GÒoM“ˆˆˆˆˆˆä§¤ÄÁBõç×MÔ·C²Vfàò£DGGñý‹5±Ü†;Úì`oÆm(¸Ø¶ Íø„ÍåHä~6.Ï“¥~bL³Æ<·æ™äÄýLjêC­m ¶d±íÍvt[àÌÐÕÇILMàØ·ƒq^Ô›öoþÌß&%"""""w %%îŽå¨HŲ¥p4Y(Y6�ÀÀŠ”ó°æ�‘ÉŠž”ë?›oß|œúµªáïíG�Žï±éb¾.®=Žõã»q %\])éW“V/,"òJ"‹•ÃùáiÄÄE§¼_Ì­ ù0*ßïî)ûùrP3ªû–ÀjuÅ;èÍ9ÌÕÌ �‘ÈÎÏÒì_J89á^®íF/!2ÿ/ïÆ¶LyŠÆUËPÂÕ ÏŠ÷Ñù­ÕÄdßê6ÌåàîKÅÊÁÜûPgFÎZÇŒv‰|9fû¯’’¶¨3.&gÚÍN(zÂÂ~ŠÅÓWbíý!t %À·u:�çƒ>Î|ûéBbì@æ!&6)MÅ^ßwùöÓ|Ý¥<Þͦ‘`�p1S™òø—,A‰—7\MyåõÕ»,öͬñ�S§‚õz2sÿE¾WŸÜÚ›ptqËw½+ç�aü™^L}ù~\Œ‹ØMÉf½èR ,xÔ £×#%8¹ï omÖFDDDDD³éÆçÈÂbqà²YRqëF>“úûÞbÈ”W¦x$¯MØÇÙ XMRZ*çvO&dÓpFÌ9‰+M§Esö«v¸”îÍò¤tÒÓÓIOþ‰U.ÿîncÏ„0¯öaÌÆÓ¤¦ÆòÓh/VìÇ´#9EˆÇΉÏ{ÐúÕpLü‰èóçˆø¿A¸,îEëÑëIÉ;çøŒî´Ÿ˜D—ù‡¹˜–ÄñUCqž×�Nã÷RļDÑ™|éг%"`ýIû­+7k?;ö™¨÷@=œ¯¼èLh£PLûw°7pªÉðÙ“¨û¿¡ Yð+vr8ñÕ@FlmÈ”YC©n°“”�„ùì*^hQ‡@?_*TˆÞïýÀéËÝH`ó†ƒ4 `÷ë�Ó ¸•jéPŠ¢~MŒ”xÎg¸ãíåT`Ä…ÕË›’™ñÄ_Êvà؇ÿ|Ö’}#2sÝÇô%’NŸFÿ¼§e¤’šå‚Sb:þOOaù†˜?ºïµ§õ›ÛrG®äœ&æ×,bç½ÇâRÏ0ó»õ,ïQâ§?IÛ7æ·ËAd±{ÊX¾­ð¯´óÊW73•ûÏf~÷_yù¾28[œ(]玴û‚/ûW¹2UDDDDDDäV1»()qWq(@ù+½CV'G°eç�L0áûÄFT\G�*þÔiƈ÷f³áxJ‘§Øã63ý¹–Ôð÷ÅÇ׿*ƒX“i'ÇVp4ÁÆ“u„ÑT#¸Àš~�ºÑ»}ÿœŸ2²Éʶ“ÓðEþ3º5µ+U¢N»7˜1ò^ŽÎšÅækFK‰k˜òùiš=÷4÷X°$�]ïv û7Uø`×9ÒméÄï�FÝÿõ¦Õ+›óF¶ˆˆˆˆˆˆÜ:æK·pĺü5þ(�dòjʸM1œØüÃõãü÷ãèX+”¾Ëb)ô£Î‰`R·nL9Ý”O·Çw–³ÑŸÑÆ©èñÆ¥Drw’xtF,vÃÀÈwØÓ–ÒÕµ°Aß¼ôècüŠ?�nÝXS |\’‰?Ÿ�só÷Ù²k+“Ûº“qîÉ.>ø•Ì×jöŽ»€S +ç"Žpþ†[�8P©zÖKg9›j€Ù / î~eq¿R¬ÿª•°&Æq®À‚¦VÏa•í1z¶ó-øì²~bÆ”½Ô6ž>u½±š¬xì×![ IDATÕîÁ¿Ÿ¿ŸÈ™ÿáǿը"""""r'0ß–­¥øä¤‘œn¥\hkž~i"s×ïceƒÅÓW^]Lñ²ßK¤íaÛ;ô{ž‡Ë9c²#ðKQ÷&u "¤*DŽÌ·­©�ØõÓyoúzbí€%˜Õ |×þÓ ²ãOr:õ/ȘÙcù¿yÿ%«n+š—-8"¸tŠðCáœL¼‰8¬¡4¬»7ïÌW¯4¶o܉)´¡W؈Ù.Ä_(üˆ KMzx�‹s^åÝN�’•ÎÙ]_2²ÿHæ·âa‚ Ԍ̯_fÌòc¤Úm$D,cTëÚ4½�Ô"Ô¾°m˜“G̉cDìXÍ´þmößr ÿ,A× ”H_;‚zµB²"©è»o˜Ëòä°®0o£îåTÜ)ö,x�Q ,tÞ•òyß¼ÔíïÐû� ôûb-ªµcÒç=9÷v/Æþœ7YÂâ�oÖV>ÚŸ¾çô¹Sì]ò&GQg`98RÿÙa4<>‘¾/-åÀésß0‘a“üôS4tÌ—ívîM§rè½>Xñx{ov|:–¯'b#‡ä¨åü{úÏxµ{‚g¤ŒˆˆˆˆˆÈŸa$$$úøî»ïŒï¾ûÎ�[)ÛØÿVÃ’;Û!ßa1j¼¶ÛÈ6 Ã02ŒUO•6\:Î7’¯\—÷Z»ÙFBÞ+ö„íÆÇ}›Á>‹‹áî{�ÑôÙÏŒ]‰ö‚·Ì8dÌìj”u³ç’†O•û�‹~5r Ã0ŒãÔŠÆC†GÙÊFÍG_÷®öäýÆWÏ=f„øºŽV7Ã'øa£ïÄ�³‚Î1Îýô�v€QÒêh¸ùÕ6Ú¿²¢`;†ad¬0z–r2ûììuëdO>hÌÑÚ¨]®¤áâäb¸—­i´ú•±ïÒ͵€ˆˆˆˆˆÈ1å%% �Áؾ};-Z´¸ÕÉùÑô )JJˆˆˆˆˆˆˆH±PRBDDDDDDDŠ…’"""""""R,””‘b¡¤„ˆˆˆˆˆˆˆ %%þÆ2—uÅÕz?ïý’SÜ¡Üy2—ÒÅÅJý GP눈ˆˆˆˆ%%îÆÅY´q6a ÉÖ¬¼íÑLmâ‚Ù¹%ŸŸ3nª\K½gùtÆ«´*[ �Ù8íÝ)ñØgœ¶_ûÞ9f·/‰[³O8yí{K=NŸÁ«­üîž/AÚÞ®ï†Kû9$w,""""""·À]ÓûÛ3{PêâRæmJ 'r!ó#\(õ'ž�C`SžêÛ�:¥L·&F#[N!$&?:ô| ÇÍ‹XþkÁ̃÷-‹6À#=ŸÀÿÏ|‹ϵ*Ñô©¾´¯]Š[Ô:·‰Avr,ÖLa@ÓLŠÈ.î€DDDDDDn%%î–j´|Ì••óþG 6Ì_ÈÅ›RÍ!ß9)ûùrP3ªû–ÀjuÅ;èÍ9Lz¾Sr�#ÔjÂdÊ;®7}Ã~žÍ=Eãªe(áâ†gÀ}<ñæjbòõwíÑÑØ­.oï;ÉÚ×ÚRÆ‹ƒ÷nK Üï÷™ðnFk·m,ú&†«i ;±+³Ñ±=Ûûæ&Œ l™’�«žï£ó[7�=Žõã»q %\])éW“V/,"2ãj9¶Ý¯RÃñrûüÎô�¶O&+zzP®ÿl¾}óqêת†¿·5:¾Ç¦‹¿M’¤-ꌋəv³(r %{#/ÖªJ³Ñßaí3�)Ýïð$ŠˆˆˆˆˆHá™ÕÁ¹CÔz¼¥×Ìcí¹íÌ[œA›öuóe�lì™ÆàÕ>ŒÙxšÔÔX~íÅÊ�ý˜väj·Ú¡ÆËlKN'==�”¯RÓrí�r8úIÚ�;I‹/ös!-‘£K{�þYžxo?—ûÝæò!Tw?ªQýx=²9Ó¶ÄpþÂY"§µÂ¹°u*Õ‚ž<عhÇ.‡h?ÍòE›qmÓ“Ö^&ÀÎñÝi?1‰.ós1-‰ã«†â<¯�Æï-R<É«Föq6ÖF“”–ʹݓ Ù4œsN^IŠXBDz7%�ôäm¼\ã7�Sèö±X¸°ìC–TÇúƒ‘ĄϤþ¾·2å¶Â¶Oa8>ȇ‘ÉÄZËǃàípãKDDDDDDîf'e%î–ZÝéVq‹?˜ËjkgzÔwÊ÷¾…Ú/oäÄžÏé\ GGjôèLã »åR`rÀê䌳³3NV‡ßþªn;ÈÜ™[ñêý£›”ÃÉäˆ÷ýÃ÷L ‡æÎgÏåµÙ¿2ÙìýµSg §Y5<<}ñ÷+Ê/õn<ö¾û±427+a?ù ‹ö¤S¯æ”È gþÌÍT4žÁõ}°bÁ³V/ÞÊ/s°ûJVâFñ¤ž=Ã%³+®8`¹|s&î<ÃêW“;&K^û8a¹^E Û>& j¯ô Á 0ûép3SE°Z•‰‘¿'³‹’wK0ÝzóýÇópëÚ�{ ¾m�ÛÌôçZRÃß_?üª bM¦�[V‹ÌŽâ—ãP­f0W‹·R Ó©(Ž_îQ›°XðoÕ‘¹Þ|•œ£KÀ!/� ;Ñ˳ӯ3aMò µ%"*ƒ]¯TÇryʉÉ�ŠÏo$ãtôÕ)7ŒÇ„ïcQq=ªøS§y#ޛ͆ã)E›2QØöÊPþJ¾À„ÕÉlÙ¿)a*éOHÍ<4[JDDDDD$?ó¥âÚý@®ÃL`—a<Õ4Œç{„Pà÷ñœ&uëÆ”ÓMùt{ qqg9ýmœ~¯¬›aÂT IeÆÓËóÏ-lD>‚Qù‚~“äø³Ýn µºw§fÔ·,_·’oÓ­{èÕQ–`jTƒð]û , ™’Ó©×K%üA<9i$§[)Úš§_šÈÜõûXÙß`ñô•Äv¸D‘ÛçÆŒK§?ÎÉDeEDDDDDòÓxò»…S| "wî!É€ÌÓÿå�6bv‡ ñ ?ÀR“žýqaî›Lüù<6lœß1…׿ˆ¥~ÿÞÜ{½µÿ$‡àn„ÝÅü—ÿþÚatqÈÿ&aƒš‘ùõËŒY~ŒT»�„ˆeŒj]›Æ£7�Zè»dðãðšTj;�­q™dÅfgDeªáa°cËÌ$##ƒŒŒLlØmY¹ÿÎÌÄfç¶´OúÚÔ«Ê�IEß}ƒìôTRRRHII%#ÛÀ°e’š’BJj*™Ê*ŠˆˆˆˆÈ]LI‰»…µ1£§ ¡Üª'©T¾ ÷õú†Ê¯.ä窱´ûø—ßnmy] YÈŠÑ~¬ìŒg Oîé¶ ¯‘+X2,˜Û²¤¢¹"O†5$6â÷‡u¡J�›˜©Øw«'ÔãÀèøº•¢JËw9ñÈtV½ß ·BßÄ™&ï,dl¥ïé[» n®nx×êÃÚJãX6¾).Y?0¸¢+...¸¸7`üátv½V›..¸¸VáùŸ²(–öù#9‡ßÈwwwÜݽès>q÷ åáòJHˆˆˆˆˆˆÈ�GI‰¿{Ò6¦=õ"Ë�Ç“j*Mµ&}˜³x4µõ”EDDDDDä¤é"""""""R,4®_DDDDDDDŠ…’"""""""R,””‘b¡¤„ˆˆˆˆˆˆˆ %%Š��_?iŠ“É„éº‡�&åä Ï9†ÈÚ0„ ΡŒ;”sÛã>ñQãëÄd¥þ„#ÜˆˆˆˆˆÈÝO›E;3e{Md›t çЇ´zb-ͯã¥:À„séò”1Ýøœ¿6Ãd'ñb"�&phí`*^¹¹ 'WþÒXDDDDDDän¤¤ÄÀÁÝ—Šî¹ÿm»P G“…’e Ìÿx sNѤ-êŒW·U<:ë +ûxb*ÒÕ 1•)�É”¸é(DDDDDDäŸÊ\´Ž¨Èev’’0Ÿ]Å -êèçK…êÑû½8m+îØDDDDDDän`qRVâË¥Õdv|›Jq”`¤’šå‚Sb:þç°¼ŽIÛf0rD{Z'¯gÛ¿àr;‚‘¿ ‹‹’ÿX¦’þ„Ô¼Ù‹K¶$ްü¯UŸÊܳ;©óÑçüôFZ:Ý‚ EDDDDDäoË|É^Ü!È߇•ªa½t–³©Fq#""""""w8³¶nüç2.�"üP8'o"3•½Ÿ™ý»ðÒò8®¦lD '»L%*¹kŽˆˆˆˆˆˆü1í¾ñwdd‘{‚%òmÌirÁ»‚/ù_J_;‚z7»û†Å߬­ Ú/×÷»×�s?}ÄàÉQÔ9›FŽ·ª2""""""òwe.îä6°fR‹ªTªTéêƼ¸[8¥ÂTšöŸ¬á³Ž™Ìî}?•ü«Óòõ=„¼¶Š•/ÕF9 ¹`$$$ú‚íÛ·ТE‹Û’ˆˆˆˆˆˆˆüh¤„ˆˆˆˆˆˆˆ %%DDDDDDD¤X()!"""""""ÅBI )JJˆˆˆˆˆˆˆH±PRBDDDDDDDŠ…’w£Ì¥tq±RÂrŠ;–»•ÚPDDDDD¤Ø))q0.΢�³ KÐH¶få½h�fjÌÎ-ùüœQðK=NŸÁ«­üîÜhœá‹Öî”xì3NÛ¯}ï³Û—Ä­Ù'œ¼ö½¿ÊÝІ—Iì™ù,�—ÁÍÙï &<3}‰Æ�/¹“Ýñý± ³¥..eÞ¦tr"2?Â…R×{B•húT_Ú×.…鯌ÑÈÁ–SÈž°É�=Ãqó"–ÿZ0ó`Ä}Ë¢ ðHÏ'ðÿ3ŸÀ¢Äs­âjÃ"38·t mGí¦æÛ눈‰äãC90¦Ï.ŽCy ¹›))q§°T£åc®¬œ÷?R°q`þB.>Ø”jWO±í~•Ž&L&&Óõ¦d²¢§åúÏæÛ7§~­jø{ûQ£ã{lº˜¯ûj?Ïæ�ž¢qÕ2”pqÃ3à>žxs51ÙùN‰þˆÆnuy{ßIÖ¾Ö†�2.X,¸w[Bz¡*d»M­Ý¶±è›®¦%ìÄ®\ÌFÇôlï››0.°eJ^<®nxV¼�ÎoÝD<ö8Ö�ïÆý�^”pu¥¤_MZ½°ˆÈŒ¢´aaÚ§�íœ'mQg\Lδ›�Pô$‚ý‹§¯ÄÚûC>èJ€oêtÏ}œùöÓ…Ä×H‘[À|gÿJüb8PëñN”^3�µç¶3oqmÚ×-�5²„ŽeoJ:éÉÛx¹†åºÅX,\Xö!K*ŽcýÁHbÂgRß[ ™r9ý¤ íÆ�¤Åû¹�–ÈÑ¥=Hÿ¬ O¼·ŸËýnsùª»aÕ¨~¼Ùœi[b8á,‘ÓZá\Ø:•jAÏì\´Œc—{þöÓ,_´×6=iíeìŸÑ�ö“è2ÿ0Ó’8¾j(ÎóºÑiüÞ"Å“¼j4ag3`m4Ii©œÛ=™�MÃ1ç䕤È�Û°písãv¾E²ö³cŸ‰zÔË×î΄6 Å´{3oåÍDDDDDDþZf'e%î–ZÝéVq‹?˜ËjkgzÔw*xŠÉ‚ÕÉgg',¿÷ÜL@Õ0^é‚`öyŒv�¬D 'Àv�¹3·âÕûF7)‡“Éïû‡1î™@Í�ÏžË=j³~e²Ùûk¦ÎN³j>xxúâïç^„én<ö¾û±427+a?ù ‹ö¤S¯æ”È gþÌÍT4žÁõ}°bÁ³V/ÞÊ/s°ûJVâFñ¤ž=Ã%³+®8`¹|s&î<ÃêW“;7jöÏ�Ú9—V“Ù}pŸt(úT#%žóîx{9qaõò¦df<ñ—4�CDDDDDî^f%%î–`ºõæû�çáÖµ;÷:Þ\1å(eÚ‡ «“#زsÁÏŽâ—ãP­f0W‹·R Ó©(Ž_îQ›°XðoÕ‘¹Þ|•œ£KÀ!/� ;Ñ˳ӯ3aMò µ%"*ƒ]¯TÇbº<­Â�ŠÏo$ãtôÕ)7ŒÇ„ïcQq=ªøS§y#ޛ͆ã)E›2QØöáíœ?²’þ„Ô !ÀãÏÍ–2—®Lh½PªzåŽð0îðÕ0DDDDDDnÄ|IsÒï f» 㩦a<ß#‡_ð»n®»jÂTàB3ž^žnáë}ôèÄ/Ks03ŠeKöØ-Œ†W�ä®íðèŒXì†�‘ï°§-¥k�ÄÇcòjʸM1œØüÃõãü÷ãèX+”¾Ëb¹5ókÛçfÛ¹w,áƒ�K2ñç3pnþ>[vmer[w2Î�#ÙÅ¿’JLˆˆˆˆˆÈÝËü›Eþ¤X™ËufÊêÏè]ù6­AêDõ*päЮ®#i#òðŒÊ÷ätí¶Ók¡V÷îÔŒú–åëVòí¡`ºu½: ÁL�j¾k�4³ãOr:õz©„?ˆ''�ät+åB[óôK™»~+û,ž¾’¸Â—(rûܘqéá‡Â9™x©k( ëÁîÍ;óµOÛ7îÄڈЛˆGDDDDDäN¡Ý7îvl™™ddd�‘‘‰Í»-+÷ß™™Ø ÛßµÔ¤gÿF\˜û&>� çwLáõ/b©ß¿7÷^ýÌ?Å!¸a÷E1ÿåÿ°¯vÝCò¿IØ fd~ý2c–#Õn#!b£Zצñè ¤ú.ü8¼&•ÚN`k\&Yñ‡Ù‘D™jAx˜ PmxÚ'}íêÕ eÈŠ¤¢ï¾a.˓ú¼QŒZ¸—Sq§Ø³àF-°ÐuxWÊë,"""""w1uiîY?0¸¢+...¸¸7`üátv½V›..¸¸VáùŸ² Y�AC²b´+»ãY“{º-Ãkä – þSSF~—¹"O†5$6â÷‡u¡J�›˜©Øw«'ÔãÀèøº•¢JËw9ñÈtV½ß ·BßÄ™&ï,dl¥ïé[» n®nx×êÃÚJãX6¾).PÈ6,†öùC&J·�ʪ© ‰x£9Õ‚iñv}²š©mKkU ¹«™#!!¡Ðlß¾€-Zܦ�DDDDDDDäŸ@#%DDDDDDD¤X()!"""""""ÅBI )JJˆˆˆˆˆˆˆH±PRBDDDDDDDŠ…’"""""""R,””¸ce²úi/\ÛÏ!ñ/»§Aâ¶�èÙ°2^®ŽXœÜð¨ÆÂ Æ_ÁMÉ\J+õ'!§¸c‘BûÇ$%²6 ¡‚s(ãÝ9ÝV#a�ú²&«¸#ÉcÛÏä/ñ�kofo çè‘ÃìÛø>-=L…/øÈöOúópµ2¸9»â]µ1}§låüMä5 Ý>–z œ>ƒW[ùÝ%h;ÑSšàbv$ä•]ØŠ;œ¿ZÚÞ®ï†Ëõnöx6MìÍ•KãluÆÃ?”c–•Y�ŠˆˆˆˆÈívwôáþ¦lv°7ãFg!!ðg¥f” -†¾DÛºAT $°ry< [@Ç>ëN«7à3d>[ömcш¶ŒiÍ“S�¹ó]¸ö*Ñô©¾´¯]ê¯l­›—s„…óöÜð^b/`[a:ÜF¶œdv sN±1ÈNŽåÀš) hÚ�IÙ×9ÇÎñÏzÐ~ìaê¼½†ÃÑ‘lœÞ–ä/Âè4n7×»BDDDDDînJJäg\`Ë”§h\µ %\Ýð¬x�ßZMÌ•ÞP&+zzP®ÿl¾}óqêת†¿·5:¾Ç¦‹ù:ƒé‡™5àA=\q÷­AÛ7¾eÑÐ@ÜÚÍ&ÁÈâ‡Aåp~x1ñ_ÑÆÉ„ÉdÂdmȇQ׌äpHbÛ]¨[®În~Ôîü!?'±ãi?Ïæ�òêåâ†gÀ}<ñf¾ze~Ko3¦’=Y‘žÄ‚N®¹ñ˜L8†¼Â®Âf²w0c✺ÄçÏ?ƽ÷Ô¦Ù�™|üTI¶Lþ„Í™¹m¸<¬¥ºÌÒ—ÚÑ n�eý©×ý#¶']®WáÚǶûUj8æ½gú�é7ª{aŸ©=Žõã»q %\])éW“V/,"²0I“kØö/`~D=úN{žf—2SzÁ�£?¢±[]ÞÞw’µ¯µ!¤Œ  îÝ–�^„sHÙÏ—ƒšQÝ·V«+ÞA�0hÎá+ï'¯}† n�™|Ì^ðþ¿~Æcîeé³"©Àëi‹:ãbr¦Ý슜úÈÞÈ‹µªÒlôwXûÌcJG÷ß&�ŒD~9a¢Á‹1©gª” vÛ×ÓɃ¨Ÿ6k¿^Á"""""r73ß¿,ÿ%ìŸÑ�ö“è2ÿ0Ó’8¾j(ÎóºÑiüÞ+¿ÒZ,\Xö!K*ŽcýÁHbÂgRß[ ™r o$@‡&õaðJOFþKâ¯?ò²Ëç¼±(ÃâˆÅ`¥é´hÎ~Õ—Ò½Yž”Nzz:éÉ?1¢JÁa 9?ÊôÄž|}à §6Ž¡ÂÆW4å`ÖNÈáè']h7î$-¾ØÏ…´DŽ.íAúg]xâ½ý¹õrjÃqé¤ÅΤ¥‹/ýV'寓žNʾ·©g)d žú™­'iøØC”¼òª4—3?óóñܨHY5�Õu¦±qo8ÑásyèàËô|{+¹ƒ ×>–бìMI'=y/׸^�…¨;…y¦�¼j4ag3`m4Ii©œÛ=™�MÃ1ç$Eë+g±}þBbêw¡S�6ty4•åóÿGJ¾3ÌåC¨î~„U£úñzds¦m‰áü…³DNk…s¡Ï±±gBƒWû0fãiRScùi´+öcÚ‘Üçàþèsô«²‹Ï¿Ø“oBGçÅær=زT‘jö‡äÃÈdâ­åãA ð¾ÞèSiZOøžµo6¾ROìg8•L‰€Š”V UDDDDäoÇ줬D®œpæÏÜLåAã\ß+ ?ïRÓm\ø£`¢àÏ2û–ÃÏ”À騴¯g�‰å¼É�ò~ùjrM½rrrrã¹uáÜÀoëþG÷6y5eܦNlþ‚á�úqþûqt¬Jße±…Ÿ¾a\`õÜo‰OYÇ� O<<<ðèͲ„$~˜·œ3>"f<½Kc®ýœ&1ð;ç¤íaÛ;ô{ž‡Ë9c²#ðËo†Ø8:`÷ïûŠÙë—ðåoz?ÛŒ׋ÿÒ)Â…s2ñ6f2ÓñqçGyéÔ“,Û²�AuKÞ;ªˆˆˆˆˆÈMùgýid‘{‚'ò1q¤äÁ„ jFæ×/3fù1Rí6"–1ªum�Þ@ê ÏãD󿕸uÉTæG¦bØ.°}Êû,?ÿÛùôÖÒ¥qKÙźŽr6î4ÇmgwtêÍŽ©¸>KMzöoÄ…¹o2ñçóذq~Ç^ÿ"–úý{so!±,ܽêñìÈæä,~‘g>úžýG²aÆ žŸ“N³—Sÿê rN/eòçH²¤G-dâücTjמZùâùãö±cËÌ$##ƒŒŒLlØmY¹ÿÎÌÄf¿•uÏàÇá5©Ôv[ã210ÈŠ?ÌΈ$ÊT £P½f;'—ÎåG§VôîB``à•#¸s:xngÁâ¨",`zNð1ˆÜ¹‡$2Oÿ—w>؈Ù.Ä_(0ºÃÆsíâ˜Ù÷M6Ö@¿PÇ뙾võj…2dEÒM|F ²ÓSIII!%%•ŒlÖIjJ )©©d椲ù�®Œ:ô0Sg�¢žõ‰‰‰$&&’t)½È[ÊŠˆˆˆˆÈ�”°fR‹ªTªTéêƼ80S±ï�<¢wMU2Ú=N~�,ÆöÍð A’$IÒ åô I’$I’•$I’$I�0”�$I’$I�0”�$I’$I�0”8ž &Ó))ž¦/'ôX$I’$I:Éœ:¡Dô[ržìÇu+S6± •ÎjNïÇæ³9z ]mϵ5{ójá/4Œ½€O?Ã}íÒJÉ….fõc—“Ž£þ½Rôp$I’$I¿k¥ã^ùW‹ðų]iwÇ›T4�y¹ xiHMæÝ}5_~Ô7ßEKÞgÑî4ŒÉ e¯Þ\Ó¸|éØ 4²œìñ ©×ì<Ö¿<‘%8&¡(ò ÉNIÚH’$I’N9¥&”˜:uê±¼ç}žñ& ]GñÜà6œwvcZ ýNcÞÈ'y· €©ÝËS¾ëL¾«Ÿ_ŸZ§×à‚®£ÈÙöà u!s¦“xÅhÖlGû„¡PˆP|3Yy`‚FÑG÷Ñ nßk¡#Lß(ÞÌ»£zÑü¬Ê”K*KjÍ ¹þ�™¬ÙóCƒ¦Ý˜Bz¿ø÷×Ñ´Q]jTJ£AæCÌýö üâ<ÞÞ…‹jU¤\™2œ–Ö�vÿõ+JšüHÑâ‰Løôz�L«o'3anþ¡C^=ŠæeÏço¹k™õ—öÔ¯œDlL,É]&‘mر˜±[qNÕrÄÇ—¡R�ÿ`à‹Ÿì}û¬¾T/Ûœ‘_úþ_?K›äÓ¹iÚ¶£?9I’$IÒI'\*~Ágo(q¬ÁDñWï1mÍÚ´à´ýÏ–åÒÖ—’´á=Þ[µ72ˆ‹‹aÇŒÑÌ{‹âi9z5Çu ©BO¦nË'??Ÿüío3¤vÌþžc›ü•E;òÉß¾€{ÄfD>²†­¥íó‹Ù²ë;>ŸÜ�üg;qýC‹ù!—ˆ��aË”G˜tÆ0ÞXº‚5ËÆÐ4÷¿ôØ’ýÕÛg ¥û{è?k5Ûvíä›�FRîí yq-Ňyç#+$gB6kšvâÚsÛÓéÊ�L�ðì8¨E¸Z}ÎI^ÎŒ?÷áþ­=o ›·ldÅèv$–¸M îÎ-3«p÷;ëØ¹s=o­Èô}½|ïÿ!ùÊ[éSûCž{~áþk>Ÿ0ŽwÓodÀUå�êÌ$I’$I'§pBiI%8ö`"òÍF6ES9½jâ!ÏÇUM§Rô6|³ïö="œžÉ€NµˆB©ÍéÛµ>_ÏœÁ’})@86�ĸ0„bˆKL$11‘Ä„xb¾Ž¡XâILL öp×·h)YcæS±çƒ ½<�„P•.º�a}kñqÖþ�8„€³ºsïMõ) „«´¡Ã%ñ¬\ºŒ½…QvnÜÀ÷á2¤¤”!†‰ÕZ3⃠Ìì_óèÊ`v½MÖ¤<.ëz-ÕcR¹ªsŠfLàµïªÊW!­ò}}.�ÿóvZÕ­BJjUj¤%˜žò‹mbi|Ï;|¹ð9zÔ+O\\ ºÝÀÅÑ¥|ôñ¾"®1}µàë¬ðÆÎ}ýîYÄ /.åܾý¸(áhNL’$I’t² '•¢PŽ-˜…¢ütUƒ(QBû^ß+6£û‹¤WO‡ _±þ·Ü>cÏJ>[uÖ#îÀ;S§~]B_­dÕAS/bªÕ¤Úþñ„ˆOˆƒ¢=û*%BT½þn†œñ:Ýj×àÜÖÝòÐ ¼¹jÇaÎõçmŸ3ž©ß·¤ÛÓå[wæªÐkŒŸ±ù@_¡bcc¨Ñ.“?”9BG%hSœ÷.Oßz jT¥JÕ4ÒjäÕ‚b"E?Ôv„©ÑõV®+žÌ˜i›ˆùsÇ1qÕ ìY‡˜Ãw+I’$I*eÂß]�©®šNZh+ëÖï:äù ëÙJ£ZÚA5¡Ð!‘H�À…* Iö>ó3­+¶dØÜ5|ùîóÜ~e›g#³QzOY_òéÑ-ÌÌú7›v¼Î :©¤¤¤�R³'S¶ncÎø©l8$á“Z1õª0~¦MäSíÒ…Çֵ䩜5äåmdãêgiÿãê‡Ó®bP¯Ó™=æ_|ÙÆkc§¹~ ×U-e)š$I’$éˆÂ¿eÀ‰�™™IffæQ®~)—f±àõ790a'óæÌ£ fsš(� ²z%«÷_”k¾XC´úÁÕ ûDÅnqu8§6,ÿxùAk&±â“åDÏ<›:G3=!²‹íùñ¤7¹š›ïAÖ¹Lïåå§§“WÂ!Fó¦‘5;Læ³±$7—ÜÜ\rs—°hlWÊÍ�Àä5?Ž7J ¡Í®…,XRÌ¥}sEz"!`ϧKøì'[ ÄѤÿ@.ÊÇ oLbì«•èù§V”+Ù)I’$I’J�R³û[ @ìüéÎÖD^¾ƒ¾£f³xùRÞ|f ƒ_̧Õ]·ÐôÀ "ë&3ò¹%l+Ž’¿2›¾ £Ã54:h½Êø (»ãC^Ÿó9óÖ±êã>Z½sß4‡bŠ Ø½{7»wP…â¢Â½PT Ä6äÆ~—°%ëF¼·™"ŠØüþcÜÿüzšöëÉy‡[ó°vóÖí ÉøÏ‡™ŸW@”(…›>áƒO·Q¹nRJTTPÌÚÉY¼•ÐŽž�êS«V­ý�z7ÜÄSs˜øòÊŸîr¬ªS³J”,d[ Öý/þÏ;„“a˦-‡Tw„kvçÖyŒéýï4îOŸ&qGìV’$I’Tú”šP☠ÂÔê3žY#[±é©®\ܸ)]Kó¯1±OÆ!!¡ÅÍ\½z(ͪ§Réü»XqÙ£Œ¿ï"ânÓòþÞ)žI�êS£V}šeÞÆ˜¾ÛJÎá–3Ê�””DRòÅ ÿ$ŸÿÒ˜rII$•©Íà· �ê ÊfÚÐ4¦w­Gj¹TÎî2…ŠwNcÒmõŽbÍ„D.0›¿f̦wãÊ”-S–J�nbVÆ0¦ oIRIºˆ¬ä¥ñ Hnß™VÉ?z-©]2«�;1›e¿U*ßœ¡£‘>£#Õjsa�W8ó¾léU—Ü{›Ñá‰Ï ¡®Ø�ry»i3 ¥æÓ*I’$I*‰ݺuk‰ÈÉÉ mÛ¶ÇiHA)`æÍétÜ2’õÓ{’ôpDٔݙ†÷§3iÉ(Z”(e‘$I’$•%ž( �8QŠ w±9÷Ÿ ºû-šÜ›Ãe’$I’ô»cA¼N>Ñ�Œ»¦*í'¿GcûføA•$I’¤ß!§oH’$I’¤@ø´$I’$I „¡„$I’$I „¡„$I’$I „¡„$I’$I „¡„$I’$I „¡„$I’$I „¡„$I’$I D8ô$I’$IÒ))œ`*!I’$I’N2”�$I’$I_ô$I’$IÒ©( z’$I’$é”äî’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)†’$I’$)áPÐ#�$I’$I§¤p‚©„$I’$I @8ÉPB’$I’$ ü}qÐC�$I’$I§¢p$èH’$I’¤S’»oH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@JH’$I’¤@ü?mµV1¹mKðIEND®B`‚someipy-2.1.2/docs/index.rst000066400000000000000000000030021513043235100157620ustar00rootroot00000000000000someipy - An Open-Source Python library for SOME/IP ===================================================== This is the documentation for someipy, an open-source Python library implementing the SOME/IP protocol, including SOME/IP Service Discovery. It is designed for fast prototyping of applications making SOME/IP more accessible to developers. Relevant resources: - :doc:`Getting Started ` - `someipy on GitHub `_ someipy is still under development. Therefore, it does not yet support all features of the SOME/IP and SOME/IP Service Discovery protocol specification. someipy is based on the specification version of R22-11: - `SOME/IP Protocol Specification `_ - `SOME/IP Service Discovery Protocol Specification `_ The library is developed and tested on Ubuntu 22.04 and using Python 3.8. Windows is supported as well. For Inquiries ------------- For any questions, feature requests, bug reports, or general support regarding someipy, please reach out to us using one of the following methods: - someipy.package@gmail.com - `LinkedIn `_ Table of Contents ================= .. toctree:: :maxdepth: 2 whatsnew getting_started cookbook someipy_daemon service_discovery service_interface changelog api/index someipy-2.1.2/docs/offering_events.rst000066400000000000000000000162401513043235100200460ustar00rootroot00000000000000Offering SOME/IP Events ======================= SOME/IP Events -------------- SOME/IP events implement the publish-subscribe concept in SOME/IP. A server offers a service to which one or more clients can subscribe. When the server sends an event, all subscribed clients will receive the event. A SOME/IP event is identified through an event ID which is packed into the header of a SOME/IP message. The event ID can be used by multiple services and does not have to be globally unique. The unique identification of an event comes through the combination of service ID, instance ID, and event ID. A SOME/IP event usually carries a serialized payload. For defining the service interface data types and serializing structured data into ``bytes`` follow the article on :doc:`service_interface`. SOME/IP SD Eventgroups vs. SOME/IP Events ----------------------------------------- In SOME/IP there is also the term of Eventgroups. It's important to understand the difference for setting up a proper SOME/IP communication. If eventgroup and event IDs are mixed up, the service discovery will not be able to create the subscription properly. Eventgroups are only used in **service discovery of SOME/IP** and group events together for logically subscription. Eventgroups only exist at the service discovery level, but never appear in the actual data sent for an event. Once a client subscribed to a service, eventgroups are obsolete. Grouping events in eventgroups allows clients to subscribe to multiple events at once reducing the bandwidth used for service discovery. For that purpose you could put all your events into a single eventgroup. Then a client can subscribe to a single eventgroup and will receive notifications for all events. This has the advantage of reduced traffic for service discovery. However, since all events are sent to the client even if they may not need all events for operation, more bandwidth is used for sending the actual data. If you want to enable clients to subscribe to single events more granularly, create multiple eventgroups or even one eventgroup for each event. This will require more service discovery traffic; however, it may lead to sending only events that are actually needed by a particular client. Step 1: Connect to the someipy Daemon ------------------------------------------------ The first step is to connect to the someipy daemon. The daemon is a separate process communicating with the application using someipy via a Unix Domain Socket (UDS). The daemon is responsible for handling all communication with the SOME/IP network, including service discovery and message sending/receiving. .. code-block:: python someipy_daemon = await connect_to_someipy_daemon() In case, a non-default Unix Domain Socket path is used, a config dictionary can be passed to the *connect_to_someipy_daemon* function. Step 2: Define a Service ------------------------ In order to offer a service containing a SOME/IP event, we will define a ``Service`` first, which is used afterwards to instantiate a ``ServerServiceInstance``. The ``Service`` will contain a single event with ID 0x0123 in the eventgroup with ID 0x0321. The ``ServiceBuilder`` class is used to build the ``Service`` object. Note, that the transport protocol (TCP or UDP) is defined per event and not per service. This means that you can have events in the same service using different transport protocols. .. code-block:: python SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.UDP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) Step 3: Instantiate the Service ------------------------------- The previously defined ``Service`` can be instantiated as one or multiple service instances. Since we are offering events as a server, a ``ServerServiceInstance`` object is created. The constructor of the ``ServerServiceInstance`` class requires several parameters: - daemon: The *someipy_daemon* object (defined above) - service: The *Service* object (defined above) - instance_id: A service instance ID (0x5678 in this example) - endpoint_ip: The IP address of the network interface on which the service is offered (127.0.0.1 in this example) - endpoint_port: The port on which the service is offered (3000 in this example) - ttl: The time-to-live for the service discovery entries (5 seconds in this example) - cyclic_offer_delay_ms: The period of the cyclic offer service SD messages (2000 ms in this example) .. code-block:: python service_instance_temperature = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) The parameters ``ttl`` and ``cyclic_offer_delay_ms`` are described in detail in :doc:`service_discovery`. .. note:: **Multiple service instances:** If you want to offer multiple service instances in the same application, you would simply construct another service instance here. Read the example application `offer_multiple_services.py `_ for more details. Step 4: Announce the Service via Service Discovery -------------------------------------------------- At this point, clients are not able to subscribe to the ``ServerServiceInstance`` and to its eventgroup with ID ``0x0321``. The next step is to use ``start_offer`` to announce the service instance to potential clients. The ``start_offer`` function will communicate with the someipy daemon which will take care of periodically sending service discovery messages with offer entries. .. code-block:: python await service_instance_temperature.start_offer() Step 5: Sending Event Notifications to Clients ----------------------------------------------- Now that the service is offered, clients can subscribe to the eventgroup with ID ``0x0321`` and the server can send events to the clients. The ``send_event`` function expects a ``bytes``-object which is typically created by serialized structured data: .. code-block:: python payload = tmp_msg.serialize() service_instance_temperature.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) Typical sending strategies for SOME/IP events are **cyclic updates** or **update on change**. Update on change means that an event is sent whenever the contained value changes. In a cyclic update, the event would be sent even if the contained data has not changed since the last publish. Step 6: Shutdown the Application ------------------------------------------------ At the end of your application, make sure to stop offering the service instance and disconnect from the someipy daemon to ensure a clean shutdown of the application. .. code-block:: python await service_instance_temperature.stop_offer() await someipy_daemon.disconnect_from_daemon() someipy-2.1.2/docs/offering_methods.rst000066400000000000000000000206721513043235100202110ustar00rootroot00000000000000Offering SOME/IP Methods ======================== SOME/IP Methods --------------- Methods implement a request-response communication in the SOME/IP protocol. A server offers a method. A client calls the method by sending a request message to the server. The server answers the request message with a response message. In contrast to SOME/IP events, no subscription of the offered service has to be set up in order to make a method request call. Request and response messages can carry a serialized payload. Typically, the payload is either the argument to the method or the return value of the method. For defining the service interface data types which can be used in methods and serializing structured data into ``bytes`` follow the article :doc:`service_interface`. In SOME/IP there is also the possibility of fire&forget communication. The client sends a request message and does not expect a response from the server. The fire&forget communication is not implemented in someipy yet. Step 1: Connect to the someipy Daemon ------------------------------------------------ The first step is to connect to the someipy daemon. The daemon is a separate process communicating with the application using someipy via a Unix Domain Socket (UDS). The daemon is responsible for handling all communication with the SOME/IP network, including service discovery and message sending/receiving. .. code-block:: python someipy_daemon = await connect_to_someipy_daemon() In case, a non-default Unix Domain Socket path is used, a config dictionary can be passed to the *connect_to_someipy_daemon* function. Step 2: Define the Data Types for Request and Response ------------------------------------------------------ In this example, we will offer a SOME/IP service that calculates the sum of two signed integers and returns the result back to the client. Therefore, we need to define two data types: one type ``Addends`` is passed as an argument in the request and the second data type ``Sum`` is used for transmitting the result in the response message. .. code-block:: python @dataclass class Addends(SomeIpPayload): addend1: Sint16 addend2: Sint16 def __init__(self, addend1: int = 0, addend2: int = 0): self.addend1 = Sint16(addend1) self.addend2 = Sint16(addend2) @dataclass class Sum(SomeIpPayload): value: Sint32 def __init__(self): self.value = Sint32() Details on defining data types can be found :doc:`here `. Step 3: Implementing the Method Handler --------------------------------------- In the next step, we will implement the method handler. This function will receive a ``bytes`` object and a Tuple with the caller's IP address and port. The received ``bytes`` object will be deserialized into an ``Addends`` object. After calculating the sum, the ``Sum`` object will be serialized and returned. The method handler has to return a ``MethodResult`` object which has the following members: - message_type (``MessageType``): The MessageType is an enum and can be either ``MessageType.RESPONSE`` or ``MessageType.ERROR``. You can use ``MessageType.ERROR`` if you want to indicate an application-specific error and send an explicit error message. Then you can also add a payload, e.g., with an error message. You could also send a ``MessageType.RESPONSE`` with an appropriate ``ReturnCode``. - return_code (``ReturnCode``): The ``ReturnCode`` enum reflects the return codes defined in the `SOME/IP protocol specification `_. For indicating a successful method call to the client, ``E_OK`` is returned. For indicating other errors, one of the other return codes has to be chosen. - payload (``bytes``): The payload to be returned is a ``bytes`` object, i.e., the method handler has to serialize structured messages used for the result. someipy will not internally serialize the data. For details about error handling in SOME/IP, read chapter 4.2.6 in the `SOME/IP protocol specification `_. The method handler is an asynchronous function (``async def``). This allows for I/O-bound calls using ``await`` inside the method handler, e.g., calling another SOME/IP method or querying from a database, without blocking other tasks or method handlers from running. .. code-block:: python async def add_method_handler(input_data: bytes, addr: Tuple[str, int]) -> MethodResult: print( f"Received data: {' '.join(f'0x{b:02x}' for b in input_data)} from IP: {addr[0]} Port: {addr[1]}" ) result = MethodResult() try: # Deserialize the input data addends = Addends() addends.deserialize(input_data) except Exception as e: print(f"Error during deserialization: {e}") # Set the return code to E_MALFORMED_MESSAGE and return result.message_type = MessageType.RESPONSE result.return_code = ReturnCode.E_MALFORMED_MESSAGE return result # Perform the addition sum = Sum() sum.value = Sint32(addends.addend1.value + addends.addend2.value) print(f"Send back: {' '.join(f'0x{b:02x}' for b in sum.serialize())}") result.message_type = MessageType.RESPONSE result.return_code = ReturnCode.E_OK result.payload = sum.serialize() return result Step 4: Definition of the Service ---------------------------------- In order to offer a service containing a SOME/IP method, we will instantiate a ``Method`` and a ``Service`` object. The ``Method`` class holds the method ID and the reference to the method handler function. The ``Service`` object contains the ``Method`` objects and is used afterwards to instantiate a ``ServerServiceInstance``. The ``Service`` will contain a single method with ID 0x1234. The ``ServiceBuilder`` class is used to create the ``Service`` object. It's also possible to define multiple ``Method``s and add them all to the ``Service``. The ``with_method`` function can be called multiple times on the ``ServiceBuilder`` object. .. code-block:: python SAMPLE_SERVICE_ID = 0x1234 addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.UDP, method_handler=add_method_handler, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) Step 5: Instantiate the Service ------------------------------- The previously defined ``Service`` can be instantiated as one or multiple service instances. Since we are offering a method as a server, a ``ServerServiceInstance`` object is created. The constructor of the ``ServerServiceInstance`` class requires several parameters: - daemon: The *someipy_daemon* object (defined above) - service: The *Service* object (defined above) - instance_id: A service instance ID (0x5678 in this example) - endpoint_ip: The IP address of the network interface on which the service is offered (127.0.0.1 in this example) - endpoint_port: The port on which the service is offered (3000 in this example) - ttl: The time-to-live for the service discovery entries (5 seconds in this example) - cyclic_offer_delay_ms: The period of the cyclic offer service SD messages (2000 ms in this example) .. code-block:: python SAMPLE_INSTANCE_ID = 0x5678 service_instance_addition = ServerServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) Step 6: Announce the Service via Service Discovery -------------------------------------------------- The next step is to use ``start_offer`` to announce the service instance to potential clients. The ``start_offer`` function will communicate with the someipy daemon which will take care of periodically sending service discovery messages with offer entries. .. code-block:: python await service_instance_addition.start_offer() Step 7: Shutdown the Application --------------------------------- At the end of your application, make sure to stop offering the service instance and disconnect from the someipy daemon to ensure a clean shutdown of the application. .. code-block:: python await service_instance_temperature.stop_offer() await someipy_daemon.disconnect_from_daemon() someipy-2.1.2/docs/requirements.txt000066400000000000000000000001011513043235100174020ustar00rootroot00000000000000sphinx==7.1.2 sphinx-rtd-theme==1.3.0 sphinx-autobuild==2021.3.14someipy-2.1.2/docs/service_discovery.rst000066400000000000000000000076271513043235100204230ustar00rootroot00000000000000Service Discovery Configuration Parameters ========================================== What is SOME/IP Service Discovery (SD)? --------------------------------------- To use a SOME/IP service, a client must know the service location—the IP address and port where the service can be accessed. A server providing a service must know the recipients of event messages. Events are delivered only to subscribers (publish-subscribe). SOME/IP SD provides these capabilities: - Locating service instances - Handling publish-subscribe behavior SD uses UDP multicast. By joining the multicast group, applications can listen to or send SD messages. .. image:: images/service_discovery/multicast_service_discovery.png :align: center The offering application periodically sends a SOME/IP SD message containing an offer entry to all multicast participants. The offer entry includes the service location (IP and port), instance ID, service ID, major and minor versions, and a TTL for the offer. Subscribers can send back a SOME/IP SD subscribe entry for the eventgroup, including the instance ID, service ID, major version, eventgroup ID, the subscription TTL, and the client endpoint (IP and port). The server responds with a subscribe_acknowledge entry. This handshake implements publish-subscribe. The actual event messages are delivered to the subscribers. An alternative is to send a find_service entry to query whether a participant offers a specific service. If offered, the participant responds with an offer_service entry, after which subscription proceeds as above. Participants can also send stop_offer entries to indicate shutdown. SD messages are SOME/IP messages marked with specific magic numbers. For example, the message ID is 0xFFFF81000 and the protocol and interface version are 0x01. The SOME/IP SD protocol specification is available `here `_. Service Discovery Parameters in the someipy Daemon ---------------------------------------------------- As shown in the someipy Daemon guide, the daemon handles all communication with the SOME/IP network, including service discovery, and uses a specific configuration for SD messages. The configuration is a JSON file with optional parameters: .. code-block:: json { "sd_address": "224.224.224.245", "sd_port": 30490, "interface": "127.0.0.1", } - ``sd_address``: Multicast address for SD. Default: "224.224.224.245". - ``sd_port``: SD port. Default: 30490. - ``interface``: Network interface IP the daemon listens on. Default: "127.0.0.1". Server-Side Parameters ---------------------- Offering a service uses ``ServerServiceInstance``. The constructor accepts SD-related parameters: .. code-block:: python service_instance_temperature = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) - ``ttl``: Lifetime of the SD offer entries in seconds. The offer entries are repeated while valid. - ``cyclic_offer_delay_ms``: Interval in milliseconds between consecutive SD offer messages. Ensure ``ttl`` > ``cyclic_offer_delay_ms``; otherwise the service may appear unavailable briefly (for example, ttl=1 s and cyclic_offer_delay_ms=2000 ms). Client-Side Parameters ---------------------- When subscribing to eventgroups as a client, the subscription lifetime is set with ``ttl_subscription_seconds`` in ``subscribe_eventgroup``. If not renewed, the subscription will be removed after this period. Ensure ``ttl_subscription_seconds`` > ``cyclic_offer_delay_ms``; otherwise, the subscription may be removed before the next offer and events will not be delivered. .. code-block:: python service_instance_temperature.subscribe_eventgroup(temperature_eventgroup, ttl_subscription_seconds=5.0) someipy-2.1.2/docs/service_interface.rst000066400000000000000000000150371513043235100203460ustar00rootroot00000000000000SOME/IP Service Interface Data Types ==================================== Defining a common SOME/IP service interface datatype is essential for service-oriented communication between ECUs (and other middleware). It ensures all participants interpret raw bytes consistently and can serialize data back for transmission. The `SOME/IP protocol specification `_ defines the on-wire format. You do not need to manage it directly; someipy provides Python types and serializers to convert between Python objects and bytes. SOME/IP Interface Datatype Definition in Python ----------------------------------------------- Many middlewares, such as `ROS (Robot Operating System) `_ or `OpenDDS `_, use language-agnostic interface descriptions to define data structures. ROS uses .msg files; OpenDDS uses .idl files. Source code is typically generated from these definitions. With someipy, data types can be defined directly in Python, either in the application file or in separate modules imported by the application. Prefer a separate file per datatype. Defining Datatypes in someipy ----------------------------- Custom SOME/IP data types can be defined directly in Python. All datatype-related classes and functions can be imported from the ``someipy.serialization`` module. To use an unsigned 8-bit datatype: .. code-block:: python from someipy.serialization import Uint8 All supported data types are listed in the table at the end of this article. If you need a single value, you can use the basic datatypes directly (e.g., Uint8). For most scenarios, you will define structured types (dataclasses) by subclassing SomeIpPayload. Defining Datatypes using SomeIpPayload ------------------------------------- As described above, you can define custom SOME/IP data types in Python. All datatype-related classes and functions reside in the someipy.serialization module. To define a structured type, subclass SomeIpPayload. For example: .. code-block:: python from dataclasses import dataclass from someipy.serialization import ( SomeIpPayload, Uint64, Float32, ) @dataclass class TemperatureMsg(SomeIpPayload): timestamp: Uint64 temperature: Float32 def __init__(self): self.timestamp = Uint64() self.temperature = Float32() Note: Using @dataclass provides auto-generated __repr__ and __eq__. The TemperatureMsg class can be serialized and deserialized with the base class methods: - serialize(self) -> bytes - deserialize(self, payload: bytes) -> TemperatureMsg Serialize is used to send data (e.g., events or method calls). Example: .. code-block:: python # Create a new instance of TemperatureMsg and fill some dummy values tmp_msg = TemperatureMsg() tmp_msg.timestamp = Uint64(10) tmp_msg.temperature = Float32(20.0) payload = tmp_msg.serialize() service_instance_temperature.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) Deserialize is used when receiving a bytes payload to interpret as TemperatureMsg. Example callback: .. code-block:: python def temperature_callback(someip_message: SomeIpMessage) -> None: """ Callback function that is called when a temperature message is received. Args: someip_message (SomeIpMessage): The SomeIpMessage object containing the received message consisting of a header and payload. Returns: None: This function does not return anything. """ try: print(f"Received {len(someip_message.payload)} bytes. Deserializing...") temperature_msg = TemperatureMsg().deserialize(someip_message.payload) print(temperature_msg) except Exception as e: print(f"Error in deserialization: {e}") Note: The ``deserialize`` call is wrapped in a try-except block to prevent crashes from malformed data. This improves robustness. Updating Values --------------- In the example above, the timestamp and temperature fields are initialized with Uint64(10) and Float32(20.0). Do not assign plain integers directly (e.g., tmp_msg.timestamp = 10); these literals are not compatible with the typed fields. Use the typed constructors and then serialize. .. code-block:: python tmp_msg = TemperatureMsg() tmp_msg.timestamp = Uint64(10) tmp_msg.temperature = Float32(20.0) payload = tmp_msg.serialize() Directly modifying the value field is also supported: .. code-block:: python tmp_msg.timestamp.value = 10 When accessing ``value``, the numeric literal can be directly assigned. Nesting Structured Data Types ----------------------------- You can nest structured types that derive from SomeIpPayload. For example, define a Version datatype and nest it inside TemperatureMsg: .. code-block:: python @dataclass class Version(SomeIpPayload): major: Uint8 minor: Uint8 def __init__(self): self.major = Uint8() self.minor = Uint8() @dataclass class TemperatureMsg(SomeIpPayload): version: Version timestamp: Uint64 temperature: Float32 def __init__(self): self.version = Version() self.version.major.value = 1 self.version.minor.value = 0 self.timestamp = Uint64() self.temperature = Float32() .. _someipy-datatypes: Supported SOME/IP Data Types in someipy --------------------------------------- The following table lists all supported SOME/IP data types and their respective classes in someipy. All the types are part of the module ``someipy.serialization``. For inquiries about support for additional data types, contact us at: - someipy.package@gmail.com - `LinkedIn `_ .. list-table:: SOME/IP Data Types :header-rows: 1 :widths: 50 50 * - SOME/IP Data Type - someipy Data Type * - boolean - Uint8 * - uint8 - Uint8 * - uint16 - Uint16 * - uint32 - Uint32 * - uint64 - Uint64 * - sint8 - Sint8 * - sint16 - Sint16 * - sint32 - Sint32 * - sint64 - Sint64 * - float32 - Float32 * - float64 - Float64 * - structs - SomeIpPayload * - fixed-length strings - SomeIpFixedSizeString * - dynamic-length strings - SomeIpDynamicSizeString * - arrays (fixed-length) - SomeIpFixedSizeArray * - arrays (dynamic-length) - SomeIpDynamicSizeArray * - union - not supported someipy-2.1.2/docs/someipy_daemon.rst000066400000000000000000000036131513043235100176730ustar00rootroot00000000000000someipy Daemon ================= The someipy daemon is a background process responsible for managing all communication with the SOME/IP network, including service discovery. Applications using the someipy library do not need to handle network communication directly, as the daemon manages these complexities. A single daemon instance should be running per ECU or PC. Applications interact with the daemon via Unix Domain Sockets (UDS). Starting the Daemon --------------------- The someipy daemon can be started from the command line. After installing the library with `pip3 install someipy`, the `someipyd` command becomes available in your system's PATH. To start the daemon, simply run: .. code-block:: bash someipyd Optionally, you can specify a path to a configuration file using the `--config` argument: .. code-block:: bash someipyd --config /path/to/config.json The configuration file is a JSON file that allows you to customize the daemon's behavior. The following fields are available and all are optional: .. code-block:: json { "sd_address": "224.224.224.245", "sd_port": 30490, "log_level": "DEBUG", "interface": "127.0.0.2", "log_path": "/var/log/someipy.log", "use_tcp": false, "tcp_host": "127.0.0.1", "tcp_port": 30500 - ``sd_address``: The multicast address for Service Discovery. - ``sd_port``: The port for Service Discovery. - ``log_level``: The logging level (e.g., DEBUG, INFO, WARNING, ERROR). - ``interface``: The network interface to bind to. - ``log_path``: The path to the log file. - ``use_tcp``: Whether to use TCP sockets instead of UDS sockets for communication between the daemon and clients. If Windows is used `use_tcp` must be set to true. - ``tcp_host``: The host address for TCP communication (only relevant if `use_tcp` is true). - ``tcp_port``: The port for TCP communication (only relevant if `use_tcp` is true).someipy-2.1.2/docs/subscribing_events.rst000066400000000000000000000137731513043235100205710ustar00rootroot00000000000000Subscribing to SOME/IP Events ============================= SOME/IP Events -------------- SOME/IP events implement the publish-subscribe concept in SOME/IP. A server offers a service to which one or more clients can subscribe. When the server sends an event, all subscribed clients will receive the event. A SOME/IP event is identified through an event ID which is packed into the header of a SOME/IP message. The event ID can be used by multiple services and does not have to be globally unique. The unique identification of an event comes through the combination of service ID, instance ID, and event ID. A SOME/IP event usually carries a serialized payload. For defining the service interface data types and serializing structured data into ``bytes`` follow the article on :doc:`service_interface`. SOME/IP SD Eventgroups vs. SOME/IP Events ------------------------------------------ In SOME/IP there is also the definition of Eventgroups. It is important to understand the difference for setting up a proper SOME/IP communication. If eventgroup and event IDs are mixed up, the service discovery will not be able to subscribe properly. Eventgroups are only used in **service discovery of SOME/IP** and logically group events together for subscription. Eventgroups only exist at the service discovery level, but never appear in the actual data sent for an event. Once a client subscribed to a service, eventgroups are obsolete. Grouping events in eventgroups allows clients to subscribe to multiple events at once. For that purpose you could put all your events into a single eventgroup. Then a client can subscribe only to a single eventgroup and will receive notifications for all events. This has the advantage of reduced traffic for service discovery. However, since all events are sent to the client, more bandwidth is used for sending the actual data. If you want to enable clients to subscribe to single events, create a single eventgroup for each event. Then a client can granularly subscribe to single events. This will require more service discovery traffic; however, it may lead to sending only events that are actually used. Step 1: Connect to the someipy Daemon ------------------------------------------------ The first step is to connect to the someipy daemon. The daemon is a separate process communicating with the application using someipy via a Unix Domain Socket (UDS). The daemon is responsible for handling all communication with the SOME/IP network, including service discovery and message sending/receiving. .. code-block:: python someipy_daemon = await connect_to_someipy_daemon() In case, a non-default Unix Domain Socket path is used, a config dictionary can be passed to the *connect_to_someipy_daemon* function. Step 2: Define a Service ------------------------ In order to subscribe to a service containing a SOME/IP event, we will define a ``Service`` first. The ``Service`` object will be used afterwards to construct a ``ClientServiceInstance`` object. The ``Service`` we define contains a single event with ID 0x0123 belonging to the eventgroup with ID 0x0321. The ``ServiceBuilder`` class is used to build the ``Service`` object for convenience. .. code-block:: python from someipy import ServiceBuilder, EventGroup, Event, TransportLayerProtocol SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.UDP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) Step 3: Instantiate the Service ------------------------------- The previously defined ``Service`` can be instantiated as a ``ClientServiceInstance``. This instance will be used to subscribe to the eventgroup and receive events. The ``endpoint_ip`` and ``endpoint_port`` parameters are the IP address and port on which the events shall be received. .. code-block:: python from someipy.client_service_instance import ClientServiceInstance service_instance_temperature = ClientServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) Step 4: Register a Notification Callback Function ------------------------------------------------- Register a callback function that will be called when an event notification is received. The callback receives the event ID and payload bytes: .. code-block:: python def temperature_callback(event_id: int, event_payload: bytes) -> None: try: print(f"Received {len(event_payload)} bytes for event 0x{event_id:04x}") temperature_msg = TemperatureMsg().deserialize(event_payload) print(temperature_msg) except Exception as e: print(f"Error in deserialization: {e}") service_instance_temperature.register_callback(temperature_callback) Step 5: Activate Subscription ----------------------------- Subscribe to the eventgroup with a time-to-live (TTL) for the subscription: .. code-block:: python service_instance_temperature.subscribe_eventgroup(temperature_eventgroup, 5.0) The TTL defines how long the subscription is valid. After this time, the subscription will be automatically removed unless it is renewed. The details of the service discovery parameters are described in :doc:`service_discovery`. Step 6: Maintain Connection --------------------------- Keep the application running to maintain the connection and receive events. At the end of your application, make sure to disconnect from the someipy daemon to ensure a clean shutdown of the application. .. code-block:: python try: await asyncio.Future() # Run forever except asyncio.CancelledError: print("Shutting down...") finally: await someipy_daemon.disconnect_from_daemon() someipy-2.1.2/docs/whatsnew.rst000066400000000000000000000056711513043235100165310ustar00rootroot00000000000000someipy v2: What's New ========================= This page outlines the new features and changes introduced in version 2 of the `someipy` Python package. Version 2 introduces a new architecture and a refined application API, addressing limitations present in version 1.0. New Architecture ---------------- `someipy` v2 features a redesigned architecture that eliminates key weaknesses of the previous version. In v1, each application utilizing `someipy` required its own network interface. Version 2 centralizes network interface handling within a dedicated `someipyd` daemon. - **someipyd Daemon:** A new `someipyd.py` daemon is introduced to manage all communication, including: - SOME/IP service discovery via UDP multicast and unicast. - SOME/IP message exchange (methods, events, fields). - **Unix Domain Socket Communication:** Applications using `someipy` communicate with the `someipyd` daemon via Unix Domain Sockets, eliminating the need for direct network access. - **Centralized Network Handling:** The `someipyd` daemon handles all network communication, allowing applications to remain lightweight and focused on application logic. - **Scalability:** Each ECU or PC can run a single `someipyd` daemon, supporting an arbitrary number of applications. .. image:: images/someipy_v2_architecture.png :alt: someipy v2 Architecture The diagram above illustrates the new architecture, showcasing the central role of the `someipyd` daemon in managing all SOME/IP communication. New Application API ------------------- The application API has been streamlined for ease of use and flexibility. The following snippets demonstrate the core elements of the new API: .. code-block:: python someipy_daemon = await connect_to_someipy_daemon() Establish a connection to the someipyd daemon. .. code-block:: python addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.UDP, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) Define a service with its methods, eventgroups, and events. .. code-block:: python client_instance_addition = ClientServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) Construct a ClientServiceInstance for service interaction. .. code-block:: python method_parameter = Addends(addend1=1, addend2=2) method_result = await client_instance_addition.call_method( SAMPLE_METHOD_ID, method_parameter.serialize() ) sum = Sum().deserialize(method_result.payload) print(f"Sum: {sum.value.value}") Prepare method parameters, call the method, and deserialize the result. .. code-block:: python await someipy_daemon.disconnect_from_daemon() Disconnect from the daemon. someipy-2.1.2/example_apps/000077500000000000000000000000001513043235100156545ustar00rootroot00000000000000someipy-2.1.2/example_apps/addition_method_parameters.py000066400000000000000000000014601513043235100236050ustar00rootroot00000000000000from dataclasses import dataclass from someipy.serialization import ( Sint32, Sint16, SomeIpPayload, ) # In this example we define two method parameter types used for the Addition method example. # In theory, Int16 and Sint32 types could be used directly instead of defining new classes, # but this way the code is more readable and the types are more descriptive and extensible, i.e. # you could other information such as version or metadata to the method parameters. @dataclass class Addends(SomeIpPayload): addend1: Sint16 addend2: Sint16 def __init__(self, addend1: int = 0, addend2: int = 0): self.addend1 = Sint16(addend1) self.addend2 = Sint16(addend2) @dataclass class Sum(SomeIpPayload): value: Sint32 def __init__(self): self.value = Sint32() someipy-2.1.2/example_apps/call_method_tcp.py000066400000000000000000000074571513043235100213640ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( TransportLayerProtocol, MessageType, ReturnCode, connect_to_someipy_daemon, ClientServiceInstance, Method, ServiceBuilder, ) from someipy.someipy_logging import set_someipy_log_level from addition_method_parameters import Addends, Sum SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_METHOD_ID = 0x0123 async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.TCP, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) # For calling methods construct a ClientServiceInstance client_instance_addition = ClientServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) method_parameter = Addends(addend1=1, addend2=2) try: while not await client_instance_addition.is_available(): await asyncio.sleep(0.5) while True: try: # The call_method function can raise an error, e.g. if no TCP connection to the server can be established # In case there is an application specific error in the server, the server still returns a response and the # message_type and return_code are evaluated. print( f"Try to call method: {SAMPLE_METHOD_ID} with parameter: {method_parameter.serialize()}" ) method_result = await client_instance_addition.call_method( SAMPLE_METHOD_ID, method_parameter.serialize() ) if method_result.message_type == MessageType.RESPONSE: print( f"Received result for method: {' '.join(f'0x{b:02x}' for b in method_result.payload)}" ) if method_result.return_code == ReturnCode.E_OK: sum = Sum().deserialize(method_result.payload) print(f"Sum: {sum.value.value}") else: print( f"Method call returned an error: {method_result.return_code}" ) elif method_result.message_type == MessageType.ERROR: print("Server returned an error..") # In case the server includes an error message in the payload, it can be deserialized and printed except Exception as e: print(f"Error during method call: {e}") await asyncio.sleep(1) except asyncio.CancelledError: print("Shutdown..") finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/call_method_udp.py000066400000000000000000000074631513043235100213630ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( TransportLayerProtocol, MessageType, ReturnCode, connect_to_someipy_daemon, ClientServiceInstance, Method, ServiceBuilder, ) from someipy.someipy_logging import set_someipy_log_level from addition_method_parameters import Addends, Sum SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_METHOD_ID = 0x0123 async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.UDP, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) # For calling methods construct a ClientServiceInstance client_instance_addition = ClientServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) try: while not await client_instance_addition.is_available(): await asyncio.sleep(0.5) method_parameter = Addends(addend1=1, addend2=2) while True: try: # The call_method function can raise an error, e.g. if no TCP connection to the server can be established # In case there is an application specific error in the server, the server still returns a response and the # message_type and return_code are evaluated. print( f"Try to call method: {SAMPLE_METHOD_ID} with parameter: {method_parameter.serialize()}" ) method_result = await client_instance_addition.call_method( SAMPLE_METHOD_ID, method_parameter.serialize() ) if method_result.message_type == MessageType.RESPONSE: print( f"Received result for method: {' '.join(f'0x{b:02x}' for b in method_result.payload)}" ) if method_result.return_code == ReturnCode.E_OK: sum = Sum().deserialize(method_result.payload) print(f"Sum: {sum.value.value}") else: print( f"Method call returned an error: {method_result.return_code}" ) elif method_result.message_type == MessageType.ERROR: print("Server returned an error..") # In case the server includes an error message in the payload, it can be deserialized and printed except Exception as e: print(f"Error during method call: {e}") await asyncio.sleep(1) except asyncio.CancelledError: print("Shutdown..") finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/offer_method_tcp.py000066400000000000000000000070751513043235100215460ustar00rootroot00000000000000import asyncio import ipaddress import logging import sys from typing import Tuple from someipy import ( TransportLayerProtocol, MethodResult, ReturnCode, MessageType, ServerServiceInstance, connect_to_someipy_daemon, ServiceBuilder, Method, ) from someipy.someipy_logging import set_someipy_log_level from someipy.serialization import Sint32 from addition_method_parameters import Addends, Sum DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_METHOD_ID = 0x0123 async def add_method_handler(input_data: bytes, addr: Tuple[str, int]) -> MethodResult: print( f"Received data: {' '.join(f'0x{b:02x}' for b in input_data)} from IP: {addr[0]} Port: {addr[1]}" ) result = MethodResult() try: # Deserialize the input data addends = Addends() addends.deserialize(input_data) except Exception as e: print(f"Error during deserialization: {e}") # Set the return code to E_MALFORMED_MESSAGE and return result.message_type = MessageType.RESPONSE result.return_code = ReturnCode.E_MALFORMED_MESSAGE return result # Perform the addition sum = Sum() sum.value = Sint32(addends.addend1.value + addends.addend2.value) print(f"Send back: {' '.join(f'0x{b:02x}' for b in sum.serialize())}") result.message_type = MessageType.RESPONSE result.return_code = ReturnCode.E_OK result.payload = sum.serialize() return result async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.TCP, method_handler=add_method_handler, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) # For offering methods use a ServerServiceInstance service_instance_addition = ServerServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) # After constructing ServerServiceInstances the start_offer method has to be called. # This will start an internal timer, which will periodically send # Offer service entries with a period of "cyclic_offer_delay_ms" print("Start offering service..") await service_instance_addition.start_offer() try: # Keep the task alive await asyncio.Future() except asyncio.CancelledError: print("Stop offering service..") await service_instance_addition.stop_offer() finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/offer_method_udp.py000066400000000000000000000070751513043235100215500ustar00rootroot00000000000000import asyncio import ipaddress import logging import sys from typing import Tuple from someipy import ( TransportLayerProtocol, MethodResult, ReturnCode, MessageType, connect_to_someipy_daemon, ServerServiceInstance, ServiceBuilder, Method, ) from someipy.someipy_logging import set_someipy_log_level from someipy.serialization import Sint32 from addition_method_parameters import Addends, Sum DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_METHOD_ID = 0x0123 async def add_method_handler(input_data: bytes, addr: Tuple[str, int]) -> MethodResult: print( f"Received data: {' '.join(f'0x{b:02x}' for b in input_data)} from IP: {addr[0]} Port: {addr[1]}" ) result = MethodResult() try: # Deserialize the input data addends = Addends() addends.deserialize(input_data) except Exception as e: print(f"Error during deserialization: {e}") # Set the return code to E_MALFORMED_MESSAGE and return result.message_type = MessageType.RESPONSE result.return_code = ReturnCode.E_MALFORMED_MESSAGE return result # Perform the addition sum = Sum() sum.value = Sint32(addends.addend1.value + addends.addend2.value) print(f"Send back: {' '.join(f'0x{b:02x}' for b in sum.serialize())}") result.message_type = MessageType.RESPONSE result.return_code = ReturnCode.E_OK result.payload = sum.serialize() return result async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) addition_method = Method( id=SAMPLE_METHOD_ID, protocol=TransportLayerProtocol.UDP, method_handler=add_method_handler, ) addition_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_method(addition_method) .build() ) # For offering methods use a ServerServiceInstance service_instance_addition = ServerServiceInstance( daemon=someipy_daemon, service=addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) # After constructing ServerServiceInstances the start_offer method has to be called. # This will start an internal timer, which will periodically send # Offer service entries with a period of "cyclic_offer_delay_ms" print("Start offering service..") await service_instance_addition.start_offer() try: # Keep the task alive await asyncio.Future() except asyncio.CancelledError: print("Stop offering service..") await service_instance_addition.stop_offer() finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/offer_multiple_services.py000066400000000000000000000107541513043235100231540ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( TransportLayerProtocol, ServiceBuilder, EventGroup, connect_to_someipy_daemon, ServerServiceInstance, Event, ) from someipy.someipy_logging import set_someipy_log_level from someipy.serialization import Uint8, Uint64, Float32 from temperature_msg import TemparatureMsg SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID_1 = 0x5678 SAMPLE_INSTANCE_ID_2 = 0x6789 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 """ This application demonstrates how to offer multiple services on different endpoints. For simplicity and keeping the example short, it uses the same service, event group and event ID for both instances. Only the instance ID and the port offers. Both instances send an event via UDP to subscribed clients. """ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.UDP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) # For sending events use a ServerServiceInstance service_instance_temperature_1 = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID_1, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) service_instance_temperature_2 = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID_2, endpoint_ip=interface_ip, endpoint_port=3001, ttl=5, cyclic_offer_delay_ms=2000, ) print("Start offering services..") await service_instance_temperature_1.start_offer() await service_instance_temperature_2.start_offer() tmp_msg = TemparatureMsg() # Reminder: Do NOT use "tmp_msg.version.major = 1". Always use the provided classes in someipy like Uint8, # so that the data can be propery serialized. Python literals won't be serialized properly tmp_msg.version.major = Uint8(1) tmp_msg.version.minor = Uint8(0) tmp_msg.measurements.data[0] = Float32(20.0) tmp_msg.measurements.data[1] = Float32(21.0) tmp_msg.measurements.data[2] = Float32(22.0) tmp_msg.measurements.data[3] = Float32(23.0) try: # Either cyclically send events in an endless loop.. while True: await asyncio.sleep(0.5) tmp_msg.timestamp = Uint64(tmp_msg.timestamp.value + 1) payload = tmp_msg.serialize() # Send out an event on the first instance service_instance_temperature_1.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) # Sleep for half a second and send out an event on the second service instance await asyncio.sleep(0.5) service_instance_temperature_2.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) # .. or in case your app is waiting for external events like method calss, # use await asyncio.Future() to keep the task alive # await asyncio.Future() except asyncio.CancelledError: print("Stop offering services..") await service_instance_temperature_1.stop_offer() await service_instance_temperature_2.stop_offer() finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/receive_events_tcp.py000066400000000000000000000071541513043235100221110ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( ServiceBuilder, EventGroup, SomeIpMessage, TransportLayerProtocol, ClientServiceInstance, connect_to_someipy_daemon, Event, ) from someipy.someipy_logging import set_someipy_log_level from temperature_msg import TemparatureMsg SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 def temperature_callback(event_id: int, event_payload: bytes) -> None: """ Callback function that is called when a temperature message is received. Args: someip_message (SomeIpMessage): The SomeIpMessage object containing the received message. Returns: None: This function does not return anything. """ try: print( f"Received {len(event_payload)} bytes for event 0x{event_id:04x}. Try to deserialize.." ) temperature_msg = TemparatureMsg().deserialize(event_payload) print(temperature_msg) except Exception as e: print(f"Error in deserialization: {e}") async def main(): asyncio.get_running_loop().set_debug(True) # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.TCP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) # For calling methods construct a ClientServiceInstance service_instance_temperature = ClientServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) # You can optionally register a callback function which will be called when an event from the # subscribed event group is received. The callback function will get the bytes of the payload passed which # can be deserialized in the callback function service_instance_temperature.register_callback(temperature_callback) # The second argument is the time to live (TTL) of the subscription in seconds service_instance_temperature.subscribe_eventgroup(temperature_eventgroup, 5) try: # Keep the task alive await asyncio.Future() except asyncio.CancelledError as e: print("Shutdown..") finally: print("Unsubscribe eventgroup..") service_instance_temperature.unsubscribe_eventgroup(temperature_eventgroup) print("Shutdown service instance..") await someipy_daemon.disconnect_from_daemon() print("End main task..") for t in asyncio.all_tasks(): print("----") print(t) if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/receive_events_udp.py000066400000000000000000000071311513043235100221060ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( ServiceBuilder, EventGroup, TransportLayerProtocol, connect_to_someipy_daemon, ClientServiceInstance, Event, ) from someipy.someipy_logging import set_someipy_log_level from temperature_msg import TemparatureMsg SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 def temperature_callback(event_id: int, event_payload: bytes) -> None: """ Callback function that is called when a temperature message is received. Args: someip_message (SomeIpMessage): The SomeIpMessage object containing the received message. Returns: None: This function does not return anything. """ try: print( f"Received {len(event_payload)} bytes for event 0x{event_id:04x}. Try to deserialize.." ) temperature_msg = TemparatureMsg().deserialize(event_payload) print(temperature_msg) except Exception as e: print(f"Error in deserialization: {e}") async def main(): asyncio.get_running_loop().set_debug(True) # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.UDP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) # For calling methods construct a ClientServiceInstance service_instance_temperature = ClientServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3002, ) # You can optionally register a callback function which will be called when an event from the # subscribed event group is received. The callback function will get the bytes of the payload passed which # can be deserialized in the callback function service_instance_temperature.register_callback(temperature_callback) # The second argument is the time to live (TTL) of the subscription in seconds service_instance_temperature.subscribe_eventgroup(temperature_eventgroup, 5) try: # Keep the task alive await asyncio.Future() except asyncio.CancelledError as e: print("Shutdown..") finally: print("Unsubscribe eventgroup..") service_instance_temperature.unsubscribe_eventgroup(temperature_eventgroup) print("Shutdown service instance..") await someipy_daemon.disconnect_from_daemon() print("End main task..") for t in asyncio.all_tasks(): print("----") print(t) if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/rosbags/000077500000000000000000000000001513043235100173145ustar00rootroot00000000000000someipy-2.1.2/example_apps/rosbags/Pose.msg000066400000000000000000000004221513043235100207300ustar00rootroot00000000000000# This is the original ROS message for topic "/turtle1/pose" contained in "test.bag" # This ROS message is just added for demonstration purposes, but not needed for running replay_rosbags.py float32 x float32 y float32 theta float32 linear_velocity float32 angular_velocitysomeipy-2.1.2/example_apps/rosbags/TurtlesimPose.py000066400000000000000000000010751513043235100225100ustar00rootroot00000000000000from someipy.serialization import SomeIpPayload, Float32 # For defining the TurtleSimPose as a SOME/IP message, simply inherit from SomeIpPayload and use # the provided datatypes such as Float32 for declaring the fields of the message class TurtlesimPose(SomeIpPayload): x: Float32 y: Float32 theta: Float32 linear_velocity: Float32 angular_velocity: Float32 def __init__(self): self.x = Float32() self.y = Float32() self.theta = Float32() self.linear_velocity = Float32() self.angular_velocity = Float32() someipy-2.1.2/example_apps/rosbags/replay_rosbag.py000066400000000000000000000106621513043235100225240ustar00rootroot00000000000000import asyncio import ipaddress import logging import rosbag import TurtlesimPose from someipy import ( TransportLayerProtocol, ServiceBuilder, EventGroup, construct_server_service_instance, ) from someipy.service_discovery import construct_service_discovery from someipy.someipy_logging import set_someipy_log_level from someipy.serialization import Float32 SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 INTERFACE_IP = "127.0.0.1" SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 SAMPLE_EVENTGROUP_ID = 0x0321 SAMPLE_EVENT_ID = 0x0123 """ Warning: This example still runs on the old someipy API, which is deprecated. """ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Since the construction of the class ServiceDiscoveryProtocol is not trivial and would require an async __init__ function # use the construct_service_discovery function # The local interface IP address needs to be passed so that the src-address of all SD UDP packets is correctly set service_discovery = await construct_service_discovery( SD_MULTICAST_GROUP, SD_PORT, INTERFACE_IP ) turtle_eventgroup = EventGroup(id=SAMPLE_EVENTGROUP_ID, event_ids=[SAMPLE_EVENT_ID]) turtle_pose_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(turtle_eventgroup) .build() ) # For sending events use a ServerServiceInstance service_instance_turtle_pose = await construct_server_service_instance( turtle_pose_service, instance_id=SAMPLE_INSTANCE_ID, endpoint=( ipaddress.IPv4Address(INTERFACE_IP), 3000, ), # src IP and port of the service ttl=5, sd_sender=service_discovery, cyclic_offer_delay_ms=2000, protocol=TransportLayerProtocol.UDP, ) # The service instance has to be attached always to the ServiceDiscoveryProtocol object, so that the service instance # is notified by the ServiceDiscoveryProtocol about e.g. subscriptions from other ECUs service_discovery.attach(service_instance_turtle_pose) # ..it's also possible to construct another ServerServiceInstance and attach it to service_discovery as well # After constructing and attaching ServerServiceInstances to the ServiceDiscoveryProtocol object the # start_offer method has to be called. This will start an internal timer, which will periodically send # Offer service entries with a period of "cyclic_offer_delay_ms" which has been passed above print("Start offering service..") service_instance_turtle_pose.start_offer() bag = rosbag.Bag("test.bag") # Get the timestamp of the first message of /turtle1/pose in order to reproduce the timing of the recording starting_timestamp = next(bag.read_messages(topics=["/turtle1/pose"])).timestamp for topic, msg, t in bag.read_messages(topics=["/turtle1/pose"]): # Calculate the time difference between the current message and the message before time_sleep = (t - starting_timestamp).to_sec() # Use asyncio.sleep to wait for the time difference between the current message and the message before print(f"Sleeping for {(t - starting_timestamp).to_sec()} seconds") await asyncio.sleep(time_sleep) # Create a SomeIpPayload object and fill it with the values from the rosbag message someipPose = TurtlesimPose.TurtlesimPose() someipPose.x = Float32(msg.x) someipPose.y = Float32(msg.y) someipPose.theta = Float32(msg.theta) someipPose.linear_velocity = Float32(msg.linear_velocity) someipPose.angular_velocity = Float32(msg.angular_velocity) # Serialize the SomeIpPayload object to a byte array payload = someipPose.serialize() print(f"Sending event for message {msg}") # Send the serialized byte array to all subscribers of the event group service_instance_turtle_pose.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) starting_timestamp = t bag.close() await service_instance_turtle_pose.stop_offer() print("Service Discovery close..") service_discovery.close() print("End main task..") if __name__ == "__main__": try: asyncio.run(main()) except KeyboardInterrupt: pass someipy-2.1.2/example_apps/rosbags/test.bag000066400000000000000000010373501513043235100207570ustar00rootroot00000000000000#ROSBAG V2.0 Echunk_count=conn_count=index_pos=Ï.op=» )compression=noneop= size="u"u& conn=op= topic=/rosoutú$callerid=/record_1717323045885203753 latching=1'md5sum=acffd30cd6b6de30f120938c17c593fbjmessage_definition=## ## Severity level constants ## byte DEBUG=1 #debug level byte INFO=2 #general level byte WARN=4 #warning level byte ERROR=8 #error level byte FATAL=16 #fatal/critical level ## ## Fields ## Header header byte level string name # name of the node string msg # message string file # file the message came from string function # function the message came from uint32 line # line the message came from string[] topics # topic names that the node publishes ================================================================================ MSG: std_msgs/Header # Standard metadata for higher-level stamped data types. # This is generally used to communicate timestamped data # in a particular coordinate frame. # # sequence ID: consecutively increasing ID uint32 seq #Two-integer timestamp that is expressed as: # * stamp.sec: seconds (stamp_secs) since epoch (in Python the variable is called 'secs') # * stamp.nsec: nanoseconds since stamp_secs (in Python the variable is called 'nsecs') # time-handling sugar is provided by the client library time stamp #Frame this data is associated with string frame_id topic=/rosouttype=rosgraph_msgs/Log& conn=op= time=%E\fúŸ7Ö%E\fÙ“6/record_1717323045885203753Subscribing to /rosout:/tmp/binarydeb/ros-melodic-rosbag-1.14.13/src/recorder.cpp7shared_ptr rosbag::Recorder::subscribeÿ/rosout& conn=op= time=%E\f+ë7Ú%E\f}±º6/record_1717323045885203753Subscribing to /rosout_agg:/tmp/binarydeb/ros-melodic-rosbag-1.14.13/src/recorder.cpp7shared_ptr rosbag::Recorder::subscribeÿ/rosout& conn=op= time=%E\fÂ7Ü%E\fáðÞ6/record_1717323045885203753Subscribing to /turtle1/pose:/tmp/binarydeb/ros-melodic-rosbag-1.14.13/src/recorder.cpp7shared_ptr rosbag::Recorder::subscribeÿ/rosout& conn=op= topic=/rosoutécallerid=/turtlesim latching=1'md5sum=acffd30cd6b6de30f120938c17c593fbjmessage_definition=## ## Severity level constants ## byte DEBUG=1 #debug level byte INFO=2 #general level byte WARN=4 #warning level byte ERROR=8 #error level byte FATAL=16 #fatal/critical level ## ## Fields ## Header header byte level string name # name of the node string msg # message string file # file the message came from string function # function the message came from uint32 line # line the message came from string[] topics # topic names that the node publishes ================================================================================ MSG: std_msgs/Header # Standard metadata for higher-level stamped data types. # This is generally used to communicate timestamped data # in a particular coordinate frame. # # sequence ID: consecutively increasing ID uint32 seq #Two-integer timestamp that is expressed as: # * stamp.sec: seconds (stamp_secs) since epoch (in Python the variable is called 'secs') # * stamp.nsec: nanoseconds since stamp_secs (in Python the variable is called 'nsecs') # time-handling sugar is provided by the client library time stamp #Frame this data is associated with string frame_id topic=/rosouttype=rosgraph_msgs/Log& conn=op= time=&E\f�¬  ï2ÃD\fŸƒ_  /turtlesim@Oh no! I hit the wall! (Clamping from [x=-0,026739, y=8,427272])9/tmp/binarydeb/ros-melodic-turtlesim-0.9.3/src/turtle.cppTurtle::update©/rosout /turtle1/pose/turtle1/color_sensor, conn=op=topic=/turtle1/poseécallerid=/turtlesim latching=0'md5sum=863b248d5016ca62ea2e895ae5265cf9gmessage_definition=float32 x float32 y float32 theta float32 linear_velocity float32 angular_velocity topic=/turtle1/posetype=turtlesim/Pose& conn=op= time=&E\fúÔñ ý´¿@®Ï}@ ×#?@4 conn=op=topic=/turtle1/color_sensor¶callerid=/turtlesim latching=0'md5sum=353891e354491c51aabe32df673fb446+message_definition=uint8 r uint8 g uint8 b topic=/turtle1/color_sensortype=turtlesim/Color& conn=op= time=&E\fÚîñ EVÿ& conn=op= time=&E\fH-ã A‡À@È@ ×#?@& conn=op= time=&E\f�“ã EVÿ& conn=op= time=&E\fä:× „YÁ@ñ €@ ×#?@& conn=op= time=&E\fe”× EVÿ& conn=op= time=&E\fһΠÈ+Â@~½€@ ×#?@& conn=op= time=&E\f˜Ï ³¸ÿ& conn=op= time=&E\f´«Æ þÂ@ Z�@ ×#?@& conn=op= time=&E\fþ²Æ³¸ÿ& conn=op= time=&E\f®é¿OÐÃ@™ö�@ ×#?@& conn=op= time=&E\fWŒÀ³¸ÿ& conn=op= time=&E\f`­ª“¢Ä@&“‚@ ×#?@& conn=op= time=&E\fä6«EVÿ& conn=op= time=&E\füÕ¢×tÅ@³/ƒ@ ×#?@& conn=op= time=&E\fíA£EVÿ& conn=op= time=&E\fë GÆ@@̃@ ×#?@& conn=op= time=&E\fúœ ³¸ÿ& conn=op= time=&E\fŸæ‰^Ç@Íh„@ ×#?@& conn=op= time=&E\f¥fг¸ÿ& conn=op= time=&E\fÅñƒ¢ëÇ@Z…@ ×#?@& conn=op= time=&E\f*t…³¸ÿ& conn=op= time=&E\fÃ|æ½È@ç¡…@ ×#?@& conn=op= time=&E\f1F}³¸ÿ& conn=op= time=&E\fjQf*�É@t>†@ ×#?@& conn=op= time=&E\fµ—f³¸ÿ& conn=op= time=&E\fE1`mbÊ@Û†@ ×#?@& conn=op= time=&E\fuc`EVÿ& conn=op= time=&E\fB%Y±4Ë@�w‡@ ×#?@& conn=op= time=&E\fq„YEVÿ& conn=op= time=&E\f²$DõÌ@ˆ@ ×#?@& conn=op= time=&E\f¶;D³¸ÿ& conn=op= time=&E\fDÑ=9ÙÌ@©°ˆ@ ×#?@& conn=op= time=&E\fo_>³¸ÿ& conn=op= time=&E\fϦ5|«Í@6M‰@ ×#?@& conn=op= time=&E\fÎ6³¸ÿ& conn=op= time=&E\f½‡À}Î@Ãé‰@ ×#?@& conn=op= time=&E\f°³¸ÿ& conn=op= time=&E\fäuPÏ@P†Š@ ×#?@& conn=op= time=&E\fcREVÿ& conn=op= time=&E\f9ÆH"Ð@Ý"‹@ ×#?@& conn=op= time=&E\fhEVÿ/ conn=op=topic=/turtle1/cmd_velcallerid=/teleop_turtle latching=0'md5sum=9f195f881246fdfa2798d1d3eebca84armessage_definition=# This expresses velocity in free space broken into its linear and angular parts. Vector3 linear Vector3 angular ================================================================================ MSG: geometry_msgs/Vector3 # This represents a vector in free space. # It is only meant to represent a direction. Therefore, it does not # make sense to apply a translation to it (e.g., when applying a # generic rigid transformation to a Vector3, tf2 will only apply the # rotation). If you want your data to be translatable too, use the # geometry_msgs/Point message instead. float64 x float64 y float64 z topic=/turtle1/cmd_veltype=geometry_msgs/Twist& conn=op= time=&E\fGè0@& conn=op= time=&E\fØ¡ú‹ôÐ@j¿‹@ ×#?@& conn=op= time=&E\fiDûEVÿ& conn=op= time=&E\f±¯ôÏÆÑ@÷[Œ@ ×#?@& conn=op= time=&E\f}wõ³¸ÿ& conn=op= time=&E\f2· 0@& conn=op= time=&E\f3;í ™Ò@…øŒ@ ×#?@& conn=op= time=&E\fð·í ³¸ÿ& conn=op= time=&E\fø“Ô!VkÓ@•�@ ×#?@& conn=op= time=&E\f¤Ô!³¸ÿ& conn=op= time=&E\fîe†"0@& conn=op= time=&E\fË´Ê"š=Ô@Ÿ1Ž@ ×#?@& conn=op= time=&E\f/.Ë"³¸ÿ& conn=op= time=&E\f™XÃ#ÞÕ@,ÎŽ@ ×#?@& conn=op= time=&E\f½éÃ#EVÿ& conn=op= time=&E\fè7_$0@& conn=op= time=&E\fë,¹$"âÕ@¹j�@ ×#?@& conn=op= time=&E\fW¥¹$EVÿ& conn=op= time=&E\fŸB¬%e´Ö@F�@ ×#?@& conn=op= time=&E\fq·¬%EVÿ& conn=op= time=&E\f‡)&0@& conn=op= time=&E\fc`¤&©†×@Ó£�@ ×#?@& conn=op= time=&E\f‡Œ¤&³¸ÿ& conn=op= time=&E\fþR™'íXØ@`@‘@ ×#?@& conn=op= time=&E\fLÁ™'³¸ÿ& conn=op= time=&E\fBÁþ'0@& conn=op= time=&E\fN"ƒ(1+Ù@íÜ‘@ ×#?@& conn=op= time=&E\f¶÷ƒ(³¸ÿ& conn=op= time=&E\f% {)týÙ@{y’@ ×#?@& conn=op= time=&E\f« |)EVÿ& conn=op= time=&E\f¼Ë)0@& conn=op= time=&E\fáCn*¸ÏÚ@“@ ×#?@& conn=op= time=&E\ff�n*EVÿ& conn=op= time=&E\f#”_+ü¡Û@•²“@ ×#?@& conn=op= time=&E\fê`+EVÿ& conn=op= time=&E\fÈŠ¡+0@& conn=op= time=&E\f¤^,@tÜ@"O”@ ×#?@& conn=op= time=&E\fÜu^,EVÿ& conn=op= time=&E\fQN-ƒFÝ@¯ë”@ ×#?@& conn=op= time=&E\fmCN-³¸ÿ& conn=op= time=&E\fá’-0@& conn=op= time=&E\f�ÕC.ÇÞ@<ˆ•@ ×#?@& conn=op= time=&E\fJD.³¸ÿ& conn=op= time=&E\f¿;/ ëÞ@É$–@ ×#?@& conn=op= time=&E\feY;/³¸ÿ& conn=op= time=&E\f‚Y¥/0@& conn=op= time=&E\f ö)0N½ß@VÁ–@ ×#?@& conn=op= time=&E\f&1*0EVÿ& conn=op= time=&E\fÏWo1’�à@ã]—@ ×#?@& conn=op= time=&E\fŠ»o1EVÿ& conn=op= time=&E\fÏС10@& conn=op= time=&E\f�®2Öaá@qú—@ ×#?@& conn=op= time=&E\fQú2EVÿ& conn=op= time=&E\fOi34â@þ–˜@ ×#?@& conn=op= time=&E\fÇ[p3EVÿ& conn=op= time=&E\fëW›30À& conn=op= time=&E\fiññ34â@þ–˜@ã¥?À& conn=op= time=&E\fD5ò3³¸ÿ& conn=op= time=&E\fÃó44â@þ–˜@¼t?À& conn=op= time=&E\fý÷ó4³¸ÿ& conn=op= time=&E\fJ Û54â@þ–˜@–C ?À& conn=op= time=&E\fáÛ5³¸ÿ& conn=op= time=&E\f}ÀÐ64â@þ–˜@o?À& conn=op= time=&E\f­0Ñ6³¸ÿ& conn=op= time=&E\f»ÕÊ74â@þ–˜@�Âõ>À& conn=op= time=&E\fqË7³¸ÿ& conn=op= time=&E\f`[Å84â@þ–˜@B`å>À& conn=op= time=&E\fßïÅ8³¸ÿ& conn=op= time=&E\f²ˆ´94â@þ–˜@ôýÔ>À& conn=op= time=&E\fêÒ´9³¸ÿ& conn=op= time=&E\f�®�:4â@þ–˜@¦›Ä>À& conn=op= time=&E\f�½�:³¸ÿ& conn=op= time=&E\f**”;4â@þ–˜@X9´>À& conn=op= time=&E\f‘§”;³¸ÿ& conn=op= time='E\f‰Ôñ4â@þ–˜@ ×£>À& conn=op= time='E\fYó³¸ÿ& conn=op= time='E\fŸÃâ4â@þ–˜@¼t“>À& conn=op= time='E\f:�㳸ÿ& conn=op= time='E\f—ß4â@þ–˜@oƒ>À& conn=op= time='E\fbÄ೸ÿ& conn=op= time='E\f4ˆÌ4â@þ–˜@B`e>À& conn=op= time='E\fººÌ³¸ÿ& conn=op= time='E\føòÇ4â@þ–˜@¦›D>À& conn=op= time='E\f.Íɳ¸ÿ& conn=op= time='E\f›å´4â@þ–˜@ ×#>À& conn=op= time='E\fWdµ³¸ÿ& conn=op= time='E\f‘®4â@þ–˜@o>À& conn=op= time='E\f‘ɯ³¸ÿ& conn=op= time='E\fþ½¦4â@þ–˜@¦›Ä=À& conn=op= time='E\fŠö§³¸ÿ& conn=op= time='E\f·ò’4â@þ–˜@oƒ=À& conn=op= time='E\f‘“³¸ÿ& conn=op= time='E\ftE� 4â@þ–˜@o=À& conn=op= time='E\fÄ÷� ³¸ÿ& conn=op= time='E\f´;x 4â@þ–˜@€¥À& conn=op= time='E\fÓy ³¸ÿ& conn=op= time='E\fÞt 4â@þ–˜@o½À& conn=op= time='E\f°t ³¸ÿ& conn=op= time='E\f#.n 4â@þ–˜@oƒ½À& conn=op= time='E\f —o ³¸ÿ& conn=op= time='E\f÷Y 4â@þ–˜@¦›Ä½À& conn=op= time='E\f=–Z ³¸ÿ& conn=op= time='E\fiÅT4â@þ–˜@o¾À& conn=op= time='E\fE÷T³¸ÿ& conn=op= time='E\f6d@4â@þ–˜@ ×#¾À& conn=op= time='E\fXö@³¸ÿ& conn=op= time='E\fª³>4â@þ–˜@¦›D¾À& conn=op= time='E\fÞ?³¸ÿ& conn=op= time='E\f½+4â@þ–˜@B`e¾À& conn=op= time='E\fñq+³¸ÿ& conn=op= time='E\fná%4â@þ–˜@oƒ¾À& conn=op= time='E\f&³¸ÿ& conn=op= time='E\fuÇ4â@þ–˜@¼t“¾À& conn=op= time='E\f‰n³¸ÿ& conn=op= time='E\f!Á4â@þ–˜@ ×£¾À& conn=op= time='E\fɳ¸ÿ& conn=op= time='E\fd«ý4â@þ–˜@X9´¾À& conn=op= time='E\fÌÿ³¸ÿ& conn=op= time='E\fËê4â@þ–˜@¦›Ä¾À& conn=op= time='E\f«Æë³¸ÿ& conn=op= time='E\f@õæ4â@þ–˜@ôýÔ¾À& conn=op= time='E\f£q糸ÿ& conn=op= time='E\fANÑ4â@þ–˜@B`å¾À& conn=op= time='E\füßѳ¸ÿ& conn=op= time='E\f÷HË4â@þ–˜@�Âõ¾À& conn=op= time='E\fL+̳¸ÿ& conn=op= time='E\fµ%¼4â@þ–˜@o¿À& conn=op= time='E\f�ü³¸ÿ& conn=op= time='E\fmz¸4â@þ–˜@–C ¿À& conn=op= time='E\f©õ¸³¸ÿ& conn=op= time='E\f8d¦4â@þ–˜@¼t¿À& conn=op= time='E\fù†¦³¸ÿ& conn=op= time='E\f:Ô 4â@þ–˜@㥿À& conn=op= time='E\f˜¡³¸ÿ& conn=op= time='E\f6€£4â@þ–˜@ ×#¿À& conn=op= time='E\f󣳸ÿ& conn=op= time='E\f8æ4â@þ–˜@1,¿À& conn=op= time='E\fbe€³¸ÿ& conn=op= time='E\f3g¢0@& conn=op= time='E\fFþ{@ã@Ëó—@1,¿@& conn=op= time='E\f‰R|EVÿ& conn=op= time='E\f(?i fÎã@˜P—@1,¿@& conn=op= time='E\fÆÍi EVÿ& conn=op= time='E\f©vc!‹›ä@e­–@1,¿@& conn=op= time='E\f…‹d!EVÿ& conn=op= time='E\f·¬Z"±hå@2 –@1,¿@& conn=op= time='E\f4.["EVÿ& conn=op= time='E\fÿ?#×5æ@g•@1,¿@& conn=op= time='E\fª*@#EVÿ& conn=op= time='E\f<ŠB$ýç@ÍÔ@1,¿@& conn=op= time='E\f› C$EVÿ& conn=op= time='E\fD±8%#Ðç@š ”@1,¿@& conn=op= time='E\f‚é9%EVÿ& conn=op= time='E\faw"&I�è@g}“@1,¿@& conn=op= time='E\fE#&EVÿ& conn=op= time='E\f¤'ojé@5Ú’@1,¿@& conn=op= time='E\fýY'EVÿ& conn=op= time='E\f ø(•7ê@7’@1,¿@& conn=op= time='E\fć(EVÿ& conn=op= time='E\f‘eþ(»ë@Ï“‘@1,¿@& conn=op= time='E\fL-)EVÿ& conn=op= time='E\f˜Tö)áÑë@œð�@1,¿@& conn=op= time='E\f(Úö)EVÿ& conn=op= time='E\f5÷é*Ÿì@iM�@1,¿@& conn=op= time='E\fÄê*EVÿ& conn=op= time='E\f“fã+-lí@7ª�@1,¿@& conn=op= time='E\f;Ïã+EVÿ& conn=op= time='E\fcwÌ,S9î@�@1,¿@& conn=op= time='E\fáÌ,EVÿ& conn=op= time='E\f×SÆ-yï@ÑcŽ@1,¿@& conn=op= time='E\fg�Æ-EVÿ& conn=op= time='E\f`Á.žÓï@žÀ�@1,¿@& conn=op= time='E\fWbÂ.EVÿ& conn=op= time='E\f¨¯«/Ä ð@l�@1,¿@& conn=op= time='E\f#3¬/EVÿ& conn=op= time='E\fSã¥0êmñ@9zŒ@1,¿@& conn=op= time='E\f²¢¨0EVÿ& conn=op= time='E\fdï‘1;ò@׋@1,¿@& conn=op= time='E\f¼1’1EVÿ& conn=op= time='E\fnq‹26ó@Ó3‹@1,¿@& conn=op= time='E\f¬ÌŒ2EVÿ& conn=op= time='E\f"!†3\Õó@ �Š@1,¿@& conn=op= time='E\f¬Ì‡3EVÿ& conn=op= time='E\fq¡n4‚¢ô@ní‰@1,¿@& conn=op= time='E\f®p4EVÿ& conn=op= time='E\fØ`i5¨oõ@;J‰@1,¿@& conn=op= time='E\fVËi5EVÿ& conn=op= time='E\foÝb6Î<ö@§ˆ@1,¿@& conn=op= time='E\fƒe6EVÿ& conn=op= time='E\fŦL7ô ÷@Õˆ@1,¿@& conn=op= time='E\fM7EVÿ& conn=op= time='E\fÖBD8×÷@¢`‡@1,¿@& conn=op= time='E\fDéD8EVÿ& conn=op= time='E\f„Ù<9@¤ø@p½†@1,¿@& conn=op= time='E\fÎ�=9EVÿ& conn=op= time='E\f':fqù@=†@1,¿@& conn=op= time='E\f&ö(:EVÿ& conn=op= time='E\ft ";Œ>ú@ w…@1,¿@& conn=op= time='E\fî#;EVÿ& conn=op= time=(E\fA:± û@×Ó„@1,¿@& conn=op= time=(E\f²)€EVÿ& conn=op= time=(E\f‚µ×0@& conn=op= time=(E\fñsiרû@¥0„@1,¿@& conn=op= time=(E\fô×iEVÿ& conn=op= time=(E\f�œ]ý¥ü@r�ƒ@1,¿@& conn=op= time=(E\fC{^EVÿ& conn=op= time=(E\fK¼¬0@& conn=op= time=(E\feÇS#sý@?ê‚@1,¿@& conn=op= time=(E\fÜSUEVÿ& conn=op= time=(E\fÑFI@þ@ G‚@1,¿@& conn=op= time=(E\fw—GEVÿ& conn=op= time=(E\f…t{0@& conn=op= time=(E\fs]>o ÿ@Ù£�@1,¿@& conn=op= time=(E\fê¾>EVÿ& conn=op= time=(E\fM3•Úÿ@§�@1,¿@& conn=op= time=(E\f€G5EVÿ& conn=op= time=(E\fcáL0@& conn=op= time=(E\f„ ,ÝSAt]€@1,¿@& conn=op= time=(E\f°Ž,EVÿ& conn=op= time=(E\f¹�0@& conn=op= time=(E\fcé pºA‚t@1,¿@& conn=op= time=(E\f±e!EVÿ& conn=op= time=(E\fÔY !A.~@1,¿@& conn=op= time=(E\fÅÄ EVÿ& conn=op= time=(E\fúð 0@& conn=op= time=(E\fªþ –‡A·ç|@1,¿@& conn=op= time=(E\fnÿ EVÿ& conn=op= time=(E\fjö )îAQ¡{@1,¿@& conn=op= time=(E\f B÷ EVÿ& conn=op= time=(E\f#ܶ 0@& conn=op= time=(E\foYð ¼TAìZz@1,¿@& conn=op= time=(E\f¡&ò EVÿ& conn=op= time=(E\fìEç O»A†y@1,¿@& conn=op= time=(E\fx›ç EVÿ& conn=op= time=(E\fb®‡ 0@& conn=op= time=(E\f[ñÎ â!A!Îw@1,¿@& conn=op= time=(E\f_HÏ EVÿ& conn=op= time=(E\f'‚ÅuˆA»‡v@1,¿@& conn=op= time=(E\feŽÅEVÿ& conn=op= time=(E\fi½B0@& conn=op= time=(E\f#«¸ïAVAu@1,¿@& conn=op= time=(E\fU¹EVÿ& conn=op= time=(E\f3~­›UAðús@1,¿@& conn=op= time=(E\f.ø­EVÿ& conn=op= time=(E\f–0@& conn=op= time=(E\f@¥.¼AŠ´r@1,¿@& conn=op= time=(E\fí¥EVÿ& conn=op= time=(E\f‡²˜Á"A%nq@1,¿@& conn=op= time=(E\f‚;™EVÿ& conn=op= time=(E\fÎ3ä0@& conn=op= time=(E\fásŒT‰A¿'p@1,¿@& conn=op= time=(E\fЬŒEVÿ& conn=op= time=(E\f^ê|çïAZán@1,¿@& conn=op= time=(E\fF^}EVÿ& conn=op= time=(E\f m£0@& conn=op= time=(E\f? rzVAôšm@1,¿@& conn=op= time=(E\fuýrEVÿ& conn=op= time=(E\fPÚe ½A�Tl@1,¿@& conn=op= time=(E\fÞfEVÿ& conn=op= time=(E\f@Ãw0@& conn=op= time=(E\f:_\ #A)k@1,¿@& conn=op= time=(E\fü]EVÿ& conn=op= time=(E\f’ÞI0@& conn=op= time=(E\f`RP3ŠAÄÇi@1,¿@& conn=op= time=(E\f%|QEVÿ& conn=op= time=(E\fS*FÆðA^�h@1,¿@& conn=op= time=(E\f›‹FEVÿ& conn=op= time=(E\f_u0@& conn=op= time=(E\f„•;YWAø:g@1,¿@& conn=op= time=(E\f¾J<EVÿ& conn=op= time=(E\fv*2ì½A“ôe@1,¿@& conn=op= time=(E\f™¡2EVÿ& conn=op= time=(E\fRÞí0@& conn=op= time=(E\f8U($ A-®d@1,¿@& conn=op= time=(E\f?¾(EVÿ& conn=op= time=(E\fMO‹ AÈgc@1,¿@& conn=op= time=(E\f×ÝEVÿ& conn=op= time=(E\fFà¹0@& conn=op= time=(E\f5› ¥ñ Ab!b@1,¿@& conn=op= time=(E\f¸ø EVÿ& conn=op= time=(E\f]Ì8X AýÚ`@1,¿@& conn=op= time=(E\f>OEVÿ& conn=op= time=(E\fOŠ0@& conn=op= time=(E\fµø˾ A—”_@1,¿@& conn=op= time=(E\f ,øEVÿ& conn=op= time=(E\fôJí ^% A1N^@1,¿@& conn=op= time=(E\f=‰í EVÿ& conn=op= time=(E\fÝÈ[!0@& conn=op= time=(E\f@¹Ó!ð‹ AÌ]@1,¿@& conn=op= time=(E\faøÓ!EVÿ& conn=op= time=(E\f'pÈ"ƒò AfÁ[@1,¿@& conn=op= time=(E\f¹È"EVÿ& conn=op= time=(E\f…”4#0@& conn=op= time=(E\fNÞ½#Y A{Z@1,¿@& conn=op= time=(E\f$.¾#EVÿ& conn=op= time=(E\f†Ë¯$©¿ A›4Y@1,¿@& conn=op= time=(E\fýG°$EVÿ& conn=op= time=(E\f]¦%0@& conn=op= time=(E\fê$©%<& A6îW@1,¿@& conn=op= time=(E\fˆ©©%EVÿ& conn=op= time=(E\fÎ�¦&ÏŒ AЧV@1,¿@& conn=op= time=(E\f §&EVÿ& conn=op= time=(E\fÓkè&0@& conn=op= time=(E\fá™'bó AjaU@1,¿@& conn=op= time=(E\fÖ¡™'EVÿ& conn=op= time=(E\fÒÊ�(õYAT@1,¿@& conn=op= time=(E\fÌÛ�(EVÿ& conn=op= time=(E\f’�§(0@& conn=op= time=(E\fkDx)ˆÀAŸÔR@1,¿@& conn=op= time=(E\f«x)EVÿ& conn=op= time=(E\fÉp*'A:ŽQ@1,¿@& conn=op= time=(E\f;or*EVÿ& conn=op= time=(E\f(Ó|*0@& conn=op= time=(E\f� h+®�AÔGP@1,¿@& conn=op= time=(E\f…Lh+EVÿ& conn=op= time=(E\f+QK,0@& conn=op= time=(E\fj],AôAoO@1,¿@& conn=op= time=(E\f‡y],EVÿ& conn=op= time=(E\fF-ÔZA »M@1,¿@& conn=op= time=(E\f¾¡F-EVÿ& conn=op= time=(E\fàF.0@& conn=op= time=(E\fûX<.gÁA£tL@1,¿@& conn=op= time=(E\f{ö<.EVÿ& conn=op= time=(E\fÀ2/ú'A>.K@1,¿@& conn=op= time=(E\f43/EVÿ& conn=op= time=(E\f‰+0�ŽAØçI@1,¿@& conn=op= time=(E\fé°+0EVÿ& conn=op= time=(E\fVR$1 õAs¡H@1,¿@& conn=op= time=(E\f/ú%1EVÿ& conn=op= time=(E\fÊ82³[A [G@1,¿@& conn=op= time=(E\f²}2EVÿ& conn=op= time=(E\fªx 3FÂA¨F@1,¿@& conn=op= time=(E\fÁ 3EVÿ& conn=op= time=(E\fOÒò3Ù(ABÎD@1,¿@& conn=op= time=(E\f„‘ó3EVÿ& conn=op= time=(E\f‹Ðì4l�A݇C@1,¿@& conn=op= time=(E\få²í4EVÿ& conn=op= time=(E\f��æ5ÿõAwAB@1,¿@& conn=op= time=(E\f¿æ5EVÿ& conn=op= time=(E\fU†Ð6’\Aû@@1,¿@& conn=op= time=(E\fð!Ó6EVÿ& conn=op= time=(E\f’eË7%ÃA¬´?@1,¿@& conn=op= time=(E\f„ÿË7EVÿ& conn=op= time=(E\f#¥Ã8¸)AFn>@1,¿@& conn=op= time=(E\fþ2Ä8EVÿ& conn=op= time=(E\fÆ­9K�Aá'=@1,¿@& conn=op= time=(E\fû`®9EVÿ& conn=op= time=(E\f„§:ÞöA{á;@1,¿@& conn=op= time=(E\fÎ…©:EVÿ& conn=op= time=)E\fÀq]A›:@1,¿@& conn=op= time=)E\f³EVÿ& conn=op= time=)E\f·/0À& conn=op= time=)E\fëîÞöA{á;@1,¿@& conn=op= time=)E\f~€î³¸ÿ& conn=op= time=)E\fÑ,åK�Aá'=@1,¿@& conn=op= time=)E\f®å³¸ÿ& conn=op= time=)E\fNcܸ)AFn>@1,¿@& conn=op= time=)E\fãÚݳ¸ÿ& conn=op= time=)E\fpÉÔ%ÃA¬´?@1,¿@& conn=op= time=)E\fK\Õ³¸ÿ& conn=op= time=)E\fì[¿’\Aû@@1,¿@& conn=op= time=)E\f.À³¸ÿ& conn=op= time=)E\f„»ÿõAwAB@1,¿@& conn=op= time=)E\fP³»³¸ÿ& conn=op= time=)E\fÍ6§l�A݇C@1,¿@& conn=op= time=)E\fn¨³¸ÿ& conn=op= time=)E\f>ê¢Ù(ABÎD@1,¿@& conn=op= time=)E\fD�£³¸ÿ& conn=op= time=)E\f,A�FÂA¨F@1,¿@& conn=op= time=)E\f_–�³¸ÿ& conn=op= time=)E\f,…‰ ³[A [G@1,¿@& conn=op= time=)E\fq–‰ ³¸ÿ& conn=op= time=)E\fÁ<‚  õAs¡H@1,¿@& conn=op= time=)E\f˜Ó‚ ³¸ÿ& conn=op= time=)E\fü÷k �ŽAØçI@1,¿@& conn=op= time=)E\f8)l ³¸ÿ& conn=op= time=)E\fıc ú'A>.K@1,¿@& conn=op= time=)E\f«te ³¸ÿ& conn=op= time=)E\fK^ gÁA£tL@1,¿@& conn=op= time=)E\fc‘^ ³¸ÿ& conn=op= time=)E\f´(UÔZA »M@1,¿@& conn=op= time=)E\f‡”U³¸ÿ& conn=op= time=)E\f5Ô>AôAoO@1,¿@& conn=op= time=)E\fÊw?³¸ÿ& conn=op= time=)E\fÈD8®�AÔGP@1,¿@& conn=op= time=)E\fƒÏ8³¸ÿ& conn=op= time=)E\f¨¯/'A:ŽQ@1,¿@& conn=op= time=)E\f®+0³¸ÿ& conn=op= time=)E\f<«ˆÀAŸÔR@1,¿@& conn=op= time=)E\fCD³¸ÿ& conn=op= time=)E\f{SõYAT@1,¿@& conn=op= time=)E\fÛ3³¸ÿ& conn=op= time=)E\f!µ bó AjaU@1,¿@& conn=op= time=)E\f¤:³¸ÿ& conn=op= time=)E\f¬-öÏŒ AЧV@1,¿@& conn=op= time=)E\f]øö³¸ÿ& conn=op= time=)E\fi©î<& A6îW@1,¿@& conn=op= time=)E\fTﳸÿ& conn=op= time=)E\fÛ"ã©¿ A›4Y@1,¿@& conn=op= time=)E\fvì㳸ÿ& conn=op= time=)E\f;wÚY A{Z@1,¿@& conn=op= time=)E\fþܳ¸ÿ& conn=op= time=)E\fØÛăò AfÁ[@1,¿@& conn=op= time=)E\fáÒdz¸ÿ& conn=op= time=)E\fȃÁð‹ AÌ]@1,¿@& conn=op= time=)E\fÈ4³¸ÿ& conn=op= time=)E\f¼P±^% A1N^@1,¿@& conn=op= time=)E\fœ±³¸ÿ& conn=op= time=)E\fg(«˾ A—”_@1,¿@& conn=op= time=)E\f¤Â«³¸ÿ& conn=op= time=)E\foÕ£8X AýÚ`@1,¿@& conn=op= time=)E\fMj¤³¸ÿ& conn=op= time=)E\f™7�¥ñ Ab!b@1,¿@& conn=op= time=)E\fž^޳¸ÿ& conn=op= time=)E\fžŠä0À& conn=op= time=)E\fŃ‹ AÈgc@1,¿@& conn=op= time=)E\f¸ÿ& conn=op= time=)E\fðu$ A-®d@1,¿@& conn=op= time=)E\fé�u³¸ÿ& conn=op= time=)E\fšÛ›0À& conn=op= time=)E\fszn ì½A“ôe@1,¿@& conn=op= time=)E\f¸Ûn ³¸ÿ& conn=op= time=)E\f”»d!YWAø:g@1,¿@& conn=op= time=)E\fœ;e!³¸ÿ& conn=op= time=)E\f˜q!0À& conn=op= time=)E\fGAL"ÆðA^�h@1,¿@& conn=op= time=)E\fÔ—L"³¸ÿ& conn=op= time=)E\f'zB#3ŠAÄÇi@1,¿@& conn=op= time=)E\fÑêB#³¸ÿ& conn=op= time=)E\f9§D#0À& conn=op= time=)E\fÚñ7$ #A)k@1,¿@& conn=op= time=)E\f A8$³¸ÿ& conn=op= time=)E\fz %0À& conn=op= time=)E\f],% ½A�Tl@1,¿@& conn=op= time=)E\f­n,%³¸ÿ& conn=op= time=)E\f²&&zVAôšm@1,¿@& conn=op= time=)E\f—&&³¸ÿ& conn=op= time=)E\f³uè&0À& conn=op= time=)E\f“s'çïAZán@1,¿@& conn=op= time=)E\f=À'³¸ÿ& conn=op= time=)E\fV*(T‰A¿'p@1,¿@& conn=op= time=)E\f+©(³¸ÿ& conn=op= time=)E\fŒä¥(0À& conn=op= time=)E\f@ )Á"A%nq@1,¿@& conn=op= time=)E\fîà )³¸ÿ& conn=op= time=)E\fóWñ).¼AŠ´r@1,¿@& conn=op= time=)E\ffÞñ)³¸ÿ& conn=op= time=)E\fÜ~*0À& conn=op= time=)E\f-3é*›UAðús@1,¿@& conn=op= time=)E\fä ê*³¸ÿ& conn=op= time=)E\fö ß+ïAVAu@1,¿@& conn=op= time=)E\f{ß+³¸ÿ& conn=op= time=)E\f:Q,0À& conn=op= time=)E\fX}Õ,uˆA»‡v@1,¿@& conn=op= time=)E\f%ÿÕ,³¸ÿ& conn=op= time=)E\f—øÌ-â!A!Îw@1,¿@& conn=op= time=)E\fqJÍ-³¸ÿ& conn=op= time=)E\f5/.0À& conn=op= time=)E\fÑÙ±.O»A†y@1,¿@& conn=op= time=)E\f—².³¸ÿ& conn=op= time=)E\fa°³/¼TAìZz@1,¿@& conn=op= time=)E\f?¼³/³¸ÿ& conn=op= time=)E\fï/0À& conn=op= time=)E\fF4§0)îAQ¡{@1,¿@& conn=op= time=)E\fm›§0³¸ÿ& conn=op= time=)E\f#›1–‡A·ç|@1,¿@& conn=op= time=)E\f(.›1³¸ÿ& conn=op= time=)E\fK}Ð10À& conn=op= time=)E\fO§ƒ2!A.~@1,¿@& conn=op= time=)E\f,+„2³¸ÿ& conn=op= time=)E\fzy3pºA‚t@1,¿@& conn=op= time=)E\f)z3³¸ÿ& conn=op= time=)E\fß`¦30À& conn=op= time=)E\fú÷t4ÝSAt]€@1,¿@& conn=op= time=)E\fd�u4³¸ÿ& conn=op= time=)E\fzƒi5•Úÿ@§�@1,¿@& conn=op= time=)E\fì^j5³¸ÿ& conn=op= time=)E\fuáu50À& conn=op= time=)E\f!,_6o ÿ@Ù£�@1,¿@& conn=op= time=)E\fns_6³¸ÿ& conn=op= time=)E\fîO;70À& conn=op= time=)E\f±Q7I@þ@ G‚@1,¿@& conn=op= time=)E\fØ€Q7³¸ÿ& conn=op= time=)E\foH8#sý@?ê‚@1,¿@& conn=op= time=)E\f|ƒH8³¸ÿ& conn=op= time=)E\f‘D90À& conn=op= time=)E\f÷-99ý¥ü@r�ƒ@1,¿@& conn=op= time=)E\fš˜99³¸ÿ& conn=op= time=)E\f‡….:רû@¥0„@1,¿@& conn=op= time=)E\fGq/:³¸ÿ& conn=op= time=)E\fàº×:0À& conn=op= time=)E\f1^!;± û@×Ó„@1,¿@& conn=op= time=)E\f¸ ";³¸ÿ& conn=op= time=*E\fv»|Œ>ú@ w…@1,¿@& conn=op= time=*E\f¨H}³¸ÿ& conn=op= time=*E\f¦$0À& conn=op= time=*E\fÆ�qfqù@=†@1,¿@& conn=op= time=*E\f¬¾q³¸ÿ& conn=op= time=*E\f€e@¤ø@p½†@1,¿@& conn=op= time=*E\fxf³¸ÿ& conn=op= time=*E\f'vâ0À& conn=op= time=*E\fOÑN×÷@¢`‡@1,¿@& conn=op= time=*E\fO³¸ÿ& conn=op= time=*E\fÚ¸Dô ÷@Õˆ@1,¿@& conn=op= time=*E\f£CE³¸ÿ& conn=op= time=*E\fÿÍÊ0À& conn=op= time=*E\f2‰;Î<ö@§ˆ@1,¿@& conn=op= time=*E\f‘Ü;³¸ÿ& conn=op= time=*E\f½§.¨oõ@;J‰@1,¿@& conn=op= time=*E\fÅ/³¸ÿ& conn=op= time=*E\fU¨”0À& conn=op= time=*E\f›A$‚¢ô@ní‰@1,¿@& conn=op= time=*E\f’G$³¸ÿ& conn=op= time=*E\f<ë\Õó@ �Š@1,¿@& conn=op= time=*E\fÔd³¸ÿ& conn=op= time=*E\f Ým0À& conn=op= time=*E\f(” 6ó@Ó3‹@1,¿@& conn=op= time=*E\f0 ³¸ÿ& conn=op= time=*E\fÔí ;ò@׋@1,¿@& conn=op= time=*E\f°O ³¸ÿ& conn=op= time=*E\fèTE 0À& conn=op= time=*E\foñ êmñ@9zŒ@1,¿@& conn=op= time=*E\f™Íñ ³¸ÿ& conn=op= time=*E\f´¼å Ä ð@l�@1,¿@& conn=op= time=*E\fE*æ ³¸ÿ& conn=op= time=*E\fÚM 0À& conn=op= time=*E\fÂÑÜ žÓï@žÀ�@1,¿@& conn=op= time=*E\f_OÝ ³¸ÿ& conn=op= time=*E\fk:Ï 0À& conn=op= time=*E\fý Ö yï@ÑcŽ@1,¿@& conn=op= time=*E\f|eÖ ³¸ÿ& conn=op= time=*E\f:VÀS9î@�@1,¿@& conn=op= time=*E\fΧÀ³¸ÿ& conn=op= time=*E\fÌ«0À& conn=op= time=*E\f½´À-lí@7ª�@1,¿@& conn=op= time=*E\f0QÁ³¸ÿ& conn=op= time=*E\fÿ쩟ì@iM�@1,¿@& conn=op= time=*E\f0bª³¸ÿ& conn=op= time=*E\fã/€0À& conn=op= time=*E\f<%¡áÑë@œð�@1,¿@& conn=op= time=*E\f>”¡³¸ÿ& conn=op= time=*E\f¨B–»ë@Ï“‘@1,¿@& conn=op= time=*E\f0¿–³¸ÿ& conn=op= time=*E\f¨;G0À& conn=op= time=*E\f©Å�•7ê@7’@1,¿@& conn=op= time=*E\f¤÷�³¸ÿ& conn=op= time=*E\f±�„ojé@5Ú’@1,¿@& conn=op= time=*E\fy…³¸ÿ& conn=op= time=*E\fq50À& conn=op= time=*E\fQvyI�è@g}“@1,¿@& conn=op= time=*E\fUéy³¸ÿ& conn=op= time=*E\f6�p#Ðç@š ”@1,¿@& conn=op= time=*E\fþmq³¸ÿ& conn=op= time=*E\fôýê0À& conn=op= time=*E\f‘øWýç@ÍÔ@1,¿@& conn=op= time=*E\feNX³¸ÿ& conn=op= time=*E\fTØJ×5æ@g•@1,¿@& conn=op= time=*E\f*3K³¸ÿ& conn=op= time=*E\fEñ0À& conn=op= time=*E\fݹ?±hå@2 –@1,¿@& conn=op= time=*E\f©.@³¸ÿ& conn=op= time=*E\fÜÝ6‹›ä@e­–@1,¿@& conn=op= time=*E\fmt7³¸ÿ& conn=op= time=*E\fØJ‘0À& conn=op= time=*E\f:û1fÎã@˜P—@1,¿@& conn=op= time=*E\fqi2³¸ÿ& conn=op= time=*E\f`E&@ã@Ëó—@1,¿@& conn=op= time=*E\föÀ&³¸ÿ& conn=op= time=*E\fI0À& conn=op= time=*E\fg4â@þ–˜@1,¿@& conn=op= time=*E\f“³¸ÿ& conn=op= time=*E\f½ôfá@0:™@1,¿@& conn=op= time=*E\fh ³¸ÿ& conn=op= time=*E\fú",0À& conn=op= time=*E\f_�üΙà@cÝ™@1,¿@& conn=op= time=*E\f6ý³¸ÿ& conn=op= time=*E\f¿jñ¨Ìß@–€š@1,¿@& conn=op= time=*E\f’tò0À& conn=op= time=*E\f°.ó³¸ÿ& conn=op= time=*E\fËZì ‚ÿÞ@É#›@1,¿@& conn=op= time=*E\f]Òì ³¸ÿ& conn=op= time=*E\f±Ä!0À& conn=op= time=*E\fÊ©à!\2Þ@üÆ›@1,¿@& conn=op= time=*E\f*á!³¸ÿ& conn=op= time=*E\f Ê"6eÝ@.jœ@1,¿@& conn=op= time=*E\fuoÊ"³¸ÿ& conn=op= time=*E\f.4†#0À& conn=op= time=*E\fbÙ¿#˜Ü@a �@1,¿@& conn=op= time=*E\fÏSÀ#³¸ÿ& conn=op= time=*E\fæ¾µ$êÊÛ@”°�@1,¿@& conn=op= time=*E\f|;¶$³¸ÿ& conn=op= time=*E\f¦Y)%0À& conn=op= time=*E\fC%§%ÄýÚ@ÇSž@1,¿@& conn=op= time=*E\f¼n§%³¸ÿ& conn=op= time=*E\fîy—&ž0Ú@ùöž@1,¿@& conn=op= time=*E\f“¼—&³¸ÿ& conn=op= time=*E\f¤'0À& conn=op= time=*E\f­–'xcÙ@,šŸ@1,¿@& conn=op= time=*E\fê^–'³¸ÿ& conn=op= time=*E\f àˆ(S–Ø@_= @1,¿@& conn=op= time=*E\fD�‰(³¸ÿ& conn=op= time=*E\f©ðã(0À& conn=op= time=*E\f(Í|)-É×@’à @1,¿@& conn=op= time=*E\fõI})³¸ÿ& conn=op= time=*E\f��q*üÖ@Ń¡@1,¿@& conn=op= time=*E\fÙq*³¸ÿ& conn=op= time=*E\f”ð­*0À& conn=op= time=*E\ftFf+á.Ö@÷&¢@1,¿@& conn=op= time=*E\ft¸f+³¸ÿ& conn=op= time=*E\f£ê[,»aÕ@*Ê¢@1,¿@& conn=op= time=*E\f�m\,³¸ÿ& conn=op= time=*E\f£ùR-•”Ô@]m£@1,¿@& conn=op= time=*E\fk~S-³¸ÿ& conn=op= time=*E\foµ;.oÇÓ@�¤@1,¿@& conn=op= time=*E\fH<.³¸ÿ& conn=op= time=*E\fk"2/0À& conn=op= time=*E\f„€2/IúÒ@ó¤@1,¿@& conn=op= time=*E\f3/³¸ÿ& conn=op= time=*E\fñ®*0IúÒ@ó¤@X94¿À& conn=op= time=*E\fF0+0³¸ÿ& conn=op= time=*E\fË1IúÒ@ó¤@j<¿À& conn=op= time=*E\fz^1³¸ÿ& conn=op= time=*E\f ”2IúÒ@ó¤@¦›D¿À& conn=op= time=*E\fÇ"2³¸ÿ& conn=op= time=*E\f@Ü 3IúÒ@ó¤@ÍÌL¿À& conn=op= time=*E\fºõ 3³¸ÿ& conn=op= time=*E\f(Où3IúÒ@ó¤@ôýT¿À& conn=op= time=*E\f–ªù3³¸ÿ& conn=op= time=*E\f”1ô4IúÒ@ó¤@/]¿À& conn=op= time=*E\fµô4³¸ÿ& conn=op= time=*E\fh„ß5IúÒ@ó¤@B`e¿À& conn=op= time=*E\f¢ß5³¸ÿ& conn=op= time=*E\fsÙ6IúÒ@ó¤@h‘m¿À& conn=op= time=*E\fÿêÙ6³¸ÿ& conn=op= time=*E\fV‡Ã7IúÒ@ó¤@�Âu¿À& conn=op= time=*E\f½ Ä7³¸ÿ& conn=op= time=*E\f\þ¿8IúÒ@ó¤@¶ó}¿À& conn=op= time=*E\f„>À8³¸ÿ& conn=op= time=*E\f¸+¬9IúÒ@ó¤@oƒ¿À& conn=op= time=*E\fMR¬9³¸ÿ& conn=op= time=*E\fEj§:IúÒ@ó¤@+‡¿À& conn=op= time=*E\fýܧ:³¸ÿ& conn=op= time=+E\fÖðIúÒ@ó¤@–C‹¿À& conn=op= time=+E\fJ!³¸ÿ& conn=op= time=+E\fÌ¿óIúÒ@ó¤@)\�¿À& conn=op= time=+E\f;óô³¸ÿ& conn=op= time=+E\f ðIúÒ@ó¤@¼t“¿À& conn=op= time=+E\fFÑð³¸ÿ& conn=op= time=+E\fªCÛIúÒ@ó¤@P�—¿À& conn=op= time=+E\f?êÛ³¸ÿ& conn=op= time=+E\fôËIúÒ@ó¤@㥛¿À& conn=op= time=+E\fX)˳¸ÿ& conn=op= time=+E\fY€ÇIúÒ@ó¤@w¾Ÿ¿À& conn=op= time=+E\f]ȳ¸ÿ& conn=op= time=+E\fñ¬³IúÒ@ó¤@ ×£¿À& conn=op= time=+E\fk1´³¸ÿ& conn=op= time=+E\f¼ž®IúÒ@ó¤@žï§¿À& conn=op= time=+E\fй®³¸ÿ& conn=op= time=+E\fQ¸ªIúÒ@ó¤@1¬¿À& conn=op= time=+E\fA«³¸ÿ& conn=op= time=+E\f à•IúÒ@ó¤@Å °¿À& conn=op= time=+E\f —³¸ÿ& conn=op= time=+E\fTÐ� IúÒ@ó¤@X9´¿À& conn=op= time=+E\f ‘ ³¸ÿ& conn=op= time=+E\fkw} IúÒ@ó¤@ìQ¸¿À& conn=op= time=+E\fgô~ ³¸ÿ& conn=op= time=+E\f›Ïx IúÒ@ó¤@j¼¿À& conn=op= time=+E\f`y ³¸ÿ& conn=op= time=+E\fì.d IúÒ@ó¤@ƒÀ¿À& conn=op= time=+E\fíGd ³¸ÿ& conn=op= time=+E\f ^ IúÒ@ó¤@¦›Ä¿À& conn=op= time=+E\fè“^ ³¸ÿ& conn=op= time=+E\fÂHIúÒ@ó¤@9´È¿À& conn=op= time=+E\f4I³¸ÿ& conn=op= time=+E\f×½CIúÒ@ó¤@ÍÌÌ¿À& conn=op= time=+E\f1bD³¸ÿ& conn=op= time=+E\f£Ž=IúÒ@ó¤@`åпÀ& conn=op= time=+E\f2œ=³¸ÿ& conn=op= time=+E\f§û'IúÒ@ó¤@ôýÔ¿À& conn=op= time=+E\fvz(³¸ÿ& conn=op= time=+E\f¯z0À& conn=op= time=+E\fŒí!IúÒ@ó¤@‡Ù¿À& conn=op= time=+E\fz "³¸ÿ& conn=op= time=+E\fø¥IúÒ@ó¤@/Ý¿À& conn=op= time=+E\fª³¸ÿ& conn=op= time=+E\f/30À& conn=op= time=+E\fVÿ IúÒ@ó¤@®Gá¿À& conn=op= time=+E\fù&³¸ÿ& conn=op= time=+E\f½ý÷IúÒ@ó¤@B`å¿À& conn=op= time=+E\f¥�ø³¸ÿ& conn=op= time=+E\fQ0À& conn=op= time=+E\fT!õIúÒ@ó¤@Õxé¿À& conn=op= time=+E\f 8õ³¸ÿ& conn=op= time=+E\f‰Û0À& conn=op= time=+E\f¯lÜIúÒ@ó¤@h‘í¿À& conn=op= time=+E\f`Zݳ¸ÿ& conn=op= time=+E\fŠùÖIúÒ@ó¤@ü©ñ¿À& conn=op= time=+E\f§N׳¸ÿ& conn=op= time=+E\fQI™0À& conn=op= time=+E\fQÇËIúÒ@ó¤@�Âõ¿À& conn=op= time=+E\fÖ�̳¸ÿ& conn=op= time=+E\fŸµÅIúÒ@ó¤@#Ûù¿À& conn=op= time=+E\f8)Ƴ¸ÿ& conn=op= time=+E\f„i0À& conn=op= time=+E\fY¶°IúÒ@ó¤@¶óý¿À& conn=op= time=+E\f?ذ³¸ÿ& conn=op= time=+E\fy¤©IúÒ@ó¤@%ÀÀ& conn=op= time=+E\f婳¸ÿ& conn=op= time=+E\f4A0À& conn=op= time=+E\f›ç¡IúÒ@ó¤@oÀÀ& conn=op= time=+E\f­ ¢³¸ÿ& conn=op= time=+E\fÁŒIúÒ@ó¤@¸ÀÀ& conn=op= time=+E\fõ‚Œ³¸ÿ& conn=op= time=+E\f9¤0À& conn=op= time=+E\fI‰IúÒ@ó¤@+ÀÀ& conn=op= time=+E\fÆ·‰³¸ÿ& conn=op= time=+E\f®]qIúÒ@ó¤@L7 ÀÀ& conn=op= time=+E\fr r³¸ÿ& conn=op= time=+E\f—Gí0À& conn=op= time=+E\f:?j IúÒ@ó¤@–C ÀÀ& conn=op= time=+E\f²Mj ³¸ÿ& conn=op= time=+E\fɶ^!IúÒ@ó¤@ßO ÀÀ& conn=op= time=+E\f|6_!³¸ÿ& conn=op= time=+E\fˆë©!0À& conn=op= time=+E\f~V"IúÒ@ó¤@)\ÀÀ& conn=op= time=+E\fØýV"³¸ÿ& conn=op= time=+E\fJeM#IúÒ@ó¤@shÀÀ& conn=op= time=+E\fyáM#³¸ÿ& conn=op= time=+E\fàƒ#0À& conn=op= time=+E\fÀ÷6$IúÒ@ó¤@¼tÀÀ& conn=op= time=+E\fÔ7$³¸ÿ& conn=op= time=+E\f&Ÿ,%IúÒ@ó¤@�ÀÀ& conn=op= time=+E\f[-%³¸ÿ& conn=op= time=+E\fŒÉS%0À& conn=op= time=+E\f'Ó%&IúÒ@ó¤@P�ÀÀ& conn=op= time=+E\f,â%&³¸ÿ& conn=op= time=+E\fœ'IúÒ@ó¤@š™ÀÀ& conn=op= time=+E\fY¶'³¸ÿ& conn=op= time=+E\fÆ¥'0@& conn=op= time=+E\f&H(û8Ò@±¤@š™À@& conn=op= time=+E\f¬(³¸ÿ& conn=op= time=+E\fÃ)®wÑ@ŸQ£@š™À@& conn=op= time=+E\fro)³¸ÿ& conn=op= time=+E\f5þ)`¶Ð@Ž ¢@š™À@& conn=op= time=+E\ftÆþ)³¸ÿ& conn=op= time=+E\f†Âè*õÏ@|ï¡@š™À@& conn=op= time=+E\f”éè*EVÿ& conn=op= time=+E\fëLá+Å3Ï@k>¡@š™À@& conn=op= time=+E\f`Üá+EVÿ& conn=op= time=+E\f¾eÍ,wrÎ@Y� @š™À@& conn=op= time=+E\f£Í,³¸ÿ& conn=op= time=+E\fšvÅ-)±Í@HÜŸ@š™À@& conn=op= time=+E\f0’Å-³¸ÿ& conn=op= time=+E\fÁ³¾.ÜïÌ@6+Ÿ@š™À@& conn=op= time=+E\f³OÀ.³¸ÿ& conn=op= time=+E\fŸ©/Ž.Ì@$zž@š™À@& conn=op= time=+E\fm©/³¸ÿ& conn=op= time=+E\fëBŸ0@mË@É�@š™À@& conn=op= time=+E\fTߟ0³¸ÿ& conn=op= time=+E\fÒ›1ó«Ê@�@š™À@& conn=op= time=+E\fœ•œ1³¸ÿ& conn=op= time=+E\f’w�2¥êÉ@ðfœ@š™À@& conn=op= time=+E\f•î�2³¸ÿ& conn=op= time=+E\f.‡3X)É@Þµ›@š™À@& conn=op= time=+E\f ¶‡3³¸ÿ& conn=op= time=+E\fHøp4 hÈ@Í›@š™À@& conn=op= time=+E\fÜ—r4³¸ÿ& conn=op= time=+E\fØj5¼¦Ç@»Sš@š™À@& conn=op= time=+E\fá÷j5³¸ÿ& conn=op= time=+E\f‹Hc6oåÆ@©¢™@š™À@& conn=op= time=+E\fçâc6³¸ÿ& conn=op= time=+E\fͱL7!$Æ@˜ñ˜@š™À@& conn=op= time=+E\fÖCM7³¸ÿ& conn=op= time=+E\fõ(G8ÓbÅ@†@˜@š™À@& conn=op= time=+E\f™G8³¸ÿ& conn=op= time=+E\fÊT>9†¡Ä@u�—@š™À@& conn=op= time=+E\fçÕ>9³¸ÿ& conn=op= time=+E\f8]&:8àÃ@cÞ–@š™À@& conn=op= time=+E\f\ò&:EVÿ& conn=op= time=+E\f^ý!;êÃ@R-–@š™À@& conn=op= time=+E\f[Z";EVÿ& conn=op= time=,E\f0~�]Â@@|•@š™À@& conn=op= time=,E\fMÎEVÿ& conn=op= time=,E\f"hOœÁ@.Ë”@š™À@& conn=op= time=,E\fÜWhEVÿ& conn=op= time=,E\f6$aÛÀ@”@š™À@& conn=op= time=,E\fÑ?aEVÿ& conn=op= time=,E\f™Z´À@ i“@š™À@& conn=op= time=,E\f(¡[EVÿ& conn=op= time=,E\fÎ…EfX¿@ú·’@š™À@& conn=op= time=,E\fFEVÿ& conn=op= time=,E\fPà?—¾@è’@š™À@& conn=op= time=,E\fÛ}@EVÿ& conn=op= time=,E\f/9ËÕ½@×U‘@š™À@& conn=op= time=,E\fBa9EVÿ& conn=op= time=,E\fPñ"}½@Ť�@š™À@& conn=op= time=,E\fû�#EVÿ& conn=op= time=,E\fìø/S¼@´ó�@š™À@& conn=op= time=,E\f•�EVÿ& conn=op= time=,E\fs¨ â‘»@¢B�@š™À@& conn=op= time=,E\f1& EVÿ& conn=op= time=,E\fÚlà 0@& conn=op= time=,E\f®Hþ ”к@�‘Ž@š™À@& conn=op= time=,E\f©äþ EVÿ& conn=op= time=,E\fniø Fº@à�@š™À@& conn=op= time=,E\f óø ³¸ÿ& conn=op= time=,E\fh$° 0@& conn=op= time=,E\fhEð ùM¹@m/�@š™À@& conn=op= time=,E\fP‡ð ³¸ÿ& conn=op= time=,E\fP8è «Œ¸@\~Œ@š™À@& conn=op= time=,E\fkfè ³¸ÿ& conn=op= time=,E\fy…i 0@& conn=op= time=,E\f°ÌÏ ]Ë·@JÍ‹@š™À@& conn=op= time=,E\f £Ð ³¸ÿ& conn=op= time=,E\f}»É ·@9‹@š™À@& conn=op= time=,E\f±?ʳ¸ÿ& conn=op= time=,E\f(éN0@& conn=op= time=,E\füá´ÂH¶@'kŠ@š™À@& conn=op= time=,E\fµ³¸ÿ& conn=op= time=,E\f}Õ¨t‡µ@º‰@š™À@& conn=op= time=,E\fU3©³¸ÿ& conn=op= time=,E\f¡0@& conn=op= time=,E\fÐ|Ÿ'Æ´@ ‰@š™À@& conn=op= time=,E\f. ³¸ÿ& conn=op= time=,E\fs6—Ù´@òWˆ@š™À@& conn=op= time=,E\f�׳¸ÿ& conn=op= time=,E\fÔìå0@& conn=op= time=,E\fŠÉ‹ŒC³@ᦇ@š™À@& conn=op= time=,E\f1ꌳ¸ÿ& conn=op= time=,E\fÉ€~>‚²@Ïõ†@š™À@& conn=op= time=,E\fð~³¸ÿ& conn=op= time=,E\fœì°0@& conn=op= time=,E\f,ÎvðÀ±@¾D†@š™À@& conn=op= time=,E\fL>w³¸ÿ& conn=op= time=,E\fÒ°j£ÿ°@¬“…@š™À@& conn=op= time=,E\fZ¢k³¸ÿ& conn=op= time=,E\f¥x0@& conn=op= time=,E\f¯ŒcU>°@šâ„@š™À@& conn=op= time=,E\fKæc³¸ÿ& conn=op= time=,E\fJ0@& conn=op= time=,E\fµÔW}¯@‰1„@š™À@& conn=op= time=,E\f=YX³¸ÿ& conn=op= time=,E\fe?º»®@w€ƒ@š™À@& conn=op= time=,E\f�‡?³¸ÿ& conn=op= time=,E\fÖ0@& conn=op= time=,E\fG:5lú­@fÏ‚@š™À@& conn=op= time=,E\f(œ5³¸ÿ& conn=op= time=,E\f@w+9­@T‚@š™À@& conn=op= time=,E\f…è+³¸ÿ& conn=op= time=,E\fFÁâ0@& conn=op= time=,E\f*;#Ñw¬@Cm�@š™À@& conn=op= time=,E\f7¶#³¸ÿ& conn=op= time=,E\fƒ¶«@1¼€@š™À@& conn=op= time=,E\fÇ?EVÿ& conn=op= time=,E\f™µ°0@& conn=op= time=,E\fbœ5õª@ €@š™À@& conn=op= time=,E\f‚QEVÿ& conn=op= time=,E\fAUøè3ª@´~@š™À@& conn=op= time=,E\fbÊøEVÿ& conn=op= time=,E\f‹:“0@& conn=op= time=,E\f‰ïšr©@ùQ}@š™À@& conn=op= time=,E\fU ïEVÿ& conn=op= time=,E\fý°ä L±¨@Öï{@š™À@& conn=op= time=,E\füËä EVÿ& conn=op= time=,E\f» Z!0@& conn=op= time=,E\fn<Û!ÿï§@²�z@š™À@& conn=op= time=,E\fµ™Û!EVÿ& conn=op= time=,E\fôÌ"±.§@�+y@š™À@& conn=op= time=,E\f7?Í"EVÿ& conn=op= time=,E\fç· #0@& conn=op= time=,E\f¼—Á#cm¦@lÉw@š™À@& conn=op= time=,E\fÂ#EVÿ& conn=op= time=,E\fê�»$¬¥@Igv@š™À@& conn=op= time=,E\f�ù»$EVÿ& conn=op= time=,E\fÖ ë$0@& conn=op= time=,E\fõ޳%Èê¤@&u@š™À@& conn=op= time=,E\f�1´%EVÿ& conn=op= time=,E\fž¾Ÿ&z)¤@£s@š™À@& conn=op= time=,E\fT &EVÿ& conn=op= time=,E\fŽSÁ&0@& conn=op= time=,E\f¸{'0@& conn=op= time=,E\fD——'z)¤@£s@P�À@& conn=op= time=,E\fËÈ—'³¸ÿ& conn=op= time=,E\f&À‰(z)¤@£s@�À@& conn=op= time=,E\f±Ñ‰(³¸ÿ& conn=op= time=,E\f©()z)¤@£s@¼tÀ@& conn=op= time=,E\f;£€)³¸ÿ& conn=op= time=,E\f„lv*z)¤@£s@shÀ@& conn=op= time=,E\fÎãv*³¸ÿ& conn=op= time=,E\föø^+z)¤@£s@)\À@& conn=op= time=,E\f 0_+³¸ÿ& conn=op= time=,E\f5Y,z)¤@£s@ßO À@& conn=op= time=,E\føY,³¸ÿ& conn=op= time=,E\f‚AS-z)¤@£s@–C À@& conn=op= time=,E\fž®S-³¸ÿ& conn=op= time=,E\f�—@.z)¤@£s@L7 À@& conn=op= time=,E\fò¿@.³¸ÿ& conn=op= time=,E\fYx9/z)¤@£s@+À@& conn=op= time=,E\fˆî9/³¸ÿ& conn=op= time=,E\f% /0z)¤@£s@¸À@& conn=op= time=,E\fæ00³¸ÿ& conn=op= time=,E\fA 1z)¤@£s@oÀ@& conn=op= time=,E\f A1³¸ÿ& conn=op= time=,E\f‘2z)¤@£s@%À@& conn=op= time=,E\fá2³¸ÿ& conn=op= time=,E\fc| 3z)¤@£s@¶óý¿@& conn=op= time=,E\f“� 3³¸ÿ& conn=op= time=,E\f�Jó3z)¤@£s@#Ûù¿@& conn=op= time=,E\fÔÖó3³¸ÿ& conn=op= time=,E\f2î4z)¤@£s@�Âõ¿@& conn=op= time=,E\fCÆï4³¸ÿ& conn=op= time=,E\fë_é5z)¤@£s@ü©ñ¿@& conn=op= time=,E\fûšé5³¸ÿ& conn=op= time=,E\fèÕ6z)¤@£s@h‘í¿@& conn=op= time=,E\fÏÕ6³¸ÿ& conn=op= time=,E\f;�Ð7z)¤@£s@Õxé¿@& conn=op= time=,E\f’Ñ7³¸ÿ& conn=op= time=,E\fU¬¼8z)¤@£s@B`å¿@& conn=op= time=,E\fdͼ8³¸ÿ& conn=op= time=,E\fŠO¸9z)¤@£s@®Gá¿@& conn=op= time=,E\f²•¸9³¸ÿ& conn=op= time=,E\fc,¥:z)¤@£s@/Ý¿@& conn=op= time=,E\fJB¥:³¸ÿ& conn=op= time=-E\f(\z)¤@£s@‡Ù¿@& conn=op= time=-E\fÙ‰³¸ÿ& conn=op= time=-E\f°îz)¤@£s@ôýÔ¿@& conn=op= time=-E\f)�ÿ& conn=op= time=-E\fr îz)¤@£s@`åп@& conn=op= time=-E\fɣÿ& conn=op= time=-E\f\SÜz)¤@£s@ÍÌÌ¿@& conn=op= time=-E\fýîܳ¸ÿ& conn=op= time=-E\f—$×z)¤@£s@9´È¿@& conn=op= time=-E\fLT׳¸ÿ& conn=op= time=-E\fÂ?Ãz)¤@£s@¦›Ä¿@& conn=op= time=-E\f"Tó¸ÿ& conn=op= time=-E\fü¾z)¤@£s@ƒÀ¿@& conn=op= time=-E\fS*¾³¸ÿ& conn=op= time=-E\f0‰ªz)¤@£s@j¼¿@& conn=op= time=-E\f÷«³¸ÿ& conn=op= time=-E\f¨ˆ¥z)¤@£s@ìQ¸¿@& conn=op= time=-E\f¦³¸ÿ& conn=op= time=-E\fM“z)¤@£s@X9´¿@& conn=op= time=-E\fY(“³¸ÿ& conn=op= time=-E\fv$^ 0@& conn=op= time=-E\fíg� z)¤@£s@Å °¿@& conn=op= time=-E\f1� ³¸ÿ& conn=op= time=-E\fXí… z)¤@£s@1¬¿@& conn=op= time=-E\fJr† ³¸ÿ& conn=op= time=-E\fN6 0@& conn=op= time=-E\f!n z)¤@£s@žï§¿@& conn=op= time=-E\f@n ³¸ÿ& conn=op= time=-E\f·^ z)¤@£s@ ×£¿@& conn=op= time=-E\fï_ ³¸ÿ& conn=op= time=-E\fŠÒö 0@& conn=op= time=-E\f³ËS z)¤@£s@w¾Ÿ¿@& conn=op= time=-E\f¼ÜS ³¸ÿ& conn=op= time=-E\f=1Jz)¤@£s@㥛¿@& conn=op= time=-E\fð¥J³¸ÿ& conn=op= time=-E\fÌKÒ0@& conn=op= time=-E\f¦f?z)¤@£s@P�—¿@& conn=op= time=-E\fIÎ?³¸ÿ& conn=op= time=-E\fúý5z)¤@£s@¼t“¿@& conn=op= time=-E\fJP6³¸ÿ& conn=op= time=-E\fE4,z)¤@£s@)\�¿@& conn=op= time=-E\fŒ,³¸ÿ& conn=op= time=-E\f�¶»0@& conn=op= time=-E\f:8&±›¤@Ëq@)\�¿@& conn=op= time=-E\fÙÂ&EVÿ& conn=op= time=-E\fŠ9 ç ¥@0óo@)\�¿@& conn=op= time=-E\f�¨ EVÿ& conn=op= time=-E\fOÆ€¥@Fn@)\�¿@& conn=op= time=-E\fäßEVÿ& conn=op= time=-E\fºŸûSò¥@]Cl@)\�¿@& conn=op= time=-E\fÃnüEVÿ& conn=op= time=-E\fubó‰d¦@tkj@)\�¿@& conn=op= time=-E\f ôEVÿ& conn=op= time=-E\fFBݿ֦@Š“h@)\�¿@& conn=op= time=-E\f—¿ÝEVÿ& conn=op= time=-E\fd2ÕöH§@¡»f@)\�¿@& conn=op= time=-E\f _ÖEVÿ& conn=op= time=-E\fãˆÑ,»§@·ãd@)\�¿@& conn=op= time=-E\f“ÃÑEVÿ& conn=op= time=-E\fe�ºb-¨@Î c@)\�¿@& conn=op= time=-E\fb»EVÿ& conn=op= time=-E\fž´˜Ÿ¨@ä3a@)\�¿@& conn=op= time=-E\fÓPµEVÿ& conn=op= time=-E\f™†®Î©@û[_@)\�¿@& conn=op= time=-E\fµ®³¸ÿ& conn=op= time=-E\fQ˜„©@„]@)\�¿@& conn=op= time=-E\f×¸ÿ& conn=op= time=-E\f÷=”:ö©@(¬[@)\�¿@& conn=op= time=-E\f”²”EVÿ& conn=op= time=-E\f{Û}qhª@?ÔY@)\�¿@& conn=op= time=-E\fúo~EVÿ& conn=op= time=-E\f^žx§Úª@UüW@)\�¿@& conn=op= time=-E\fÎxEVÿ& conn=op= time=-E\fÆ—r ÝL«@l$V@)\�¿@& conn=op= time=-E\f”#s EVÿ& conn=op= time=-E\f*d]!¿«@‚LT@)\�¿@& conn=op= time=-E\fûó^!EVÿ& conn=op= time=-E\f?ÕU"I1¬@™tR@)\�¿@& conn=op= time=-E\fbRV"EVÿ& conn=op= time=-E\fßïN#£¬@¯œP@)\�¿@& conn=op= time=-E\fíO#EVÿ& conn=op= time=-E\f^æ9$¶­@ÆÄN@)\�¿@& conn=op= time=-E\fƒ:$EVÿ& conn=op= time=-E\fÆ\5%쇭@ÝìL@)\�¿@& conn=op= time=-E\f®á5%EVÿ& conn=op= time=-E\fx¤-&"ú­@óK@)\�¿@& conn=op= time=-E\fØ).&EVÿ& conn=op= time=-E\fíV'Xl®@ =I@)\�¿@& conn=op= time=-E\fýÖ'EVÿ& conn=op= time=-E\fè7(ŽÞ®@ eG@)\�¿@& conn=op= time=-E\fNÜ(EVÿ& conn=op= time=-E\fD )ÄP¯@7�E@)\�¿@& conn=op= time=-E\f— )EVÿ& conn=op= time=-E\f$ó)ú¯@MµC@)\�¿@& conn=op= time=-E\f Åó)EVÿ& conn=op= time=-E\f]Õï*15°@dÝA@)\�¿@& conn=op= time=-E\f(9ð*EVÿ& conn=op= time=-E\f¬Û+g§°@{@@)\�¿@& conn=op= time=-E\fƳÛ+EVÿ& conn=op= time=-E\f›Ø,�±@‘->@)\�¿@& conn=op= time=-E\f|ŸØ,EVÿ& conn=op= time=-E\f²ƒÁ-Ó‹±@¨U<@)\�¿@& conn=op= time=-E\féÂ-EVÿ& conn=op= time=-E\f1Ú½. þ±@¾}:@)\�¿@& conn=op= time=-E\f/m¾.EVÿ& conn=op= time=-E\fz^˜/0@& conn=op= time=-E\fj³³/?p²@Õ¥8@)\�¿@& conn=op= time=-E\fê´/EVÿ& conn=op= time=-E\fn œ0vâ²@ëÍ6@)\�¿@& conn=op= time=-E\f¢´œ0EVÿ& conn=op= time=-E\f!¾b10@& conn=op= time=-E\f^õ–1¬T³@ö4@)\�¿@& conn=op= time=-E\fl—1EVÿ& conn=op= time=-E\f�‘2âÆ³@3@)\�¿@& conn=op= time=-E\fy ’2EVÿ& conn=op= time=-E\fu2,30@& conn=op= time=-E\fÄ~39´@/F1@)\�¿@& conn=op= time=-E\fn~3EVÿ& conn=op= time=-E\f@[o4N«´@Fn/@)\�¿@& conn=op= time=-E\fC©o4EVÿ& conn=op= time=-E\f5�ï40@& conn=op= time=-E\fæ–a5„µ@\–-@)\�¿@& conn=op= time=-E\f‰¿a5EVÿ& conn=op= time=-E\f[@W6º�µ@s¾+@)\�¿@& conn=op= time=-E\fÇ]W6EVÿ& conn=op= time=-E\fZÇ60@& conn=op= time=-E\f“çK7ñ¶@‰æ)@)\�¿@& conn=op= time=-E\f[�L7EVÿ& conn=op= time=-E\fT@8't¶@ (@)\�¿@& conn=op= time=-E\fÃ�@8EVÿ& conn=op= time=-E\f•l“80@& conn=op= time=-E\fGª59]æ¶@¶6&@)\�¿@& conn=op= time=-E\fi69EVÿ& conn=op= time=-E\fM.:“X·@Í^$@)\�¿@& conn=op= time=-E\f0 /:EVÿ& conn=op= time=-E\fàšs:0@& conn=op= time=-E\f…%;ÉÊ·@ä†"@)\�¿@& conn=op= time=-E\fïÞ%;EVÿ& conn=op= time=.E\f¿xÿ<¸@ú® @)\�¿@& conn=op= time=.E\fæëEVÿ& conn=op= time=.E\f带0@& conn=op= time=.E\f÷‰f6¯¸@×@)\�¿@& conn=op= time=.E\f£æfEVÿ& conn=op= time=.E\fŸ†[l!¹@'ÿ@)\�¿@& conn=op= time=.E\fÒò[EVÿ& conn=op= time=.E\fã†r0@& conn=op= time=.E\f1£S¢“¹@>'@)\�¿@& conn=op= time=.E\f[äSEVÿ& conn=op= time=.E\fÑmKغ@TO@)\�¿@& conn=op= time=.E\f/LEVÿ& conn=op= time=.E\fkyV0@& conn=op= time=.E\fY‡Dxº@kw@)\�¿@& conn=op= time=.E\fPÃDEVÿ& conn=op= time=.E\fÕ}0@& conn=op= time=.E\f’9Dêº@‚Ÿ@)\�¿@& conn=op= time=.E\f/�9EVÿ& conn=op= time=.E\fÀ4!z\»@˜Ç@)\�¿@& conn=op= time=.E\f©¼!EVÿ& conn=op= time=.E\f)Àå0@& conn=op= time=.E\f½ž±Î»@¯ï@)\�¿@& conn=op= time=.E\fE4EVÿ& conn=op= time=.E\fÜB ç@¼@Å@)\�¿@& conn=op= time=.E\f½Ê EVÿ& conn=op= time=.E\fäS¢ 0@& conn=op= time=.E\fØ^ ³¼@Ü?@)\�¿@& conn=op= time=.E\fŒÃ EVÿ& conn=op= time=.E\fqý S%½@òg @)\�¿@& conn=op= time=.E\f+ þ EVÿ& conn=op= time=.E\f÷~ 0@& conn=op= time=.E\fS?æ ‰—½@ � @)\�¿@& conn=op= time=.E\fMŸæ EVÿ& conn=op= time=.E\fèÝ ¿ ¾@¸@)\�¿@& conn=op= time=.E\f iÝ EVÿ& conn=op= time=.E\fµŒ\ 0@& conn=op= time=.E\fÇ‡Ñ ö{¾@6à@)\�¿@& conn=op= time=.E\fp Ò EVÿ& conn=op= time=.E\fè Ê,î¾@M@)\�¿@& conn=op= time=.E\fQ™Ê³¸ÿ& conn=op= time=.E\fuè.0@& conn=op= time=.E\f¾þÂb`¿@c0@)\�¿@& conn=op= time=.E\fvvÃEVÿ& conn=op= time=.E\fÅ2­˜Ò¿@zX@)\�¿@& conn=op= time=.E\ft±­EVÿ& conn=op= time=.E\fˆ 0@& conn=op= time=.E\f˜ð:0À& conn=op= time=.E\f™ê¢˜Ò¿@zX@¼t“¿À& conn=op= time=.E\fÞ2¤³¸ÿ& conn=op= time=.E\fæd˜˜Ò¿@zX@P�—¿À& conn=op= time=.E\f`%™³¸ÿ& conn=op= time=.E\fB’˜Ò¿@zX@㥛¿À& conn=op= time=.E\f)’³¸ÿ& conn=op= time=.E\fáÊ{˜Ò¿@zX@w¾Ÿ¿À& conn=op= time=.E\f3|³¸ÿ& conn=op= time=.E\f5!t˜Ò¿@zX@ ×£¿À& conn=op= time=.E\f8®v³¸ÿ& conn=op= time=.E\f "p˜Ò¿@zX@žï§¿À& conn=op= time=.E\f(×p³¸ÿ& conn=op= time=.E\fÓ¼Y˜Ò¿@zX@1¬¿À& conn=op= time=.E\f¤D[³¸ÿ& conn=op= time=.E\f‘xS˜Ò¿@zX@Å °¿À& conn=op= time=.E\f\ýT³¸ÿ& conn=op= time=.E\fPÀ?˜Ò¿@zX@X9´¿À& conn=op= time=.E\f@³¸ÿ& conn=op= time=.E\fÓ9˜Ò¿@zX@ìQ¸¿À& conn=op= time=.E\fiï9³¸ÿ& conn=op= time=.E\f³º4˜Ò¿@zX@j¼¿À& conn=op= time=.E\fà4³¸ÿ& conn=op= time=.E\f…h ˜Ò¿@zX@ƒÀ¿À& conn=op= time=.E\fíº ³¸ÿ& conn=op= time=.E\f‚˜Ò¿@zX@¦›Ä¿À& conn=op= time=.E\fQ9³¸ÿ& conn=op= time=.E\f]Ÿ˜Ò¿@zX@9´È¿À& conn=op= time=.E\f0õ³¸ÿ& conn=op= time=.E\f£7˜Ò¿@zX@ÍÌÌ¿À& conn=op= time=.E\ftD³¸ÿ& conn=op= time=.E\fdYï˜Ò¿@zX@`åпÀ& conn=op= time=.E\f+ìﳸÿ& conn=op= time=.E\fd�ê ˜Ò¿@zX@ôýÔ¿À& conn=op= time=.E\fÚë ³¸ÿ& conn=op= time=.E\fg½Õ!˜Ò¿@zX@‡Ù¿À& conn=op= time=.E\fÒAÖ!³¸ÿ& conn=op= time=.E\f šÑ"˜Ò¿@zX@/Ý¿À& conn=op= time=.E\f#-Ò"³¸ÿ& conn=op= time=.E\f9ý¿#˜Ò¿@zX@®Gá¿À& conn=op= time=.E\fZDÀ#³¸ÿ& conn=op= time=.E\fq¦¯$˜Ò¿@zX@B`å¿À& conn=op= time=.E\fjŸ°$³¸ÿ& conn=op= time=.E\fÊ\°%˜Ò¿@zX@Õxé¿À& conn=op= time=.E\f�›°%³¸ÿ& conn=op= time=.E\fO&¡&˜Ò¿@zX@h‘í¿À& conn=op= time=.E\fZ»¡&³¸ÿ& conn=op= time=.E\fG¯Ž'˜Ò¿@zX@ü©ñ¿À& conn=op= time=.E\f�'³¸ÿ& conn=op= time=.E\fòCŒ(˜Ò¿@zX@�Âõ¿À& conn=op= time=.E\fQšŒ(³¸ÿ& conn=op= time=.E\fªQw)˜Ò¿@zX@#Ûù¿À& conn=op= time=.E\f7Âw)³¸ÿ& conn=op= time=.E\f88t*˜Ò¿@zX@¶óý¿À& conn=op= time=.E\f{gt*³¸ÿ& conn=op= time=.E\fÜê`+˜Ò¿@zX@%ÀÀ& conn=op= time=.E\fˆ:a+³¸ÿ& conn=op= time=.E\få\_,˜Ò¿@zX@oÀÀ& conn=op= time=.E\fºª_,³¸ÿ& conn=op= time=.E\f4°I-˜Ò¿@zX@¸ÀÀ& conn=op= time=.E\f:åI-³¸ÿ& conn=op= time=.E\fÜ}@.˜Ò¿@zX@+ÀÀ& conn=op= time=.E\fÀ—@.³¸ÿ& conn=op= time=.E\fÐ9/0À& conn=op= time=.E\fYÝ7/˜Ò¿@zX@L7 ÀÀ& conn=op= time=.E\f·8/³¸ÿ& conn=op= time=.E\f9É,0˜Ò¿@zX@–C ÀÀ& conn=op= time=.E\få,0³¸ÿ& conn=op= time=.E\f½×00À& conn=op= time=.E\fA“$1˜Ò¿@zX@ßO ÀÀ& conn=op= time=.E\f°Ù$1³¸ÿ& conn=op= time=.E\f_22˜Ò¿@zX@)\ÀÀ& conn=op= time=.E\fã¸2³¸ÿ& conn=op= time=.E\f¼ÿš20À& conn=op= time=.E\fv3˜Ò¿@zX@shÀÀ& conn=op= time=.E\fÀº3³¸ÿ& conn=op= time=.E\fKù3˜Ò¿@zX@¼tÀÀ& conn=op= time=.E\fâÇù3³¸ÿ& conn=op= time=.E\f£yy40À& conn=op= time=.E\fÍÖñ4˜Ò¿@zX@�ÀÀ& conn=op= time=.E\fÃûñ4³¸ÿ& conn=op= time=.E\f5·æ5˜Ò¿@zX@P�ÀÀ& conn=op= time=.E\fo)ç5³¸ÿ& conn=op= time=.E\fŒQ60À& conn=op= time=.E\f‡?Ñ6˜Ò¿@zX@š™ÀÀ& conn=op= time=.E\fUÑ6³¸ÿ& conn=op= time=.E\fBÊ7˜Ò¿@zX@ã¥ÀÀ& conn=op= time=.E\fÎYÊ7³¸ÿ& conn=op= time=.E\f\=480À& conn=op= time=.E\fûòÄ8˜Ò¿@zX@-²ÀÀ& conn=op= time=.E\f+Å8³¸ÿ& conn=op= time=.E\fS¬9˜Ò¿@zX@w¾ÀÀ& conn=op= time=.E\f•^¬9³¸ÿ& conn=op= time=.E\f™›ü90À& conn=op= time=.E\f?“¦:˜Ò¿@zX@ÁÊ!ÀÀ& conn=op= time=.E\fµç¬:³¸ÿ& conn=op= time=/E\fŒb˜Ò¿@zX@ ×#ÀÀ& conn=op= time=/E\f§³¸ÿ& conn=op= time=/E\fŸ*;0À& conn=op= time=/E\fÖ]ö˜Ò¿@zX@Tã%ÀÀ& conn=op= time=/E\fÖrö³¸ÿ& conn=op= time=/E\f—>é˜Ò¿@zX@žï'ÀÀ& conn=op= time=/E\fÑa鳸ÿ& conn=op= time=/E\föÅâ˜Ò¿@zX@çû)ÀÀ& conn=op= time=/E\fܼ䳸ÿ& conn=op= time=/E\fk„ë0@& conn=op= time=/E\f©ÂÌÁê¾@Æc@çû)À@& conn=op= time=/E\fFÍEVÿ& conn=op= time=/E\f‹_Äê¾@$Þþ?çû)À@& conn=op= time=/E\fðij¸ÿ& conn=op= time=/E\f p¼½@½ôü?çû)À@& conn=op= time=/E\f@ù¼³¸ÿ& conn=op= time=/E\fqT©<3¼@U û?çû)À@& conn=op= time=/E\f3T«³¸ÿ& conn=op= time=/E\f ¢eK»@î!ù?çû)À@& conn=op= time=/E\fß—¢³¸ÿ& conn=op= time=/E\fÖV™Žcº@†8÷?çû)À@& conn=op= time=/E\f¹ñ™³¸ÿ& conn=op= time=/E\f0[� ·{¹@Oõ?çû)À@& conn=op= time=/E\f¹‘ ³¸ÿ& conn=op= time=/E\f¬Üz à“¸@·eó?çû)À@& conn=op= time=/E\fôp{ ³¸ÿ& conn=op= time=/E\fýPt  ¬·@O|ñ?çû)À@& conn=op= time=/E\fåÓt ³¸ÿ& conn=op= time=/E\f¹¹k 2Ķ@è’ï?çû)À@& conn=op= time=/E\fPl ³¸ÿ& conn=op= time=/E\fw9U [ܵ@€©í?çû)À@& conn=op= time=/E\fcU ³¸ÿ& conn=op= time=/E\f±"N„ô´@Àë?çû)À@& conn=op= time=/E\fþ}OEVÿ& conn=op= time=/E\fžG­ ´@±Öé?çû)À@& conn=op= time=/E\fÚH³¸ÿ& conn=op= time=/E\f½à.Ö$³@Iíç?çû)À@& conn=op= time=/E\fö@/³¸ÿ& conn=op= time=/E\f¡½#ÿ<²@âæ?çû)À@& conn=op= time=/E\f\A$³¸ÿ& conn=op= time=/E\f‚(U±@zä?çû)À@& conn=op= time=/E\fñÚEVÿ& conn=op= time=/E\f…Qm°@1â?çû)À@& conn=op= time=/E\fÓ³¸ÿ& conn=op= time=/E\f9Ä z…¯@«Gà?çû)À@& conn=op= time=/E\fßÓ ³¸ÿ& conn=op= time=/E\f;Õö£�®@D^Þ?çû)À@& conn=op= time=/E\fšf÷³¸ÿ& conn=op= time=/E\fgPô̵­@ÜtÜ?çû)À@& conn=op= time=/E\f¢èô³¸ÿ& conn=op= time=/E\foÜõͬ@t‹Ú?çû)À@& conn=op= time=/E\fØÜ³¸ÿ& conn=op= time=/E\f‰ÕÓæ«@ ¢Ø?çû)À@& conn=op= time=/E\fîÔ³¸ÿ& conn=op= time=/E\f9cÏGþª@¥¸Ö?çû)À@& conn=op= time=/E\fÝÏEVÿ& conn=op= time=/E\fLÈqª@>ÏÔ?çû)À@& conn=op= time=/E\f߂ȳ¸ÿ& conn=op= time=/E\fÆ¿³š.©@ÖåÒ?çû)À@& conn=op= time=/E\fó{´³¸ÿ& conn=op= time=/E\fl@­ÃF¨@oüÐ?çû)À@& conn=op= time=/E\fá­³¸ÿ& conn=op= time=/E\fÄ(—ì^§@Ï?çû)À@& conn=op= time=/E\f¹—³¸ÿ& conn=op= time=/E\fF>’w¦@Ÿ)Í?çû)À@& conn=op= time=/E\fƒ ”³¸ÿ& conn=op= time=/E\f´I>�¥@8@Ë?çû)À@& conn=op= time=/E\fÒ峸ÿ& conn=op= time=/E\f™¸xg§¤@ÐVÉ?çû)À@& conn=op= time=/E\f@£y³¸ÿ& conn=op= time=/E\f®Dr �¿£@imÇ?çû)À@& conn=op= time=/E\f­Zr EVÿ& conn=op= time=/E\f(¶É 0@& conn=op= time=/E\fIXZ!¹×¢@„Å?çû)À@& conn=op= time=/E\f`ÅZ!³¸ÿ& conn=op= time=/E\fŒÜM"âï¡@™šÃ?çû)À@& conn=op= time=/E\fÀ§N"³¸ÿ& conn=op= time=/E\fÑ}"0@& conn=op= time=/E\fFD# ¡@2±Á?çû)À@& conn=op= time=/E\f´GE#EVÿ& conn=op= time=/E\f– ;$4  @ÊÇ¿?çû)À@& conn=op= time=/E\f&˜;$EVÿ& conn=op= time=/E\fêÁW$0@& conn=op= time=/E\f¾61%]8Ÿ@cÞ½?çû)À@& conn=op= time=/E\f�³1%³¸ÿ& conn=op= time=/E\fÎÿ%0@& conn=op= time=/E\fÎÏ&†Pž@ûô»?çû)À@& conn=op= time=/E\fÐ&³¸ÿ& conn=op= time=/E\fv�'¯h�@” º?çû)À@& conn=op= time=/E\f¶Ö'EVÿ& conn=op= time=/E\f-ìÙ'0@& conn=op= time=/E\fÝ (Ø€œ@,"¸?çû)À@& conn=op= time=/E\f?õ (³¸ÿ& conn=op= time=/E\fxPý(™›@Ä8¶?çû)À@& conn=op= time=/E\fÊ…ý(³¸ÿ& conn=op= time=/E\fÄš´)0@& conn=op= time=/E\fDfñ)*±š@]O´?çû)À@& conn=op= time=/E\fGÑñ)³¸ÿ& conn=op= time=/E\f¤ýç*SÉ™@õe²?çû)À@& conn=op= time=/E\f­è*³¸ÿ& conn=op= time=/E\fO}}+0@& conn=op= time=/E\fÞ+|á˜@Ž|°?çû)À@& conn=op= time=/E\f6ˆÞ+³¸ÿ& conn=op= time=/E\f„ÃÐ,¥ù—@&“®?çû)À@& conn=op= time=/E\fËÍÐ,³¸ÿ& conn=op= time=/E\fçÊP-0@& conn=op= time=/E\f†Æ-Η@¿©¬?çû)À@& conn=op= time=/E\f„æÆ-³¸ÿ& conn=op= time=/E\fÒ1¼.÷)–@WÀª?çû)À@& conn=op= time=/E\f¿‰¼.³¸ÿ& conn=op= time=/E\f º/0@& conn=op= time=/E\f]O²/ B•@ïÖ¨?çû)À@& conn=op= time=/E\fж²/³¸ÿ& conn=op= time=/E\f&¨¦0IZ”@ˆí¦?çû)À@& conn=op= time=/E\fÈÿ¦0³¸ÿ& conn=op= time=/E\frߨ00@& conn=op= time=/E\f;'œ1rr“@ ¥?çû)À@& conn=op= time=/E\f¨„œ1EVÿ& conn=op= time=/E\f“wŽ2›Š’@¹£?çû)À@& conn=op= time=/E\fî�2³¸ÿ& conn=op= time=/E\fÒ0¤20@& conn=op= time=/E\fÁ…3Ä¢‘@Q1¡?çû)À@& conn=op= time=/E\fæ †3³¸ÿ& conn=op= time=/E\ftBx40@& conn=op= time=/E\f7z4íº�@êGŸ?çû)À@& conn=op= time=/E\f±¾z4³¸ÿ& conn=op= time=/E\fƒDb5Ó�@‚^�?çû)À@& conn=op= time=/E\fbÎb5EVÿ& conn=op= time=/E\fgÔ560@& conn=op= time=/E\f tW6?ëŽ@u›?çû)À@& conn=op= time=/E\fRÜW6³¸ÿ& conn=op= time=/E\f?lM7hŽ@³‹™?çû)À@& conn=op= time=/E\füÖN7³¸ÿ& conn=op= time=/E\f†ø80@& conn=op= time=/E\fgäC8‘�@K¢—?çû)À@& conn=op= time=/E\fkMD8EVÿ& conn=op= time=/E\féX99º3Œ@丕?çû)À@& conn=op= time=/E\f�):9³¸ÿ& conn=op= time=/E\f¡íñ90@& conn=op= time=/E\fÖ71:ãK‹@|Ï“?çû)À@& conn=op= time=/E\f²¢1:³¸ÿ& conn=op= time=/E\fü™¯:0@& conn=op= time=/E\f+P;ãK‹@|Ï“?žï'À@& conn=op= time=/E\f$Å;³¸ÿ& conn=op= time=0E\f“wãK‹@|Ï“?Tã%À@& conn=op= time=0E\f+"w³¸ÿ& conn=op= time=0E\f�,sãK‹@|Ï“? ×#À@& conn=op= time=0E\fq]s³¸ÿ& conn=op= time=0E\fµ6^ãK‹@|Ï“?ÁÊ!À@& conn=op= time=0E\fc¼^³¸ÿ& conn=op= time=0E\fjEWãK‹@|Ï“?w¾À@& conn=op= time=0E\føYW³¸ÿ& conn=op= time=0E\f2GNãK‹@|Ï“?-²À@& conn=op= time=0E\f�YN³¸ÿ& conn=op= time=0E\frm8ãK‹@|Ï“?ã¥À@& conn=op= time=0E\f˃8³¸ÿ& conn=op= time=0E\fZ>5ãK‹@|Ï“?š™À@& conn=op= time=0E\fƒä5³¸ÿ& conn=op= time=0E\fÌ™!ãK‹@|Ï“?P�À@& conn=op= time=0E\fõØ!³¸ÿ& conn=op= time=0E\fަãK‹@|Ï“?�À@& conn=op= time=0E\f ó¸ÿ& conn=op= time=0E\fÁ¿ ãK‹@|Ï“?¼tÀ@& conn=op= time=0E\fkö ³¸ÿ& conn=op= time=0E\fpë ãK‹@|Ï“?shÀ@& conn=op= time=0E\fÝ‚ ³¸ÿ& conn=op= time=0E\f©ò ãK‹@|Ï“?)\À@& conn=op= time=0E\fê÷ó ³¸ÿ& conn=op= time=0E\f¿¢ê ãK‹@|Ï“?ßO À@& conn=op= time=0E\fÊ©ë ³¸ÿ& conn=op= time=0E\fTxç ãK‹@|Ï“?–C À@& conn=op= time=0E\fèç ³¸ÿ& conn=op= time=0E\f†Ó ãK‹@|Ï“?L7 À@& conn=op= time=0E\fˆÔ ³¸ÿ& conn=op= time=0E\f›ŠÃãK‹@|Ï“?+À@& conn=op= time=0E\f ij¸ÿ& conn=op= time=0E\fª7ÀãK‹@|Ï“?¸À@& conn=op= time=0E\fF]À³¸ÿ& conn=op= time=0E\fŠ­ãK‹@|Ï“?oÀ@& conn=op= time=0E\fW­³¸ÿ& conn=op= time=0E\f^¨ãK‹@|Ï“?%À@& conn=op= time=0E\fþ´¨³¸ÿ& conn=op= time=0E\fqN”ãK‹@|Ï“?¶óý¿@& conn=op= time=0E\fzj”³¸ÿ& conn=op= time=0E\f7R�ãK‹@|Ï“?#Ûù¿@& conn=op= time=0E\f3è�³¸ÿ& conn=op= time=0E\fèy|ãK‹@|Ï“?�Âõ¿@& conn=op= time=0E\f¹Á|³¸ÿ& conn=op= time=0E\fÎüxãK‹@|Ï“?ü©ñ¿@& conn=op= time=0E\fæny³¸ÿ& conn=op= time=0E\fh#eãK‹@|Ï“?h‘í¿@& conn=op= time=0E\f–we³¸ÿ& conn=op= time=0E\fþ`ãK‹@|Ï“?Õxé¿@& conn=op= time=0E\fšŸa³¸ÿ& conn=op= time=0E\fYÌLãK‹@|Ï“?B`å¿@& conn=op= time=0E\f* M³¸ÿ& conn=op= time=0E\f2CIãK‹@|Ï“?®Gá¿@& conn=op= time=0E\f¶ãI³¸ÿ& conn=op= time=0E\f¸‹4ãK‹@|Ï“?/Ý¿@& conn=op= time=0E\fËÔ4³¸ÿ& conn=op= time=0E\fäz.ãK‹@|Ï“?‡Ù¿@& conn=op= time=0E\f +/³¸ÿ& conn=op= time=0E\fûÑãK‹@|Ï“?ôýÔ¿@& conn=op= time=0E\fh³¸ÿ& conn=op= time=0E\fCsã0@& conn=op= time=0E\f ÇãK‹@|Ï“?`åп@& conn=op= time=0E\f W³¸ÿ& conn=op= time=0E\ftÓ ãK‹@|Ï“?ÍÌÌ¿@& conn=op= time=0E\f8Y ³¸ÿ& conn=op= time=0E\fÆË¡0@& conn=op= time=0E\fö¼÷ãK‹@|Ï“?9´È¿@& conn=op= time=0E\flÃ÷³¸ÿ& conn=op= time=0E\fo±ïãK‹@|Ï“?¦›Ä¿@& conn=op= time=0E\fy:ð³¸ÿ& conn=op= time=0E\f×åƒ 0@& conn=op= time=0E\fnÄæ ãK‹@|Ï“?ƒÀ¿@& conn=op= time=0E\f1ç ³¸ÿ& conn=op= time=0E\fÊKÛ!ãK‹@|Ï“?j¼¿@& conn=op= time=0E\f™ÆÛ!³¸ÿ& conn=op= time=0E\fy×_"0@& conn=op= time=0E\f�•Ô"ãK‹@|Ï“?ìQ¸¿@& conn=op= time=0E\f°Ô"³¸ÿ& conn=op= time=0E\fªˆ¾#ãK‹@|Ï“?X9´¿@& conn=op= time=0E\f¿#³¸ÿ& conn=op= time=0E\fäþ:$0@& conn=op= time=0E\f?á¸$ãK‹@|Ï“?Å °¿@& conn=op= time=0E\f‚v¹$³¸ÿ& conn=op= time=0E\f¢ß±%ãK‹@|Ï“?1¬¿@& conn=op= time=0E\f͘²%³¸ÿ& conn=op= time=0E\f�—&0@& conn=op= time=0E\f·�&ãK‹@|Ï“?žï§¿@& conn=op= time=0E\fÍp�&³¸ÿ& conn=op= time=0E\f!£’'ãK‹@|Ï“? ×£¿@& conn=op= time=0E\f&“'³¸ÿ& conn=op= time=0E\f £Ü'0@& conn=op= time=0E\f=!‹(ãK‹@|Ï“?w¾Ÿ¿@& conn=op= time=0E\fä7‹(³¸ÿ& conn=op= time=0E\fëÂv)ãK‹@|Ï“?㥛¿@& conn=op= time=0E\f Mw)³¸ÿ& conn=op= time=0E\fá»±)0@& conn=op= time=0E\fñâp*ãK‹@|Ï“?P�—¿@& conn=op= time=0E\f0q*³¸ÿ& conn=op= time=0E\f)¡g+ãK‹@|Ï“?¼t“¿@& conn=op= time=0E\f ßg+³¸ÿ& conn=op= time=0E\fIíz+0@& conn=op= time=0E\fý ],ãK‹@|Ï“?)\�¿@& conn=op= time=0E\fMX],³¸ÿ& conn=op= time=0E\f|I-ãK‹@|Ï“?–C‹¿@& conn=op= time=0E\fáÜI-³¸ÿ& conn=op= time=0E\fMT-0@& conn=op= time=0E\f³B.ãK‹@|Ï“?+‡¿@& conn=op= time=0E\fÞC.³¸ÿ& conn=op= time=0E\fÎB/0@& conn=op= time=0E\fƒ©7/ãK‹@|Ï“?oƒ¿@& conn=op= time=0E\f¤á7/³¸ÿ& conn=op= time=0E\f±v*0ãK‹@|Ï“?¶ó}¿@& conn=op= time=0E\fË*0³¸ÿ& conn=op= time=0E\f°M×00@& conn=op= time=0E\fš%"1ãK‹@|Ï“?�Âu¿@& conn=op= time=0E\f52"1³¸ÿ& conn=op= time=0E\fÃ2ãK‹@|Ï“?h‘m¿@& conn=op= time=0E\fWB2³¸ÿ& conn=op= time=0E\f È©20@& conn=op= time=0E\fçÍ 3ãK‹@|Ï“?B`e¿@& conn=op= time=0E\f/8 3³¸ÿ& conn=op= time=0E\f%?4ãK‹@|Ï“?/]¿@& conn=op= time=0E\f ¥4³¸ÿ& conn=op= time=0E\fÁJŠ40@& conn=op= time=0E\f(Òé4ãK‹@|Ï“?ôýT¿@& conn=op= time=0E\fðïé4³¸ÿ& conn=op= time=0E\fÀ­Þ5ãK‹@|Ï“?ÍÌL¿@& conn=op= time=0E\fNÁÞ5³¸ÿ& conn=op= time=0E\fòòU60@& conn=op= time=0E\f'Ù6ãK‹@|Ï“?¦›D¿@& conn=op= time=0E\fÀvÙ6³¸ÿ& conn=op= time=0E\f8Ä7ãK‹@|Ï“?j<¿@& conn=op= time=0E\f›Ä7³¸ÿ& conn=op= time=0E\fD´:80@& conn=op= time=0E\f)¼8ãK‹@|Ï“?X94¿@& conn=op= time=0E\f÷K¼8³¸ÿ& conn=op= time=0E\fê´9ãK‹@|Ï“?1,¿@& conn=op= time=0E\flxµ9³¸ÿ& conn=op= time=0E\fr»:0@& conn=op= time=0E\fmŽ£:ãK‹@|Ï“? ×#¿@& conn=op= time=0E\fŽ«£:³¸ÿ& conn=op= time=1E\f )ãK‹@|Ï“?㥿@& conn=op= time=1E\fÁT³¸ÿ& conn=op= time=1E\fåÔC0@& conn=op= time=1E\f=ñíãK‹@|Ï“?¼t¿@& conn=op= time=1E\f–øí³¸ÿ& conn=op= time=1E\fEBÞãK‹@|Ï“?–C ¿@& conn=op= time=1E\fO�Þ³¸ÿ& conn=op= time=1E\f:žù0@& conn=op= time=1E\fTEØãK‹@|Ï“?o¿@& conn=op= time=1E\fO^س¸ÿ& conn=op= time=1E\f{ƒË0@& conn=op= time=1E\f= ÌãK‹@|Ï“?�Âõ¾@& conn=op= time=1E\f­R̳¸ÿ& conn=op= time=1E\f£#ÈãK‹@|Ï“?B`å¾@& conn=op= time=1E\fZ]ȳ¸ÿ& conn=op= time=1E\fø¦š0@& conn=op= time=1E\fxæ½ãK‹@|Ï“?ôýÔ¾@& conn=op= time=1E\fÚ6¾³¸ÿ& conn=op= time=1E\fÚ™¨ãK‹@|Ï“?¦›Ä¾@& conn=op= time=1E\f&f©³¸ÿ& conn=op= time=1E\f©%n0@& conn=op= time=1E\f$ £ãK‹@|Ï“?X9´¾@& conn=op= time=1E\f£³¸ÿ& conn=op= time=1E\f€’™ãK‹@|Ï“? ×£¾@& conn=op= time=1E\f¢š³¸ÿ& conn=op= time=1E\f|œ. 0@& conn=op= time=1E\f�݃ ãK‹@|Ï“?¼t“¾@& conn=op= time=1E\f4„ ³¸ÿ& conn=op= time=1E\fIÏz ãK‹@|Ï“?oƒ¾@& conn=op= time=1E\f4{ ³¸ÿ& conn=op= time=1E\f c 0@& conn=op= time=1E\f÷bp ãK‹@|Ï“?B`e¾@& conn=op= time=1E\f$¬p ³¸ÿ& conn=op= time=1E\fb�b ãK‹@|Ï“?¦›D¾@& conn=op= time=1E\fc ³¸ÿ& conn=op= time=1E\f©åÅ 0@& conn=op= time=1E\fm8X ãK‹@|Ï“? ×#¾@& conn=op= time=1E\fëTX ³¸ÿ& conn=op= time=1E\f‰ NãK‹@|Ï“?o¾@& conn=op= time=1E\f8N³¸ÿ& conn=op= time=1E\fr™0@& conn=op= time=1E\fîøBãK‹@|Ï“?¦›Ä½@& conn=op= time=1E\fzUC³¸ÿ& conn=op= time=1E\fܱ8ãK‹@|Ï“?oƒ½@& conn=op= time=1E\f¹89³¸ÿ& conn=op= time=1E\fØ¢c0@& conn=op= time=1E\f�å#ãK‹@|Ï“?o½@& conn=op= time=1E\f�6$³¸ÿ& conn=op= time=1E\f,µãK‹@|Ï“?€¥@& conn=op= time=1E\f¹ñ³¸ÿ& conn=op= time=1E\f<Ã/0@& conn=op= time=1E\fIãK‹@|Ï“?o=@& conn=op= time=1E\fúʳ¸ÿ& conn=op= time=1E\f>0@& conn=op= time=1E\fîÿ ãK‹@|Ï“?oƒ=@& conn=op= time=1E\f£'³¸ÿ& conn=op= time=1E\f±¯÷ãK‹@|Ï“?¦›Ä=@& conn=op= time=1E\fÐÞ÷³¸ÿ& conn=op= time=1E\fBœÈ0@& conn=op= time=1E\f²ZïãK‹@|Ï“?o>@& conn=op= time=1E\fӳﳸÿ& conn=op= time=1E\fbèãK‹@|Ï“? ×#>@& conn=op= time=1E\fgX賸ÿ& conn=op= time=1E\fº%‰0@& conn=op= time=1E\fÑ®ÑãK‹@|Ï“?¦›D>@& conn=op= time=1E\fÐ/Ò³¸ÿ& conn=op= time=1E\fÍ‹ÌãK‹@|Ï“?B`e>@& conn=op= time=1E\fäœÌ³¸ÿ& conn=op= time=1E\fMüR0@& conn=op= time=1E\f÷ÆãK‹@|Ï“?oƒ>@& conn=op= time=1E\f‘"Ƴ¸ÿ& conn=op= time=1E\fón°ãK‹@|Ï“?¼t“>@& conn=op= time=1E\f ±³¸ÿ& conn=op= time=1E\f h20@& conn=op= time=1E\f”«ãK‹@|Ï“? ×£>@& conn=op= time=1E\f «³¸ÿ& conn=op= time=1E\f Y¡ãK‹@|Ï“?X9´>@& conn=op= time=1E\fúÚ¡³¸ÿ& conn=op= time=1E\f;Jü0@& conn=op= time=1E\fyíˆãK‹@|Ï“?¦›Ä>@& conn=op= time=1E\föB‰³¸ÿ& conn=op= time=1E\fn€ãK‹@|Ï“?ôýÔ>@& conn=op= time=1E\f¹Š€³¸ÿ& conn=op= time=1E\fg­É0@& conn=op= time=1E\f¥hzãK‹@|Ï“?B`å>@& conn=op= time=1E\f-”z³¸ÿ& conn=op= time=1E\f¸lh ãK‹@|Ï“?�Âõ>@& conn=op= time=1E\f`úh ³¸ÿ& conn=op= time=1E\fËzœ 0@& conn=op= time=1E\f¶jb!ãK‹@|Ï“?o?@& conn=op= time=1E\fcéb!³¸ÿ& conn=op= time=1E\ftƒ\"ãK‹@|Ï“?–C ?@& conn=op= time=1E\fc«\"³¸ÿ& conn=op= time=1E\fÃG{"0@& conn=op= time=1E\fKæJ#ãK‹@|Ï“?¼t?@& conn=op= time=1E\fþ K#³¸ÿ& conn=op= time=1E\f„@$ãK‹@|Ï“?ã¥?@& conn=op= time=1E\fÐLA$³¸ÿ& conn=op= time=1E\fl‡A$0@& conn=op= time=1E\f É(%ãK‹@|Ï“? ×#?@& conn=op= time=1E\f /)%³¸ÿ& conn=op= time=1E\fÙå&0@& conn=op= time=1E\fÕK,&ãK‹@|Ï“?1,?@& conn=op= time=1E\fe½,&³¸ÿ& conn=op= time=1E\fº'ãK‹@|Ï“?X94?@& conn=op= time=1E\få¤'³¸ÿ& conn=op= time=1E\f­ø'0@& conn=op= time=1E\fë(ãK‹@|Ï“?j@ôýT?@& conn=op= time=2E\f‰r¼8EVÿ& conn=op= time=2E\fݰ9Á@0@@ôýT?@& conn=op= time=2E\fÅM±9EVÿ& conn=op= time=2E\f\Š:0@& conn=op= time=2E\f{ ©:�ÅÁ@ȃA@ôýT?@& conn=op= time=2E\f"é:³¸ÿ& conn=op= time=3E\fKŸvÂ@aC@ôýT?@& conn=op= time=3E\fñ4³¸ÿ& conn=op= time=3E\f íÁ0@& conn=op= time=3E\fò÷›&Ã@ùŠD@ôýT?@& conn=op= time=3E\frIø³¸ÿ& conn=op= time=3E\føì"×Ã@’F@ôýT?@& conn=op= time=3E\fí.쳸ÿ& conn=op= time=3E\f|&ˆ0@& conn=op= time=3E\f`Ð⩇Ä@*’G@ôýT?@& conn=op= time=3E\fNœã³¸ÿ& conn=op= time=3E\f»ÁË08Å@ÃI@ôýT?@& conn=op= time=3E\fò`̳¸ÿ& conn=op= time=3E\fd»U0@& conn=op= time=3E\fµŸÁ·èÅ@[™J@ôýT?@& conn=op= time=3E\f× Â³¸ÿ& conn=op= time=3E\f«k¹>™Æ@óL@ôýT?@& conn=op= time=3E\f/ï¹EVÿ& conn=op= time=3E\fÆ`+0@& conn=op= time=3E\f�X®ÅIÇ@Œ M@ôýT?@& conn=op= time=3E\f·ï®EVÿ& conn=op= time=3E\f›l¤LúÇ@$$O@ôýT?@& conn=op= time=3E\fØò¤EVÿ& conn=op= time=3E\f:Ðò0@& conn=op= time=3E\fÔ£˜ÓªÈ@½§P@ôýT?@& conn=op= time=3E\fg¸ÿ& conn=op= time=3E\f“Њ Z[É@U+R@ôýT?@& conn=op= time=3E\fß*‹ ³¸ÿ& conn=op= time=3E\f±¦ 0@& conn=op= time=3E\f¦b| á Ê@î®S@ôýT?@& conn=op= time=3E\f­u| ³¸ÿ& conn=op= time=3E\füöm h¼Ê@†2U@ôýT?@& conn=op= time=3E\f8ln ³¸ÿ& conn=op= time=3E\fÊY 0@& conn=op= time=3E\fÄ€d ïlË@¶V@ôýT?@& conn=op= time=3E\fE=e ³¸ÿ& conn=op= time=3E\fD¦[ vÌ@·9X@ôýT?@& conn=op= time=3E\fÆ=\ ³¸ÿ& conn=op= time=3E\f‘‘_ 0@& conn=op= time=3E\f\FýÍÌ@O½Y@ôýT?@& conn=op= time=3E\fÉ:F³¸ÿ& conn=op= time=3E\fBs*0@& conn=op= time=3E\fN|H„~Í@è@[@ôýT?@& conn=op= time=3E\fƒéH³¸ÿ& conn=op= time=3E\fS= /Î@€Ä\@ôýT?@& conn=op= time=3E\fœ=³¸ÿ& conn=op= time=3E\f Íú0@& conn=op= time=3E\fÙÃ#’ßÎ@H^@ôýT?@& conn=op= time=3E\f6$³¸ÿ& conn=op= time=3E\fóð�Ï@±Ë_@ôýT?@& conn=op= time=3E\fŠ[³¸ÿ& conn=op= time=3E\f¶F¿0@& conn=op= time=3E\fqH @Ð@JOa@ôýT?@& conn=op= time=3E\fCˆ³¸ÿ& conn=op= time=3E\f¹­'ñÐ@âÒb@ôýT?@& conn=op= time=3E\fZ3 ³¸ÿ& conn=op= time=3E\f¬m•0@& conn=op= time=3E\fÝ{ÿ®¡Ñ@zVd@ôýT?@& conn=op= time=3E\fLEVÿ& conn=op= time=3E\fZè5RÒ@Úe@ôýT?@& conn=op= time=3E\fÅ„èEVÿ& conn=op= time=3E\fù+i0@& conn=op= time=3E\f†åß¼Ó@«]g@ôýT?@& conn=op= time=3E\fRlàEVÿ& conn=op= time=3E\fTÙC³Ó@Dáh@ôýT?@& conn=op= time=3E\f«ÙEVÿ& conn=op= time=3E\fÕtG0@& conn=op= time=3E\f¦ÄÊcÔ@Üdj@ôýT?@& conn=op= time=3E\fqëÄEVÿ& conn=op= time=3E\f½;¼QÕ@uèk@ôýT?@& conn=op= time=3E\fí±¼EVÿ& conn=op= time=3E\fEp0@& conn=op= time=3E\f‘W¶ÙÄÕ@ lm@ôýT?@& conn=op= time=3E\fvº¶EVÿ& conn=op= time=3E\fð«`uÖ@¥ïn@ôýT?@& conn=op= time=3E\fëˬEVÿ& conn=op= time=3E\fæ0@& conn=op= time=3E\f²D”ç%×@>sp@ôýT?@& conn=op= time=3E\f"«”EVÿ& conn=op= time=3E\f!ŠnÖ×@Ööq@ôýT?@& conn=op= time=3E\f)šŠEVÿ& conn=op= time=3E\fµ5¸0@& conn=op= time=3E\f5…õ†Ø@ozs@ôýT?@& conn=op= time=3E\f/±…³¸ÿ& conn=op= time=3E\f‘}|7Ù@þt@ôýT?@& conn=op= time=3E\f]£}³¸ÿ& conn=op= time=3E\f,•‚0@& conn=op= time=3E\f_4f èÙ@ �v@ôýT?@& conn=op= time=3E\f–žf ³¸ÿ& conn=op= time=3E\f�^J!0@& conn=op= time=3E\fuð]!Š˜Ú@8x@ôýT?@& conn=op= time=3E\fnƒ^!³¸ÿ& conn=op= time=3E\fËäT"IÛ@Јy@ôýT?@& conn=op= time=3E\fOU"³¸ÿ& conn=op= time=3E\fs�#0@& conn=op= time=3E\fSéK#˜ùÛ@i {@ôýT?@& conn=op= time=3E\f�iÔ,ÞÞâ@/…@ôýT?@& conn=op= time=3E\f–ÓÔ,³¸ÿ& conn=op= time=3E\fÓÊ-e�ã@ûÙ…@ôýT?@& conn=op= time=3E\fªBÊ-³¸ÿ& conn=op= time=3E\f¥îÖ-0@& conn=op= time=3E\f_�À.ì?ä@Ç›†@ôýT?@& conn=op= time=3E\fYûÀ.³¸ÿ& conn=op= time=3E\fu´¨/sðä@“]‡@ôýT?@& conn=op= time=3E\fxg©/³¸ÿ& conn=op= time=3E\f 4°/0@& conn=op= time=3E\fÈã¥0ú å@_ˆ@ôýT?@& conn=op= time=3E\få{¦0³¸ÿ& conn=op= time=3E\fó�‰10@& conn=op= time=3E\f”÷›1�Qæ@,áˆ@ôýT?@& conn=op= time=3E\fi.œ1³¸ÿ& conn=op= time=3E\f©-†2ç@ø¢‰@ôýT?@& conn=op= time=3E\f¸†2EVÿ& conn=op= time=3E\fãö\30@& conn=op= time=3E\fÚö3�²ç@ÄdŠ@ôýT?@& conn=op= time=3E\f³Ì€3EVÿ& conn=op= time=3E\f"Æv4cè@�&‹@ôýT?@& conn=op= time=3E\f†?w4EVÿ& conn=op= time=3E\fb650@& conn=op= time=3E\f«úm5�é@]è‹@ôýT?@& conn=op= time=3E\f„n5EVÿ& conn=op= time=3E\f _U6$Äé@)ªŒ@ôýT?@& conn=op= time=3E\fëáU6EVÿ& conn=op= time=3E\fD6ô60@& conn=op= time=3E\f°«H7«tê@õk�@ôýT?@& conn=op= time=3E\f5øH7EVÿ& conn=op= time=3E\fs J82%ë@Á-Ž@ôýT?@& conn=op= time=3E\f¢�J8EVÿ& conn=op= time=3E\f†h«80@& conn=op= time=3E\fFæ<9¹Õë@�ïŽ@ôýT?@& conn=op= time=3E\fðK>9EVÿ& conn=op= time=3E\fôÁ3:@†ì@Z±�@ôýT?@& conn=op= time=3E\fÚ3:³¸ÿ& conn=op= time=3E\fñÙ|:0@& conn=op= time=3E\f6¯;Ç6í@&s�@ôýT?@& conn=op= time=3E\fhÃ;³¸ÿ& conn=op= time=4E\f¼¤vNçí@ò4‘@ôýT?@& conn=op= time=4E\fÕ°wEVÿ& conn=op= time=4E\fž'¨0@& conn=op= time=4E\f8ÙlÕ—î@¾ö‘@ôýT?@& conn=op= time=4E\f —mEVÿ& conn=op= time=4E\fôD`\Hï@‹¸’@ôýT?@& conn=op= time=4E\f-|`³¸ÿ& conn=op= time=4E\fË®v0@& conn=op= time=4E\f�*Xãøï@Wz“@ôýT?@& conn=op= time=4E\f°�X³¸ÿ& conn=op= time=4E\f4¬Nj©ð@#<”@ôýT?@& conn=op= time=4E\f¦7O³¸ÿ& conn=op= time=4E\f+FT0@& conn=op= time=4E\f( 7ñYñ@ïý”@ôýT?@& conn=op= time=4E\fcT7³¸ÿ& conn=op= time=4E\f(v0@& conn=op= time=4E\fÓæ7x ò@»¿•@ôýT?@& conn=op= time=4E\f›b8³¸ÿ& conn=op= time=4E\f¨-ÿºò@ˆ�–@ôýT?@& conn=op= time=4E\fë©-³¸ÿ& conn=op= time=4E\f5+Þ0@& conn=op= time=4E\f!†kó@TC—@ôýT?@& conn=op= time=4E\f@r³¸ÿ& conn=op= time=4E\f+ä  ô@ ˜@ôýT?@& conn=op= time=4E\f¿z ³¸ÿ& conn=op= time=4E\fzg� 0@& conn=op= time=4E\f!$þ ”Ìô@ìÆ˜@ôýT?@& conn=op= time=4E\fÝ|þ ³¸ÿ& conn=op= time=4E\fŤñ }õ@¸ˆ™@ôýT?@& conn=op= time=4E\f§ò ³¸ÿ& conn=op= time=4E\f´äe 0@& conn=op= time=4E\f(è ¢-ö@…Jš@ôýT?@& conn=op= time=4E\f0¢è ³¸ÿ& conn=op= time=4E\f!Íæ )Þö@Q ›@ôýT?@& conn=op= time=4E\fgç ³¸ÿ& conn=op= time=4E\fÕáL 0@& conn=op= time=4E\f;GÍ °Ž÷@Λ@ôýT?@& conn=op= time=4E\fªòÍ ³¸ÿ& conn=op= time=4E\fW"Ã7?ø@é�œ@ôýT?@& conn=op= time=4E\feUó¸ÿ& conn=op= time=4E\fö¤ 0@& conn=op= time=4E\fnö·¾ïø@¶Q�@ôýT?@& conn=op= time=4E\fT6¸³¸ÿ& conn=op= time=4E\fî·³E ù@‚ž@ôýT?@& conn=op= time=4E\ft*´³¸ÿ& conn=op= time=4E\f6ïÞ0@& conn=op= time=4E\fæ�ÌPú@NÕž@ôýT?@& conn=op= time=4E\fÈ´�³¸ÿ& conn=op= time=4E\f|#—Sû@—Ÿ@ôýT?@& conn=op= time=4E\f ˜³¸ÿ& conn=op= time=4E\f2d½0@& conn=op= time=4E\fñ…Ú±û@æX @ôýT?@& conn=op= time=4E\f=†³¸ÿ& conn=op= time=4E\f¶ŽzEVÿ& conn=op= time=4E\f>’zabü@³¡@ôýT?@& conn=op= time=4E\f<æz0@& conn=op= time=4E\f’ƒoèý@Ü¡@ôýT?@& conn=op= time=4E\fædpEVÿ& conn=op= time=4E\fQS]0@& conn=op= time=4E\fj{goÃý@Kž¢@ôýT?@& conn=op= time=4E\f£¹gEVÿ& conn=op= time=4E\fC`ösþ@`£@ôýT?@& conn=op= time=4E\f)~`EVÿ& conn=op= time=4E\f¸Ð#0@& conn=op= time=4E\f7ÚS}$ÿ@ä!¤@ôýT?@& conn=op= time=4E\fÈÆÑ0@& conn=op= time=4E\fì MóA)§@ôýT?@& conn=op= time=4E\fS©EVÿ& conn=op= time=4E\f1]�KAáê§@ôýT?@& conn=op= time=4E\f˜EVÿ& conn=op= time=4E\fä™0@& conn=op= time=4E\fôs Ô£A­¬¨@ôýT?@& conn=op= time=4E\fÁ EVÿ& conn=op= time=4E\fÞúüAyn©@ôýT?@& conn=op= time=4E\f~7û³¸ÿ& conn=op= time=4E\fä£]0@& conn=op= time=4E\fwæï[TAE0ª@ôýT?@& conn=op= time=4E\f²lð³¸ÿ& conn=op= time=4E\f˜Úå ž¬Aòª@ôýT?@& conn=op= time=4E\f®æ ³¸ÿ& conn=op= time=4E\fŸ˜)!0@& conn=op= time=4E\f�iÛ!âAÞ³«@ôýT?@& conn=op= time=4E\fÒÉÛ!³¸ÿ& conn=op= time=4E\fáÑ"%]Aªu¬@ôýT?@& conn=op= time=4E\fJÑ"³¸ÿ& conn=op= time=4E\fëÌ #0@& conn=op= time=4E\fÄ�Ç#iµAv7­@ôýT?@& conn=op= time=4E\f¹ÜÇ#³¸ÿ& conn=op= time=4E\fãgº$¬ ABù­@ôýT?@& conn=op= time=4E\fߺ$³¸ÿ& conn=op= time=4E\fª³Ô$0@& conn=op= time=4E\fžŒ±%ðeA»®@ôýT?@& conn=op= time=4E\fßN²%³¸ÿ& conn=op= time=4E\fÊñ&0@& conn=op= time=4E\fà\£&3¾AÛ|¯@ôýT?@& conn=op= time=4E\f[|£&³¸ÿ& conn=op= time=4E\f˜d”'wA§>°@ôýT?@& conn=op= time=4E\f x”'³¸ÿ& conn=op= time=4E\f]Ý\(0@& conn=op= time=4E\f Ü‚(ºnAs±@ôýT?@& conn=op= time=4E\fé,ƒ(³¸ÿ& conn=op= time=4E\f]Æu)þÆA?±@ôýT?@& conn=op= time=4E\fõ5v)³¸ÿ& conn=op= time=4E\fäf=*0@& conn=op= time=4E\fqöj*AA „²@ôýT?@& conn=op= time=4E\f4k*³¸ÿ& conn=op= time=4E\fé®b+…wAØE³@ôýT?@& conn=op= time=4E\fµöb+³¸ÿ& conn=op= time=4E\fÅ ,0@& conn=op= time=4E\f»¨Z,ÈÏA¤´@ôýT?@& conn=op= time=4E\fQ*[,³¸ÿ& conn=op= time=4E\fB:S- (ApÉ´@ôýT?@& conn=op= time=4E\fŠÏS-³¸ÿ& conn=op= time=4E\føãá-0@& conn=op= time=4E\fÀ§:.O€A=‹µ@ôýT?@& conn=op= time=4E\f$è:.³¸ÿ& conn=op= time=4E\fÚ}-/“ØA M¶@ôýT?@& conn=op= time=4E\f|Ä-/³¸ÿ& conn=op= time=4E\fV�/0@& conn=op= time=4E\fV!0Ö0AÕ·@ôýT?@& conn=op= time=4E\fâz!0³¸ÿ& conn=op= time=4E\f(1‰A¡Ð·@ôýT?@& conn=op= time=4E\f%Š1³¸ÿ& conn=op= time=4E\f¶¶y10@& conn=op= time=4E\fØ@2]áAm’¸@ôýT?@& conn=op= time=4E\fa©2EVÿ& conn=op= time=4E\f©Ö3¡9 A:T¹@ôýT?@& conn=op= time=4E\fö03EVÿ& conn=op= time=4E\f¸|D30@& conn=op= time=4E\f?Éÿ3ä‘ Aº@ôýT?@& conn=op= time=4E\fB4EVÿ& conn=op= time=4E\fCÔå4(ê AÒ׺@ôýT?@& conn=op= time=4E\f@zæ4EVÿ& conn=op= time=4E\fP50@& conn=op= time=4E\f%ˆà5kB Až™»@ôýT?@& conn=op= time=4E\f•à5EVÿ& conn=op= time=4E\fx8Ó6¯š Aj[¼@ôýT?@& conn=op= time=4E\f;rÓ6EVÿ& conn=op= time=4E\f,6é60@& conn=op= time=4E\fz”Ç7òò A7½@ôýT?@& conn=op= time=4E\faÿÇ7EVÿ& conn=op= time=4E\fc„·80@& conn=op= time=4E\fŒÚ¼86K Aß½@ôýT?@& conn=op= time=4E\fg¶½8EVÿ& conn=op= time=4E\f…iµ9y£ AÏ ¾@ôýT?@& conn=op= time=4E\f–ïµ9EVÿ& conn=op= time=4E\fšqŽ:0@& conn=op= time=4E\fÌÀª:½û A›b¿@ôýT?@& conn=op= time=4E\f¹V«:EVÿ& conn=op= time=4E\fÂÏ’;T Ah$À@ôýT?@& conn=op= time=4E\f>“;³¸ÿ& conn=op= time=5E\f«Í·0@& conn=op= time=5E\fÿ�ìD¬ A4æÀ@ôýT?@& conn=op= time=5E\f5í³¸ÿ& conn=op= time=5E\fSæ‡ A¨Á@ôýT?@& conn=op= time=5E\f¶¿æ³¸ÿ& conn=op= time=5E\fua�0@& conn=op= time=5E\fõ‚ßË\ AÌiÂ@ôýT?@& conn=op= time=5E\f‰Þß³¸ÿ& conn=op= time=5E\f $×µ A˜+Ã@ôýT?@& conn=op= time=5E\f“è׳¸ÿ& conn=op= time=5E\f–©l0@& conn=op= time=5E\fQ¥¿R AeíÃ@ôýT?@& conn=op= time=5E\f‘Þ¿EVÿ& conn=op= time=5E\f’È´•eA1¯Ä@ôýT?@& conn=op= time=5E\f{-µ³¸ÿ& conn=op= time=5E\fä:0@& conn=op= time=5E\f™½©Ù½AýpÅ@ôýT?@& conn=op= time=5E\f *ª³¸ÿ& conn=op= time=5E\f‚‘¢AÉ2Æ@ôýT?@& conn=op= time=5E\f•¢³¸ÿ& conn=op= time=5E\f{E0@& conn=op= time=5E\f!óš`nA–ôÆ@ôýT?@& conn=op= time=5E\f>{›³¸ÿ& conn=op= time=5E\fŸƒ £ÆAb¶Ç@ôýT?@& conn=op= time=5E\f<4„ ³¸ÿ& conn=op= time=5E\f.ÍÜ 0@& conn=op= time=5E\f·{ çA.xÈ@ôýT?@& conn=op= time=5E\fÛÈ{ ³¸ÿ& conn=op= time=5E\f_#ANþ@)\�?@& conn=op= time=6E\f\nv³¸ÿ& conn=op= time=6E\fÅ–lâw#AB ÿ@)\�?@& conn=op= time=6E\fxmEVÿ& conn=op= time=6E\fÒÐv0@& conn=op= time=6E\fèfaâw#AB ÿ@¼t“?@& conn=op= time=6E\fͳa³¸ÿ& conn=op= time=6E\fKâw#AB ÿ@P�—?@& conn=op= time=6E\fâ$K³¸ÿ& conn=op= time=6E\fCDâw#AB ÿ@㥛?@& conn=op= time=6E\f¥˜D³¸ÿ& conn=op= time=6E\f8ç=âw#AB ÿ@w¾Ÿ?@& conn=op= time=6E\f_d>³¸ÿ& conn=op= time=6E\f}ò)âw#AB ÿ@ ×£?@& conn=op= time=6E\f¦ˆ*³¸ÿ& conn=op= time=6E\f½±&âw#AB ÿ@žï§?@& conn=op= time=6E\fÈ'³¸ÿ& conn=op= time=6E\fWÎâw#AB ÿ@1¬?@& conn=op= time=6E\f¬2³¸ÿ& conn=op= time=6E\fà âw#AB ÿ@Å °?@& conn=op= time=6E\f:w ³¸ÿ& conn=op= time=6E\f§Iâw#AB ÿ@X9´?@& conn=op= time=6E\foz³¸ÿ& conn=op= time=6E\f¶%òâw#AB ÿ@ìQ¸?@& conn=op= time=6E\f'Ïò³¸ÿ& conn=op= time=6E\ftXî âw#AB ÿ@j¼?@& conn=op= time=6E\f9íî ³¸ÿ& conn=op= time=6E\fwKÛ!âw#AB ÿ@ƒÀ?@& conn=op= time=6E\f�öÛ!³¸ÿ& conn=op= time=6E\f ,È"âw#AB ÿ@¦›Ä?@& conn=op= time=6E\fäŒÈ"³¸ÿ& conn=op= time=6E\fÒdÃ#âw#AB ÿ@9´È?@& conn=op= time=6E\f“Ä#³¸ÿ& conn=op= time=6E\f*»$âw#AB ÿ@ÍÌÌ?@& conn=op= time=6E\fVh»$³¸ÿ& conn=op= time=6E\fò–¯%âw#AB ÿ@`åÐ?@& conn=op= time=6E\f�°%³¸ÿ& conn=op= time=6E\fÄÛ˜&âw#AB ÿ@ôýÔ?@& conn=op= time=6E\fP™&³¸ÿ& conn=op= time=6E\f5|�'âw#AB ÿ@‡Ù?@& conn=op= time=6E\f£Î�'³¸ÿ& conn=op= time=6E\f'‚‰(âw#AB ÿ@/Ý?@& conn=op= time=6E\f¥ü‰(³¸ÿ& conn=op= time=6E\fÛu)âw#AB ÿ@®Gá?@& conn=op= time=6E\fƒŠv)³¸ÿ& conn=op= time=6E\fª6o*âw#AB ÿ@B`å?@& conn=op= time=6E\fs3p*³¸ÿ& conn=op= time=6E\fœi+âw#AB ÿ@Õxé?@& conn=op= time=6E\fÍói+³¸ÿ& conn=op= time=6E\f’ T,âw#AB ÿ@h‘í?@& conn=op= time=6E\f‚aT,³¸ÿ& conn=op= time=6E\fÆzS-âw#AB ÿ@ü©ñ?@& conn=op= time=6E\f¤ðS-³¸ÿ& conn=op= time=6E\fý«@.âw#AB ÿ@�Âõ?@& conn=op= time=6E\f‹A.³¸ÿ& conn=op= time=6E\f(÷:/âw#AB ÿ@#Ûù?@& conn=op= time=6E\f¿Q;/³¸ÿ& conn=op= time=6E\f­C'0âw#AB ÿ@¶óý?@& conn=op= time=6E\fÁ”'0³¸ÿ& conn=op= time=6E\f£Ž"1âw#AB ÿ@%@@& conn=op= time=6E\fšþ"1³¸ÿ& conn=op= time=6E\f¿2âw#AB ÿ@o@@& conn=op= time=6E\f$2³¸ÿ& conn=op= time=6E\fñ 3âw#AB ÿ@¸@@& conn=op= time=6E\fì 3³¸ÿ& conn=op= time=6E\f Òö3âw#AB ÿ@+@@& conn=op= time=6E\fÔëö3³¸ÿ& conn=op= time=6E\fÔEH40@& conn=op= time=6E\fŒmî4âw#AB ÿ@L7 @@& conn=op= time=6E\f´î4³¸ÿ& conn=op= time=6E\f”hã5âw#AB ÿ@–C @@& conn=op= time=6E\f,yã5³¸ÿ& conn=op= time=6E\f-ßã50@& conn=op= time=6E\fÇÙ6P-#AØâÿ@–C @@& conn=op= time=6E\fá`Ú6³¸ÿ& conn=op= time=6E\f:’Ï7¾â"A7]A–C @@& conn=op= time=6E\f§ÎÏ7³¸ÿ& conn=op= time=6E\fs¤¸8,˜"AÉA–C @@& conn=op= time=6E\fÃä¸8³¸ÿ& conn=op= time=6E\fÌW²9šM"AÌ4A–C @@& conn=op= time=6E\f³¸ÿ& conn=op= time=7E\fyx7ÂÄA×4 A–C @@& conn=op= time=7E\fO‰8³¸ÿ& conn=op= time=7E\fº�/0zA¢  A–C @@& conn=op= time=7E\f|0³¸ÿ& conn=op= time=7E\fV½ž/Am A–C @@& conn=op= time=7E\fÈ_³¸ÿ& conn=op= time=7E\fÈ¿ åA7x A–C @@& conn=op= time=7E\fòI³¸ÿ& conn=op= time=7E\f«yšAä A–C @@& conn=op= time=7E\f¯G³¸ÿ& conn=op= time=7E\fY/ûçOAÍO A–C @@& conn=op= time=7E\fɾû³¸ÿ& conn=op= time=7E\fÒ<õUA˜» A–C @@& conn=op= time=7E\fRZõ³¸ÿ& conn=op= time=7E\fÀÄÞúAb' A–C @@& conn=op= time=7E\fRß³¸ÿ& conn=op= time=7E\f•¹Ú1pA-“ A–C @@& conn=op= time=7E\fyHÛ³¸ÿ& conn=op= time=7E\fe0@& conn=op= time=7E\fxП%Aøþ A–C @@& conn=op= time=7E\fZÓг¸ÿ& conn=op= time=7E\f�†Ã ÛAÂj A–C @@& conn=op= time=7E\f¤@ij¸ÿ& conn=op= time=7E\fK(é0@& conn=op= time=7E\föyª{�A�Ö A–C @@& conn=op= time=7E\f<«³¸ÿ& conn=op= time=7E\f�¶¬èEAXBA–C @@& conn=op= time=7E\f•­³¸ÿ& conn=op= time=7E\f¯°0@& conn=op= time=7E\fÅ—VûA"®A–C @@& conn=op= time=7E\f}w—³¸ÿ& conn=op= time=7E\f¶mŽİAíA–C @@& conn=op= time=7E\fp�³¸ÿ& conn=op= time=7E\fã°�0@& conn=op= time=7E\fÐ5ˆ2fA¸…A–C @@& conn=op= time=7E\f«¿ˆ³¸ÿ& conn=op= time=7E\fTm\0@& conn=op= time=7E\f>&~³¸ÿ& conn=op= time=7E\feI~ AƒñA–C @@& conn=op= time=7E\f¯¼f ÑAM]A–C @@& conn=op= time=7E\fS3g ³¸ÿ& conn=op= time=7E\fß,!0@& conn=op= time=7E\f¥,^!|†AÉA–C @@& conn=op= time=7E\fa¢^!³¸ÿ& conn=op= time=7E\f°W"ê;Aã4A–C @@& conn=op= time=7E\fÞW"³¸ÿ& conn=op= time=7E\fè¿ü"0@& conn=op= time=7E\f$-K#XñA­ A–C @@& conn=op= time=7E\f½lK#³¸ÿ& conn=op= time=7E\fn;$ŦAx A–C @@& conn=op= time=7E\fÍ;$³¸ÿ& conn=op= time=7E\fÓqÀ$0@& conn=op= time=7E\fË.%3\ACxA–C @@& conn=op= time=7E\fm/%³¸ÿ& conn=op= time=7E\fé«&&¡AäA–C @@& conn=op= time=7E\f+-'&³¸ÿ& conn=op= time=7E\fl{š&0@& conn=op= time=7E\fŒ.'ÇAØOA–C @@& conn=op= time=7E\f.k'³¸ÿ& conn=op= time=7E\fŸ@ (}|A£»A–C @@& conn=op= time=7E\f¤ (³¸ÿ& conn=op= time=7E\fœ^(0@& conn=op= time=7E\fǰÿ(ë1An'A–C @@& conn=op= time=7E\f¿ùÿ(³¸ÿ& conn=op= time=7E\fSyò)YçA8“A–C @@& conn=op= time=7E\flìò)³¸ÿ& conn=op= time=7E\fØ}+*0@& conn=op= time=7E\f-=è*ÇœAÿA–C @@& conn=op= time=7E\f¾›è*³¸ÿ& conn=op= time=7E\fyÜ+5RAÎjA–C @@& conn=op= time=7E\fŽ÷Ü+³¸ÿ& conn=op= time=7E\fÝu,0@& conn=op= time=7E\f9ÙÖ,¢A˜ÖA–C @@& conn=op= time=7E\fI×,³¸ÿ& conn=op= time=7E\fäTÌ-½AcBA–C @@& conn=op= time=7E\f¼úÌ-³¸ÿ& conn=op= time=7E\f¤^Ó-0@& conn=op= time=7E\fáó³.~rA.®A–C @@& conn=op= time=7E\f¤^´.³¸ÿ& conn=op= time=7E\fg«/ì'AùA–C @@& conn=op= time=7E\fÉú«/0@& conn=op= time=7E\f%\±/³¸ÿ& conn=op= time=7E\faVž0ZÝAÃ…A–C @@& conn=op= time=7E\fÆŸž0³¸ÿ& conn=op= time=7E\fò�{10@& conn=op= time=7E\f¼ÕŽ10@& conn=op= time=7E\fëî“1ZÝAÃ…AßO @@& conn=op= time=7E\fÀŽ”1³¸ÿ& conn=op= time=7E\fâ>‹2ZÝAÃ…A)\@@& conn=op= time=7E\fÖÌ‹2³¸ÿ& conn=op= time=7E\f‚3ZÝAÃ…Ash@@& conn=op= time=7E\f¥"‚3³¸ÿ& conn=op= time=7E\f5Ðl4ZÝAÃ…A¼t@@& conn=op= time=7E\fu m4³¸ÿ& conn=op= time=7E\f†Øe5ZÝAÃ…A�@@& conn=op= time=7E\fBýe5³¸ÿ& conn=op= time=7E\fªq_6ZÝAÃ…AP�@@& conn=op= time=7E\f#B`6³¸ÿ& conn=op= time=7E\f?\K7ZÝAÃ…Aš™@@& conn=op= time=7E\f•¹K7³¸ÿ& conn=op= time=7E\f !D8ZÝAÃ…Aã¥@@& conn=op= time=7E\f•·D8³¸ÿ& conn=op= time=7E\fi£=9ZÝAÃ…A-²@@& conn=op= time=7E\fYÍ?9³¸ÿ& conn=op= time=7E\fÃÙ*:ZÝAÃ…Aw¾@@& conn=op= time=7E\fè*:³¸ÿ& conn=op= time=7E\fEÛ&;ZÝAÃ…AÁÊ!@@& conn=op= time=7E\fœ.';³¸ÿ& conn=op= time=8E\f_ÁxZÝAÃ…A ×#@@& conn=op= time=8E\fÏæx³¸ÿ& conn=op= time=8E\f�rZÝAÃ…ATã%@@& conn=op= time=8E\fQ—r³¸ÿ& conn=op= time=8E\f/Â]ZÝAÃ…Ažï'@@& conn=op= time=8E\fèI^³¸ÿ& conn=op= time=8E\fAd[ZÝAÃ…Açû)@@& conn=op= time=8E\f�ž[³¸ÿ& conn=op= time=8E\föÔEZÝAÃ…A1,@@& conn=op= time=8E\f¥kF³¸ÿ& conn=op= time=8E\fæ@ZÝAÃ…A{.@@& conn=op= time=8E\f8€A³¸ÿ& conn=op= time=8E\fÒ4J0@& conn=op= time=8E\fÜY,ÂeAf»A{.@@& conn=op= time=8E\f{,³¸ÿ& conn=op= time=8E\f}ˆ$)îA ñA{.@@& conn=op= time=8E\fCw%³¸ÿ& conn=op= time=8E\fТ‘vA¬&A{.@@& conn=op= time=8E\fFö³¸ÿ& conn=op= time=8E\fÌð ùþAO\A{.@@& conn=op= time=8E\fè< ³¸ÿ& conn=op= time=8E\f™ô `‡Aò‘A{.@@& conn=op= time=8E\feã ³¸ÿ& conn=op= time=8E\fÝ5ü ÈA•ÇA{.@@& conn=op= time=8E\fx{ü ³¸ÿ& conn=op= time=8E\fØÄå 0˜A8ýA{.@@& conn=op= time=8E\fuIæ ³¸ÿ& conn=op= time=8E\fv¬Þ — AÛ2A{.@@& conn=op= time=8E\f‚�ß ³¸ÿ& conn=op= time=8E\fV�× ÿ¨A~hA{.@@& conn=op= time=8E\f-Ø ³¸ÿ& conn=op= time=8E\f‰Âg1A!žA{.@@& conn=op= time=8E\f§§Â³¸ÿ& conn=op= time=8E\fŸJ»ι AÄÓA{.@@& conn=op= time=8E\fË,¼³¸ÿ& conn=op= time=8E\f�¯²6B Ag A{.@@& conn=op= time=8E\f·a³³¸ÿ& conn=op= time=8E\f"U«�Ê A ?A{.@@& conn=op= time=8E\f€˜¬³¸ÿ& conn=op= time=8E\f=œ”S A­tA{.@@& conn=op= time=8E\fÖ%•³¸ÿ& conn=op= time=8E\fï‘mÛ AOªA{.@@& conn=op= time=8E\fñ�‘³¸ÿ& conn=op= time=8E\f$Î}Ôc AòßA{.@@& conn=op= time=8E\fŽY~³¸ÿ& conn=op= time=8E\f�@w<ì A•A{.@@& conn=op= time=8E\fQ y³¸ÿ& conn=op= time=8E\fþ•p¤t A8KA{.@@& conn=op= time=8E\fÊ-q³¸ÿ& conn=op= time=8E\fÌóY ý AÛ€A{.@@& conn=op= time=8E\f_j[³¸ÿ& conn=op= time=8E\fNðTs… A~¶A{.@@& conn=op= time=8E\fÑvU³¸ÿ& conn=op= time=8E\f°KÛ A!ìA{.@@& conn=op= time=8E\f"CM³¸ÿ& conn=op= time=8E\f[á?B–AÄ!A{.@@& conn=op= time=8E\fm0@³¸ÿ& conn=op= time=8E\fýp5ªAgWA{.@@& conn=op= time=8E\f˜ä5³¸ÿ& conn=op= time=8E\fL3§A �A{.@@& conn=op= time=8E\f<§³¸ÿ& conn=op= time=8E\fAäy/A­ÂA{.@@& conn=op= time=8E\fTð³¸ÿ& conn=op= time=8E\fDá·APøA{.@@& conn=op= time=8E\fÁų¸ÿ& conn=op= time=8E\fÍŽI@Aó-A{.@@& conn=op= time=8E\fÓ³¸ÿ& conn=op= time=8E\f —ñ°ÈA–cA{.@@& conn=op= time=8E\fÃò³¸ÿ& conn=op= time=8E\f¯Òé QA9™A{.@@& conn=op= time=8E\fä‚ë ³¸ÿ& conn=op= time=8E\fâ!€ÙAÜÎA{.@@& conn=op= time=8E\fasâ!³¸ÿ& conn=op= time=8E\faË"çaAA{.@@& conn=op= time=8E\fµÎ"³¸ÿ& conn=op= time=8E\fðjç"0@& conn=op= time=8E\fÆÂ#çaAAÅ 0@@& conn=op= time=8E\fÂ#³¸ÿ& conn=op= time=8E\f ½µ$çaAA-2@@& conn=op= time=8E\f :¶$³¸ÿ& conn=op= time=8E\f–Æ®%çaAAX94@@& conn=op= time=8E\faD¯%³¸ÿ& conn=op= time=8E\f´S™&çaAA¢E6@@& conn=op= time=8E\f«É™&³¸ÿ& conn=op= time=8E\fT”'çaAAìQ8@@& conn=op= time=8E\fc‚”'³¸ÿ& conn=op= time=8E\fë=Š(çaAA5^:@@& conn=op= time=8E\f¡;‹(³¸ÿ& conn=op= time=8E\fιƒ)çaAAj<@@& conn=op= time=8E\f·3„)³¸ÿ& conn=op= time=8E\feío*çaAAÉv>@@& conn=op= time=8E\fÏHp*³¸ÿ& conn=op= time=8E\fœlj+çaAAƒ@@@& conn=op= time=8E\fí±j+³¸ÿ& conn=op= time=8E\f[¹U,çaAA\�B@@& conn=op= time=8E\f6·X,³¸ÿ& conn=op= time=8E\f3ZQ-çaAA¦›D@@& conn=op= time=8E\frQ-³¸ÿ& conn=op= time=8E\f=L<.çaAAð§F@@& conn=op= time=8E\f× =.³¸ÿ& conn=op= time=8E\f]g8/çaAA9´H@@& conn=op= time=8E\f+ý8/³¸ÿ& conn=op= time=8E\fu#0çaAA2_GÀ@& conn=op= time=8E\f½#0³¸ÿ& conn=op= time=8E\f;Ä1çaAAèREÀ@& conn=op= time=8E\f¯d 1³¸ÿ& conn=op= time=8E\f%õ 2çaAAŸFCÀ@& conn=op= time=8E\fYN 2³¸ÿ& conn=op= time=8E\fýÅ3çaAAU:AÀ@& conn=op= time=8E\f]3³¸ÿ& conn=op= time=8E\fòšó3çaAA .?À@& conn=op= time=8E\fªýó3³¸ÿ& conn=op= time=8E\f@4ï4çaAAÂ!=À@& conn=op= time=8E\f+Ëï4³¸ÿ& conn=op= time=8E\fYŠÜ5çaAAx;À@& conn=op= time=8E\fà¯Ü5³¸ÿ& conn=op= time=8E\fvrä6çaAA. 9À@& conn=op= time=8E\fr å6³¸ÿ& conn=op= time=8E\f£åè60@& conn=op= time=8E\f ÃÄ7ëâAäA. 9À@& conn=op= time=8E\fñ4Å7³¸ÿ& conn=op= time=8E\fЃ¸8ïcA‰ÃA. 9À@& conn=op= time=8E\f£î¸8³¸ÿ& conn=op= time=8E\f�5¯9óäA£A. 9À@& conn=op= time=8E\f\¯9³¸ÿ& conn=op= time=8E\fkð¦:÷eA”‚A. 9À@& conn=op= time=8E\fz§:³¸ÿ& conn=op= time=9E\f2çüæAbA. 9À@& conn=op= time=9E\fk³¸ÿ& conn=op= time=9E\fV�ðhAžAA. 9À@& conn=op= time=9E\f:/ñ³¸ÿ& conn=op= time=9E\fí_ëéA#!A. 9À@& conn=op= time=9E\f–#í³¸ÿ& conn=op= time=9E\f©ñájA©A. 9À@& conn=op= time=9E\föo⳸ÿ& conn=op= time=9E\f¥~ÌÖÿ@.àA. 9À@& conn=op= time=9E\fx ͳ¸ÿ& conn=op= time=9E\fGÉ Øþ@³¿A. 9À@& conn=op= time=9E\f€Ðɳ¸ÿ& conn=op= time=9E\f7Þ³(Úý@8ŸA. 9À@& conn=op= time=9E\f(Öµ³¸ÿ& conn=op= time=9E\f.)­0Üü@¾~A. 9À@& conn=op= time=9E\fWí³¸ÿ& conn=op= time=9E\fÇ7š8Þû@C^A. 9À@& conn=op= time=9E\f�y›³¸ÿ& conn=op= time=9E\f/•Aàú@È=A. 9À@& conn=op= time=9E\fY²•³¸ÿ& conn=op= time=9E\f:|� Iâù@NA. 9À@& conn=op= time=9E\fÐJ� ³¸ÿ& conn=op= time=9E\f=Êz Qäø@ÓüA. 9À@& conn=op= time=9E\fvd{ ³¸ÿ& conn=op= time=9E\f�t Yæ÷@XÜA. 9À@& conn=op= time=9E\fWcu ³¸ÿ& conn=op= time=9E\fŠÆl aèö@Ý»A. 9À@& conn=op= time=9E\fiUm ³¸ÿ& conn=op= time=9E\f­æV iêõ@c›A. 9À@& conn=op= time=9E\f~eX ³¸ÿ& conn=op= time=9E\f¿|Qqìô@èzA. 9À@& conn=op= time=9E\füREVÿ& conn=op= time=9E\fwÔIzîó@mZA. 9À@& conn=op= time=9E\fá_J³¸ÿ& conn=op= time=9E\fA‚3‚ðò@ò9A. 9À@& conn=op= time=9E\f-4³¸ÿ& conn=op= time=9E\fM-Šòñ@xA. 9À@& conn=op= time=9E\fþµ-³¸ÿ& conn=op= time=9E\fðK$’ôð@ýøA. 9À@& conn=op= time=9E\frÑ$³¸ÿ& conn=op= time=9E\f¾Ðšöï@‚ØA. 9À@& conn=op= time=9E\f~`³¸ÿ& conn=op= time=9E\f½ï¢øî@¸A. 9À@& conn=op= time=9E\f†³¸ÿ& conn=op= time=9E\f·|ÿ«úí@�—A. 9À@& conn=op= time=9E\fsh³¸ÿ& conn=op= time=9E\fD]ê³üì@wA. 9À@& conn=op= time=9E\f0£ê³¸ÿ& conn=op= time=9E\fiä»þë@—VA. 9À@& conn=op= time=9E\f´2泸ÿ& conn=op= time=9E\fó}ÝÃë@6A. 9À@& conn=op= time=9E\f  Þ³¸ÿ& conn=op= time=9E\fèÆËê@¢A. 9À@& conn=op= time=9E\fHP˳¸ÿ& conn=op= time=9E\fœ'0@& conn=op= time=9E\f½¿¾Óé@'õA. 9À@& conn=op= time=9E\f42¿³¸ÿ& conn=op= time=9E\fç°Ûè@¬ÔA. 9À@& conn=op= time=9E\fXd°³¸ÿ& conn=op= time=9E\féöÞ0@& conn=op= time=9E\fóÅ©äç@1´A. 9À@& conn=op= time=9E\fUª³¸ÿ& conn=op= time=9E\ft°žì æ@·“A. 9À@& conn=op= time=9E\f'@ŸEVÿ& conn=op= time=9E\f)€µ0@& conn=op= time=9E\f›Ã•ô å@ &=Ü@ëNA. 9À@& conn=op= time=9E\fsc &³¸ÿ& conn=op= time=9E\f 'F!Û@q.A. 9À@& conn=op= time=9E\f'³¸ÿ& conn=op= time=9E\fîào'0@& conn=op= time=9E\f¦ô (N#Ú@ö A. 9À@& conn=op= time=9E\fß* (³¸ÿ& conn=op= time=9E\fRNø(V%Ù@{íA. 9À@& conn=op= time=9E\f}‘ø(EVÿ& conn=op= time=9E\fæ5M)0@& conn=op= time=9E\fšMù)^'Ø@ÍA. 9À@& conn=op= time=9E\f_(ú)³¸ÿ& conn=op= time=9E\frkï*f)×@†¬A. 9À@& conn=op= time=9E\f…ð*³¸ÿ& conn=op= time=9E\fPU&+0@& conn=op= time=9E\fëë×+n+Ö@ ŒA. 9À@& conn=op= time=9E\f˜5Ø+³¸ÿ& conn=op= time=9E\fb~É,v-Õ@�kA. 9À@& conn=op= time=9E\fÔâÉ,³¸ÿ& conn=op= time=9E\fDçå,0@& conn=op= time=9E\fÀ-/Ô@KA. 9À@& conn=op= time=9E\fãzÀ-³¸ÿ& conn=op= time=9E\fß¹.‡1Ó@›*A. 9À@& conn=op= time=9E\f�„¹.³¸ÿ& conn=op= time=9E\f¦^Ë.0@& conn=op= time=9E\f0²/�3Ò@ A. 9À@& conn=op= time=9E\f1¨²/³¸ÿ& conn=op= time=9E\fÜŧ0—5Ñ@¥éA. 9À@& conn=op= time=9E\fÚû§0³¸ÿ& conn=op= time=9E\fñ�1Ÿ7Ð@*ÉA. 9À@& conn=op= time=9E\f3˜�1³¸ÿ& conn=op= time=9E\f<ø‡2§9Ï@°¨A. 9À@& conn=op= time=9E\fß‹ˆ2³¸ÿ& conn=op= time=9E\f²·�3°;Î@5ˆA. 9À@& conn=op= time=9E\fCvƒ3³¸ÿ& conn=op= time=9E\f˜@þ30@& conn=op= time=9E\fÁœx4°;Î@5ˆAäü6À@& conn=op= time=9E\fÞ©x4³¸ÿ& conn=op= time=9E\f­úm5°;Î@5ˆA›ð4À@& conn=op= time=9E\fi0n5³¸ÿ& conn=op= time=9E\f0šT6°;Î@5ˆAQä2À@& conn=op= time=9E\fîÿT6³¸ÿ& conn=op= time=9E\fá%M7°;Î@5ˆAØ0À@& conn=op= time=9E\f•M7³¸ÿ& conn=op= time=9E\f¸ F8°;Î@5ˆA½Ë.À@& conn=op= time=9E\f@G8³¸ÿ& conn=op= time=9E\fñ29°;Î@5ˆAt¿,À@& conn=op= time=9E\f®39³¸ÿ& conn=op= time=9E\fëi.:°;Î@5ˆA*³*À@& conn=op= time=9E\f|/:³¸ÿ& conn=op= time=9E\fÁ ;°;Î@5ˆAà¦(À@& conn=op= time=9E\fß¼;³¸ÿ& conn=op= time=:E\fƒÄ~°;Î@5ˆA—š&À@& conn=op= time=:E\f”î~³¸ÿ& conn=op= time=:E\fnQi°;Î@5ˆAMŽ$À@& conn=op= time=:E\fàˆi³¸ÿ& conn=op= time=:E\fœbd°;Î@5ˆA‚"À@& conn=op= time=:E\fáÞd³¸ÿ& conn=op= time=:E\f»’[°;Î@5ˆA¹u À@& conn=op= time=:E\f%í[³¸ÿ& conn=op= time=:E\fèƒQ°;Î@5ˆApiÀ@& conn=op= time=:E\fŽMR³¸ÿ& conn=op= time=:E\fFÏ:°;Î@5ˆA&]À@& conn=op= time=:E\fД<³¸ÿ& conn=op= time=:E\f)çO0@& conn=op= time=:E\f}_3ërÍ@í3A&]À@& conn=op= time=:E\fÒò3EVÿ& conn=op= time=:E\fWò('ªÌ@¦ßA&]À@& conn=op= time=:E\ft)³¸ÿ& conn=op= time=:E\fy) báË@^‹A&]À@& conn=op= time=:E\f3ž ³¸ÿ& conn=op= time=:E\f\Ÿ žË@7A&]À@& conn=op= time=:E\f>ó ³¸ÿ& conn=op= time=:E\fÆNü ÙOÊ@ÐâA&]À@& conn=op= time=:E\fæÖü ³¸ÿ& conn=op= time=:E\föæó ‡É@ˆŽA&]À@& conn=op= time=:E\fõ²ô EVÿ& conn=op= time=:E\fË·ð P¾È@A:A&]À@& conn=op= time=:E\fKñ EVÿ& conn=op= time=:E\fARÙ ŒõÇ@ùåA&]À@& conn=op= time=:E\f:õÙ EVÿ& conn=op= time=:E\fÅÑ Ç,Ç@²‘A&]À@& conn=op= time=:E\f¹MÒ ³¸ÿ& conn=op= time=:E\f+ñÈdÆ@j=A&]À@& conn=op= time=:E\fSúɳ¸ÿ& conn=op= time=:E\fLʵ>›Å@#éA&]À@& conn=op= time=:E\fªø¶³¸ÿ& conn=op= time=:E\fs¿²zÒÄ@Û”A&]À@& conn=op= time=:E\f\^³³¸ÿ& conn=op= time=:E\fF¬µ Ä@”@A&]À@& conn=op= time=:E\fgά³¸ÿ& conn=op= time=:E\fÓ=•ñ@Ã@LìA&]À@& conn=op= time=:E\faø•³¸ÿ& conn=op= time=:E\f²J�,xÂ@˜A&]À@& conn=op= time=:E\fÖ‘EVÿ& conn=op= time=:E\fQË{h¯Á@¾CA&]À@& conn=op= time=:E\fWF|³¸ÿ& conn=op= time=:E\f:{v£æÀ@vïA&]À@& conn=op= time=:E\f\¯v³¸ÿ& conn=op= time=:E\fž¹nßÀ@/›A&]À@& conn=op= time=:E\fXJo³¸ÿ& conn=op= time=:E\fÙYU¿@çFA&]À@& conn=op= time=:E\fú£Y³¸ÿ& conn=op= time=:E\fÅSSVŒ¾@ òA&]À@& conn=op= time=:E\fªS³¸ÿ& conn=op= time=:E\fänL‘ý@XžA&]À@& conn=op= time=:E\f<êM³¸ÿ& conn=op= time=:E\fãÂ7Íú¼@JA&]À@& conn=op= time=:E\f¨\8³¸ÿ& conn=op= time=:E\fíQ2 2¼@ÉõA&]À@& conn=op= time=:E\f9Ò2³¸ÿ& conn=op= time=:E\f ‘Di»@‚¡A&]À@& conn=op= time=:E\f`b³¸ÿ& conn=op= time=:E\fS8€ º@:MA&]À@& conn=op= time=:E\fïbEVÿ& conn=op= time=:E\fÆž»×¹@óø A&]À@& conn=op= time=:E\fÏ EVÿ& conn=op= time=:E\f6Iù÷¹@¬¤ A&]À@& conn=op= time=:E\f‡ùEVÿ& conn=op= time=:E\fžLò2F¸@dP A&]À@& conn=op= time=:E\f.óEVÿ& conn=op= time=:E\fœÉê n}·@ü A&]À@& conn=op= time=:E\fàaë ³¸ÿ& conn=op= time=:E\fÿäÔ!©´¶@Õ§ A&]À@& conn=op= time=:E\ftÕ!³¸ÿ& conn=op= time=:E\f›ÁÐ"åëµ@ŽS A&]À@& conn=op= time=:E\f´Ò"³¸ÿ& conn=op= time=:E\fr-�@& conn=op= time=:E\fÀ_Æ# #µ@Fÿ A&]À@& conn=op= time=:E\fµ¸Æ#³¸ÿ& conn=op= time=:E\fëw»$\Z´@ÿª A&]À@& conn=op= time=:E\fAr¿$³¸ÿ& conn=op= time=:E\fÔ]â$0@& conn=op= time=:E\fýå¥%—‘³@·V A&]À@& conn=op= time=:E\f„f¦%³¸ÿ& conn=op= time=:E\furœ&EVÿ& conn=op= time=:E\fuÍœ&ÓȲ@p A&]À@& conn=op= time=:E\f¼&0@& conn=op= time=:E\fÿ³’'²@(® A&]À@& conn=op= time=:E\fêm“'EVÿ& conn=op= time=:E\f†(J7±@áY A&]À@& conn=op= time=:E\fQ�†(EVÿ& conn=op= time=:E\f©…Š(0@& conn=op= time=:E\f‡Á)…n°@™ A&]À@& conn=op= time=:E\fG€)EVÿ& conn=op= time=:E\f±f*0@& conn=op= time=:E\fh}v*Á¥¯@R± A&]À@& conn=op= time=:E\fÞv*EVÿ& conn=op= time=:E\fŸk+üÜ®@ ] A&]À@& conn=op= time=:E\fÈ©l+EVÿ& conn=op= time=:E\fÛù7,0@& conn=op= time=:E\fä™S,8®@à A&]À@& conn=op= time=:E\fT,³¸ÿ& conn=op= time=:E\fÀ©J-sK­@|´A&]À@& conn=op= time=:E\fz"K-³¸ÿ& conn=op= time=:E\fe.0@& conn=op= time=:E\fäŽB.¯‚¬@4`A&]À@& conn=op= time=:E\f C.³¸ÿ& conn=op= time=:E\fž69/깫@í A&]À@& conn=op= time=:E\f·L9/EVÿ& conn=op= time=:E\fæBë/0@& conn=op= time=:E\f-S,0&ñª@¥·A&]À@& conn=op= time=:E\f�–,0³¸ÿ& conn=op= time=:E\fëÁ1b(ª@^cA&]À@& conn=op= time=:E\fÌ1³¸ÿ& conn=op= time=:E\fèw¶10@& conn=op= time=:E\fj~2�_©@A&]À@& conn=op= time=:E\fŠî2³¸ÿ& conn=op= time=:E\fN3Ù–¨@ϺA&]À@& conn=op= time=:E\fS˜3³¸ÿ& conn=op= time=:E\f/TŒ30@& conn=op= time=:E\fÎ.ÿ3Χ@‡fA&]À@& conn=op= time=:E\f†·ÿ3³¸ÿ& conn=op= time=:E\fêõ4P§@@A&]À@& conn=op= time=:E\fp{ö4³¸ÿ& conn=op= time=:E\f{m50@& conn=op= time=:E\f˜ÜÝ5‹<¦@ù½A&]À@& conn=op= time=:E\fÖTÞ5³¸ÿ& conn=op= time=:E\f¡bÓ6Çs¥@±iA&]À@& conn=op= time=:E\fôÏÓ6³¸ÿ& conn=op= time=:E\fq.870@& conn=op= time=:E\fL5Ê7«¤@jA&]À@& conn=op= time=:E\fXöÊ7³¸ÿ& conn=op= time=:E\fêÝ¿8>â£@"ÁA&]À@& conn=op= time=:E\fuQÁ8EVÿ& conn=op= time=:E\fÚ90@& conn=op= time=:E\f¹Ìµ9y£@ÛlA&]À@& conn=op= time=:E\fl*¶9EVÿ& conn=op= time=:E\f¹(ª:µP¢@“A&]À@& conn=op= time=:E\fz°ª:³¸ÿ& conn=op= time=:E\fA�Ý:0@& conn=op= time=:E\f߯’;ð‡¡@LÄA&]À@& conn=op= time=:E\fW“;³¸ÿ& conn=op= time=;E\flþí,¿ @pA&]À@& conn=op= time=;E\f´“ÿ& conn=op= time=;E\f×F0@& conn=op= time=;E\fØàägöŸ@½A&]À@& conn=op= time=;E\fa{峸ÿ& conn=op= time=;E\f£¨Ì0@& conn=op= time=;E\fòÒÜ£-Ÿ@uÇA&]À@& conn=op= time=;E\f»Nݳ¸ÿ& conn=op= time=;E\f!~ÒÞdž@.sA&]À@& conn=op= time=;E\fÀÓ³¸ÿ& conn=op= time=;E\f6œ0@& conn=op= time=;E\fû¡Ëœ�@æA&]À@& conn=op= time=;E\f g̳¸ÿ& conn=op= time=;E\f©¹³UÓœ@ŸÊA&]À@& conn=op= time=;E\fŸ=´³¸ÿ& conn=op= time=;E\f5€0@& conn=op= time=;E\f;úª‘ œ@XvA&]À@& conn=op= time=;E\fŒ¯«EVÿ& conn=op= time=;E\f*Þ£ÌA›@"A&]À@& conn=op= time=;E\fQ¤EVÿ& conn=op= time=;E\fI0@& conn=op= time=;E\fK™ÌA›@"AÜPÀ@& conn=op= time=;E\fêË™³¸ÿ& conn=op= time=;E\fa‹‚ ÌA›@"A’DÀ@& conn=op= time=;E\fò‚ ³¸ÿ& conn=op= time=;E\f’Ñ{ ÌA›@"AI8À@& conn=op= time=;E\füò{ ³¸ÿ& conn=op= time=;E\fÝ;t ÌA›@"Aÿ+À@& conn=op= time=;E\f¯›t ³¸ÿ& conn=op= time=;E\fÓÆj ÌA›@"AµÀ@& conn=op= time=;E\f{ðj ³¸ÿ& conn=op= time=;E\f©%S ÌA›@"AlÀ@& conn=op= time=;E\f(GS ³¸ÿ& conn=op= time=;E\f‹=LÌA›@"A"À@& conn=op= time=;E\f¯L³¸ÿ& conn=op= time=;E\fÖGÌA›@"AØú À@& conn=op= time=;E\f‰fH³¸ÿ& conn=op= time=;E\fÙÿ3ÌA›@"AŽî À@& conn=op= time=;E\f’&4³¸ÿ& conn=op= time=;E\f-Z.ÌA›@"AEâÀ@& conn=op= time=;E\f—.³¸ÿ& conn=op= time=;E\f¦]ÌA›@"AûÕÀ@& conn=op= time=;E\fÇz³¸ÿ& conn=op= time=;E\f Ä›0@& conn=op= time=;E\fêLu¿š@W°AûÕÀ@& conn=op= time=;E\f’˳¸ÿ& conn=op= time=;E\fÂ] =š@Ÿ>AûÕÀ@& conn=op= time=;E\f&Ô ³¸ÿ& conn=op= time=;E\f\†ôź™@Ì™ÿ@ûÕÀ@& conn=op= time=;E\f£�õEVÿ& conn=op= time=;E\fïïn8™@[¶þ@ûÕÀ@& conn=op= time=;E\f¼ïEVÿ& conn=op= time=;E\fäÃ鶘@éÒý@ûÕÀ@& conn=op= time=;E\fS9곸ÿ& conn=op= time=;E\f²øÒ¾3˜@xïü@ûÕÀ@& conn=op= time=;E\f[Ô³¸ÿ& conn=op= time=;E\f)Ìf±—@ ü@ûÕÀ@& conn=op= time=;E\fªÌEVÿ& conn=op= time=;E\fuüÂ/—@•(û@ûÕÀ@& conn=op= time=;E\fÙÄEVÿ& conn=op= time=;E\f¼’¬·¬–@$Eú@ûÕÀ@& conn=op= time=;E\f�á¬EVÿ& conn=op= time=;E\f\V¤_*–@²aù@ûÕÀ@& conn=op= time=;E\f楳¸ÿ& conn=op= time=;E\fè® ¨•@A~ø@ûÕÀ@& conn=op= time=;E\fê EVÿ& conn=op= time=;E\f¨—а%•@К÷@ûÕÀ@& conn=op= time=;E\fÄäŠEVÿ& conn=op= time=;E\fùLƒX£”@^·ö@ûÕÀ@& conn=op= time=;E\fß„EVÿ& conn=op= time=;E\f“Ì|!”@íÓõ@ûÕÀ@& conn=op= time=;E\fág}EVÿ& conn=op= time=;E\f'Ãt ©ž“@{ðô@ûÕÀ@& conn=op= time=;E\f3Ru EVÿ& conn=op= time=;E\f°^!Q“@ ô@ûÕÀ@& conn=op= time=;E\fª’^!EVÿ& conn=op= time=;E\fØWW"ù™’@™)ó@ûÕÀ@& conn=op= time=;E\f!LX"EVÿ& conn=op= time=;E\f† C#¢’@'Fò@ûÕÀ@& conn=op= time=;E\f"ÕD#EVÿ& conn=op= time=;E\fw�@$J•‘@¶bñ@ûÕÀ@& conn=op= time=;E\fãB$EVÿ& conn=op= time=;E\f3[9%ò‘@Eð@ûÕÀ@& conn=op= time=;E\fÙæ9%EVÿ& conn=op= time=;E\f‡ë!&š��@Ó›ï@ûÕÀ@& conn=op= time=;E\fM"&EVÿ& conn=op= time=;E\fA˜'C�@b¸î@ûÕÀ@& conn=op= time=;E\fw%'³¸ÿ& conn=op= time=;E\f> (ë‹�@ðÔí@ûÕÀ@& conn=op= time=;E\f•(EVÿ& conn=op= time=;E\f!ý(“ �@ñì@ûÕÀ@& conn=op= time=;E\fÙtý(EVÿ& conn=op= time=;E\fóðö)<‡Ž@ì@ûÕÀ@& conn=op= time=;E\fÜ„÷)EVÿ& conn=op= time=;E\fè#ð*äŽ@œ*ë@ûÕÀ@& conn=op= time=;E\fàíð*³¸ÿ& conn=op= time=;E\fœ¾Ù+Œ‚�@+Gê@ûÕÀ@& conn=op= time=;E\fÔ^Ú+EVÿ& conn=op= time=;E\f Õ,4�@¹cé@ûÕÀ@& conn=op= time=;E\f¼�Õ,EVÿ& conn=op= time=;E\f—‹Î-Ý}Œ@H€è@ûÕÀ@& conn=op= time=;E\föÏ-³¸ÿ& conn=op= time=;E\f¯Â».…û‹@לç@ûÕÀ@& conn=op= time=;E\fà½.³¸ÿ& conn=op= time=;E\fÆñ´/-y‹@e¹æ@ûÕÀ@& conn=op= time=;E\fùwµ/EVÿ& conn=op= time=;E\f@Tb00@& conn=op= time=;E\f·ož0ÖöŠ@ôÕå@ûÕÀ@& conn=op= time=;E\fŽŸ0EVÿ& conn=op= time=;E\fJΕ1~tŠ@ƒòä@ûÕÀ@& conn=op= time=;E\f¤í•1³¸ÿ& conn=op= time=;E\fÚK20@& conn=op= time=;E\föÌ�2&ò‰@ä@ûÕÀ@& conn=op= time=;E\fv4wíˆ@.Hâ@ûÕÀ@& conn=op= time=;E\fÂÅv4EVÿ& conn=op= time=;E\fçE`5kˆ@½dá@ûÕÀ@& conn=op= time=;E\fr¶`5EVÿ& conn=op= time=;E\f…rä50@& conn=op= time=;E\frNV6Çè‡@L�à@ûÕÀ@& conn=op= time=;E\f³ÏV6³¸ÿ& conn=op= time=;E\f<àÚ60@& conn=op= time=;E\fnAM7Çè‡@L�à@±ÉÀ@& conn=op= time=;E\f¿ N7³¸ÿ& conn=op= time=;E\fêžD8Çè‡@L�à@g½À@& conn=op= time=;E\fà+E8³¸ÿ& conn=op= time=;E\fB?9Çè‡@L�à@;bÿ¿@& conn=op= time=;E\f:|?9³¸ÿ& conn=op= time=;E\f/Å-:Çè‡@L�à@¨Iû¿@& conn=op= time=;E\fp+.:³¸ÿ& conn=op= time=;E\f^';Çè‡@L�à@1÷¿@& conn=op= time=;E\fiÊ';³¸ÿ& conn=op= time=_³¸ÿ& conn=op= time=�&`c„@¢å¾@ylÖ¿@& conn=op= time=!09Rƒ@w¶´@ylÖ¿@& conn=op= time= Iù€@±Nž@ylÖ¿@& conn=op= time==E\f�Z EVÿ& conn=op= time==E\fÒ3| ùÝ€@ùI�@ylÖ¿@& conn=op= time==E\fÃ3| EVÿ& conn=op= time==E\f%Pû 0@& conn=op= time==E\fzCi ¨Â€@BEœ@ylÖ¿@& conn=op= time==E\f Oi EVÿ& conn=op= time==E\fëõf W§€@Š@›@ylÖ¿@& conn=op= time==E\f›:g EVÿ& conn=op= time==E\f|ïÉ 0@& conn=op= time==E\f±V Œ€@Ó;š@ylÖ¿@& conn=op= time==E\f2ùV EVÿ& conn=op= time==E\f.lJ¶p€@7™@ylÖ¿@& conn=op= time==E\fN…JEVÿ& conn=op= time==E\f–³0@& conn=op= time==E\f7â=eU€@c2˜@ylÖ¿@& conn=op= time==E\f…p>EVÿ& conn=op= time==E\f�“3:€@¬-—@ylÖ¿@& conn=op= time==E\fá 4EVÿ& conn=op= time==E\f¥„0@& conn=op= time==E\fm4(Ä€@ô(–@ylÖ¿@& conn=op= time==E\ft(EVÿ& conn=op= time==E\f½s€@=$•@ylÖ¿@& conn=op= time==E\fßEVÿ& conn=op= time==E\fþUJ0@& conn=op= time==E\fYDÐ@…”@ylÖ¿@& conn=op= time==E\f‡EVÿ& conn=op= time==E\f@£™@Γ@ylÖ¿@& conn=op= time==E\fg�EVÿ& conn=op= time==E\fVƒ0@& conn=op= time==E\fUzÿc@’@ylÖ¿@& conn=op= time==E\féêÿEVÿ& conn=op= time==E\fh%é`,@_‘@ylÖ¿@& conn=op= time==E\f·aéEVÿ& conn=op= time==E\fÉZò0@& conn=op= time==E\f«µà¿õ~@§ �@ylÖ¿@& conn=op= time==E\f_"᳸ÿ& conn=op= time==E\f‰ÿ²0@& conn=op= time==E\fV3Ö¿~@ð�@ylÖ¿@& conn=op= time==E\fV×EVÿ& conn=op= time==E\fX!Ï|ˆ~@8Ž@ylÖ¿@& conn=op= time==E\f¹’ÏEVÿ& conn=op= time==E\fŠ—O0À& conn=op= time==E\f¶¯Ç|ˆ~@8Ž@ …Ú¿À& conn=op= time==E\fáÃȳ¸ÿ& conn=op= time==E\fZñ´|ˆ~@8Ž@ �Þ¿À& conn=op= time==E\fÄ|µ³¸ÿ& conn=op= time==E\f¬£|ˆ~@8Ž@3¶â¿À& conn=op= time==E\f+¤³¸ÿ& conn=op= time==E\fJ–¡|ˆ~@8Ž@ÇÎæ¿À& conn=op= time==E\fr¼¡³¸ÿ& conn=op= time==E\fõ ޳¸ÿ& conn=op= time==E\fŽ|ˆ~@8Ž@Zçê¿À& conn=op= time==E\f³‡‰|ˆ~@8Ž@îÿî¿À& conn=op= time==E\fY²‰³¸ÿ& conn=op= time==E\fyvw|ˆ~@8Ž@�ó¿À& conn=op= time==E\f‚¨w³¸ÿ& conn=op= time==E\f÷E\f:ûv|ˆ~@8Ž@äü6ÀÀ& conn=op= time=>E\f Aw³¸ÿ& conn=op= time=>E\f%Åï0À& conn=op= time=>E\fÒ­ú0@& conn=op= time=>E\fÎùk÷�|@+º�@äü6À@& conn=op= time=>E\f‰hl³¸ÿ& conn=op= time=>E\f'¤_r™z@q�@äü6À@& conn=op= time=>E\f�`³¸ÿ& conn=op= time=>E\fÚ1Wí¡x@(�@äü6À@& conn=op= time=>E\fs²W³¸ÿ& conn=op= time=>E\f7rPhªv@ߌ@äü6À@& conn=op= time=>E\fêQEVÿ& conn=op= time=>E\f,:ã²t@ö•Œ@äü6À@& conn=op= time=>E\f5};³¸ÿ& conn=op= time=>E\fè©4^»r@éLŒ@äü6À@& conn=op= time=>E\fh>5³¸ÿ& conn=op= time=>E\fc-ÙÃp@ÜŒ@äü6À@& conn=op= time=>E\fÄæ-³¸ÿ& conn=op= time=>E\f®uTÌn@Ϻ‹@äü6À@& conn=op= time=>E\fY ³¸ÿ& conn=op= time=>E\f-� ÏÔl@Âq‹@äü6À@& conn=op= time=>E\fõX ³¸ÿ& conn=op= time=>E\fõÖ JÝj@µ(‹@äü6À@& conn=op= time=>E\fsl ³¸ÿ& conn=op= time=>E\fßcó Ååh@¨ßŠ@äü6À@& conn=op= time=>E\f^0õ ³¸ÿ& conn=op= time=>E\f’7í @îf@š–Š@äü6À@& conn=op= time=>E\fLÎí ³¸ÿ& conn=op= time=>E\fbsÛ »öd@�MŠ@äü6À@& conn=op= time=>E\fýÏÞ ³¸ÿ& conn=op= time=>E\fžÖ 6ÿb@€Š@äü6À@& conn=op= time=>E\fóÚ× ³¸ÿ& conn=op= time=>E\fš‰Ï±a@s»‰@äü6À@& conn=op= time=>E\fÒ³¸ÿ& conn=op= time=>E\fØC½,_@fr‰@äü6À@& conn=op= time=>E\f å½³¸ÿ& conn=op= time=>E\f÷€·§]@Y)‰@äü6À@& conn=op= time=>E\f7ó·EVÿ& conn=op= time=>E\fy›£"![@Làˆ@äü6À@& conn=op= time=>E\fòP¤³¸ÿ& conn=op= time=>E\f<�œ�)Y@?—ˆ@äü6À@& conn=op= time=>E\fh�³¸ÿ& conn=op= time=>E\f”é…2W@1Nˆ@äü6À@& conn=op= time=>E\fà~†³¸ÿ& conn=op= time=>E\f“¢‚“:U@$ˆ@äü6À@& conn=op= time=>E\fÂü‚³¸ÿ& conn=op= time=>E\f°»{CS@¼‡@äü6À@& conn=op= time=>E\fL|³¸ÿ& conn=op= time=>E\fíte‰KQ@ s‡@äü6À@& conn=op= time=>E\fÙïe³¸ÿ& conn=op= time=>E\fý²]TO@ý)‡@äü6À@& conn=op= time=>E\fÏ8^³¸ÿ& conn=op= time=>E\fàKU~\M@ðà†@äü6À@& conn=op= time=>E\f1XV³¸ÿ& conn=op= time=>E\fñŠ?ùdK@ã—†@äü6À@& conn=op= time=>E\f¬%@³¸ÿ& conn=op= time=>E\f¨¸:tmI@ÖN†@äü6À@& conn=op= time=>E\fÞÆ;³¸ÿ& conn=op= time=>E\f³4ïuG@Ɇ@äü6À@& conn=op= time=>E\fk­4³¸ÿ& conn=op= time=>E\f°ç j~E@»¼…@äü6À@& conn=op= time=>E\f’¼#³¸ÿ& conn=op= time=>E\fENå†C@®s…@äü6À@& conn=op= time=>E\fZس¸ÿ& conn=op= time=>E\fvþ`�A@¡*…@äü6À@& conn=op= time=>E\fQ³¸ÿ& conn=op= time=>E\f”!š0À& conn=op= time=>E\fßÐû`�A@¡*…@. 9ÀÀ& conn=op= time=>E\fZÿû³¸ÿ& conn=op= time=>E\f�"ð`�A@¡*…@x;ÀÀ& conn=op= time=>E\f˜\ð³¸ÿ& conn=op= time=>E\fÿÁç `�A@¡*…@Â!=ÀÀ& conn=op= time=>E\f¥-è ³¸ÿ& conn=op= time=>E\f”â!`�A@¡*…@ .?ÀÀ& conn=op= time=>E\fEfâ!³¸ÿ& conn=op= time=>E\fà(Í"`�A@¡*…@U:AÀÀ& conn=op= time=>E\f uÍ"³¸ÿ& conn=op= time=>E\f ©É#`�A@¡*…@ŸFCÀÀ& conn=op= time=>E\f–Ê#³¸ÿ& conn=op= time=>E\fÃ7µ$`�A@¡*…@èREÀÀ& conn=op= time=>E\fZbµ$³¸ÿ& conn=op= time=>E\f%\¯%`�A@¡*…@2_GÀÀ& conn=op= time=>E\f\ƒ¯%³¸ÿ& conn=op= time=>E\f¿=¦&`�A@¡*…@9´H@À& conn=op= time=>E\f6›¦&³¸ÿ& conn=op= time=>E\fÄ‹'`�A@¡*…@ð§F@À& conn=op= time=>E\f¶!‹'³¸ÿ& conn=op= time=>E\fV‡(`�A@¡*…@¦›D@À& conn=op= time=>E\fûŒ‡(³¸ÿ& conn=op= time=>E\fA¨u)`�A@¡*…@\�B@À& conn=op= time=>E\fK¿u)³¸ÿ& conn=op= time=>E\f‚at*`�A@¡*…@ƒ@@À& conn=op= time=>E\f>ñt*³¸ÿ& conn=op= time=>E\f›Ûf+`�A@¡*…@Év>@À& conn=op= time=>E\fág+³¸ÿ& conn=op= time=>E\fè],`�A@¡*…@j<@À& conn=op= time=>E\fµ‚^,³¸ÿ& conn=op= time=>E\fùGF-`�A@¡*…@5^:@À& conn=op= time=>E\f³¢F-³¸ÿ& conn=op= time=>E\f4½@.`�A@¡*…@ìQ8@À& conn=op= time=>E\fçß@.³¸ÿ& conn=op= time=>E\f·E\f)pE\fbH)0`�A@¡*…@X94@À& conn=op= time=>E\f r)0³¸ÿ& conn=op= time=>E\fÜ$1`�A@¡*…@-2@À& conn=op= time=>E\flN$1³¸ÿ& conn=op= time=>E\f²I2`�A@¡*…@Å 0@À& conn=op= time=>E\fÓ{2³¸ÿ& conn=op= time=>E\fì 3`�A@¡*…@{.@À& conn=op= time=>E\f4… 3³¸ÿ& conn=op= time=>E\fà£ö3`�A@¡*…@1,@À& conn=op= time=>E\f· ÷3³¸ÿ& conn=op= time=>E\f™Zò4`�A@¡*…@çû)@À& conn=op= time=>E\f«’ò4³¸ÿ& conn=op= time=>E\f�UÜ5`�A@¡*…@žï'@À& conn=op= time=>E\f©ÓÜ5³¸ÿ& conn=op= time=>E\f^¨Ó6`�A@¡*…@Tã%@À& conn=op= time=>E\flèÓ6³¸ÿ& conn=op= time=>E\f$±Ì7`�A@¡*…@ ×#@À& conn=op= time=>E\f1Í7³¸ÿ& conn=op= time=>E\f)ùÅ8`�A@¡*…@ÁÊ!@À& conn=op= time=>E\féÆ8³¸ÿ& conn=op= time=>E\f]bµ9`�A@¡*…@w¾@À& conn=op= time=>E\f}µ9³¸ÿ& conn=op= time=>E\fC'¤:`�A@¡*…@-²@À& conn=op= time=>E\fK*¤:³¸ÿ& conn=op= time=>E\fÆ›—;`�A@¡*…@ã¥@À& conn=op= time=>E\f8 —;³¸ÿ& conn=op= time=?E\fÎ5ï`�A@¡*…@š™@À& conn=op= time=?E\f®¼ï³¸ÿ& conn=op= time=?E\f3£ê`�A@¡*…@P�@À& conn=op= time=?E\fŠ=본ÿ& conn=op= time=?E\f›BÕ`�A@¡*…@�@À& conn=op= time=?E\f†wÕ³¸ÿ& conn=op= time=?E\f³µÊ`�A@¡*…@¼t@À& conn=op= time=?E\fsb˳¸ÿ& conn=op= time=?E\fØßÅ`�A@¡*…@sh@À& conn=op= time=?E\f“Ƴ¸ÿ& conn=op= time=?E\f©ñ¾`�A@¡*…@)\@À& conn=op= time=?E\f'¿³¸ÿ& conn=op= time=?E\f¢&«`�A@¡*…@ßO @À& conn=op= time=?E\f칫³¸ÿ& conn=op= time=?E\fä¨`�A@¡*…@–C @À& conn=op= time=?E\fL\¨³¸ÿ& conn=op= time=?E\f¼V–`�A@¡*…@L7 @À& conn=op= time=?E\f¿¾–³¸ÿ& conn=op= time=?E\fs ‘ `�A@¡*…@+@À& conn=op= time=?E\fk$‘ ³¸ÿ& conn=op= time=?E\f»i| `�A@¡*…@¸@À& conn=op= time=?E\fà$} ³¸ÿ& conn=op= time=?E\fáw `�A@¡*…@o@À& conn=op= time=?E\fà#w ³¸ÿ& conn=op= time=?E\f„Ša `�A@¡*…@%@À& conn=op= time=?E\fùa ³¸ÿ& conn=op= time=?E\f³¸\ `�A@¡*…@¶óý?À& conn=op= time=?E\f•t] ³¸ÿ& conn=op= time=?E\fé*J`�A@¡*…@#Ûù?À& conn=op= time=?E\f}¿J³¸ÿ& conn=op= time=?E\f²�F`�A@¡*…@�Âõ?À& conn=op= time=?E\fÀ¯F³¸ÿ& conn=op= time=?E\f^2`�A@¡*…@ü©ñ?À& conn=op= time=?E\f÷õ2³¸ÿ& conn=op= time=?E\f]-&`�A@¡*…@h‘í?À& conn=op= time=?E\fvT&³¸ÿ& conn=op= time=?E\fOâ`�A@¡*…@Õxé?À& conn=op= time=?E\f¥£³¸ÿ& conn=op= time=?E\fu`�A@¡*…@B`å?À& conn=op= time=?E\fæ�³¸ÿ& conn=op= time=?E\f Y `�A@¡*…@®Gá?À& conn=op= time=?E\fi{³¸ÿ& conn=op= time=?E\f€Jù`�A@¡*…@/Ý?À& conn=op= time=?E\fßÖù³¸ÿ& conn=op= time=?E\fú½ô`�A@¡*…@‡Ù?À& conn=op= time=?E\f6Jõ³¸ÿ& conn=op= time=?E\f4à`�A@¡*…@ôýÔ?À& conn=op= time=?E\fe೸ÿ& conn=op= time=?E\f"yÜ`�A@¡*…@`åÐ?À& conn=op= time=?E\f‡³Ü³¸ÿ& conn=op= time=?E\f| È`�A@¡*…@ÍÌÌ?À& conn=op= time=?E\f§É³¸ÿ& conn=op= time=?E\fÂÅ`�A@¡*…@9´È?À& conn=op= time=?E\f¶“ų¸ÿ& conn=op= time=?E\fÍW°`�A@¡*…@¦›Ä?À& conn=op= time=?E\füа³¸ÿ& conn=op= time=?E\f‚­`�A@¡*…@ƒÀ?À& conn=op= time=?E\f‰É­³¸ÿ& conn=op= time=?E\f@¥™`�A@¡*…@j¼?À& conn=op= time=?E\fH>š³¸ÿ& conn=op= time=?E\fí�”`�A@¡*…@ìQ¸?À& conn=op= time=?E\frÖ”³¸ÿ& conn=op= time=?E\f¡`�A@¡*…@X9´?À& conn=op= time=?E\f¥€³¸ÿ/ conn= count=op=ver=$%E\fúŸ7(%E\f+ë7,%E\fÂ74/ conn= count=op=ver= &E\f�¬  U / conn= count=0op=ver=@J&E\fúÔñ �&E\fH-ã ô&E\fä:× g&E\fһΠÚ&E\f´«ÆM&E\f®é¿À&E\f`­ª3&E\füÕ¢¦&E\fë &E\fŸæ‰Œ&E\fÅñƒÿ&E\fÃ|r&E\fjQfå&E\fE1`X&E\fB%YË&E\f²$D>&E\fDÑ=±&E\fϦ5$&E\f½‡—&E\fäu &E\f9Æ}&E\fØ¡ú…&E\f±¯ôø&E\f3;í É&E\fø“Ô!<&E\fË´Ê" &E\f™XÃ#€ &E\fë,¹$Q!&E\fŸB¬%Ä!&E\fc`¤&•"&E\fþR™'#&E\fN"ƒ(Ù#&E\f% {)L$&E\fáCn*%&E\f#”_+�%&E\f¤^,a&&E\fQN-Ô&&E\f�ÕC.¥'&E\f¿;/(&E\f ö)0é(&E\fÏWo1\)&E\f�®2-*&E\fOi3 *&E\fiññ3q+&E\fÃó4ä+&E\fJ Û5W,&E\f}ÀÐ6Ê,&E\f»ÕÊ7=-&E\f`[Å8°-&E\f²ˆ´9#.&E\f�®�:–.&E\f**”; /'E\f‰Ôñ|/'E\fŸÃâï/'E\f—ßb0'E\f4ˆÌÕ0'E\føòÇH1'E\f›å´»1'E\f‘®.2'E\fþ½¦¡2'E\f·ò’3'E\ftE� ‡3'E\f´;x ú3'E\fÞt m4'E\f#.n à4'E\f÷Y S5'E\fiÅTÆ5'E\f6d@96'E\fª³>¬6'E\f½+7'E\fná%’7'E\fuÇ8'E\f!Áx8'E\fd«ýë8'E\fËê^9'E\f@õæÑ9'E\fANÑD:'E\f÷HË·:'E\fµ%¼*;'E\fmz¸�;'E\f8d¦<'E\f:Ô ƒ<'E\f6€£ö<'E\f8æi='E\fFþ{:>'E\f(?i ­>'E\f©vc! ?'E\f·¬Z"“?'E\fÿ?#@'E\f<ŠB$y@'E\fD±8%ì@'E\faw"&_A'E\f¤'ÒA'E\f ø(EB'E\f‘eþ(¸B'E\f˜Tö)+C'E\f5÷é*žC'E\f“fã+D'E\fcwÌ,„D'E\f×SÆ-÷D'E\f`Á.jE'E\f¨¯«/ÝE'E\fSã¥0PF'E\fdï‘1ÃF'E\fnq‹26G'E\f"!†3©G'E\fq¡n4H'E\fØ`i5�H'E\foÝb6I'E\fŦL7uI'E\fÖBD8èI'E\f„Ù<9[J'E\f':ÎJ'E\ft ";AK(E\fA:´K(E\fñsi…L(E\f�œ]øL(E\feÇSÉM(E\fÑF O(E\fM3€O(E\f„ ,QP(E\fcé "Q(E\fÔY •Q(E\fªþ fR(E\fjö ÙR(E\foYð ªS(E\fìEç T(E\f[ñÎ îT(E\f'‚ÅaU(E\f#«¸2V(E\f3~­¥V(E\f@¥vW(E\f‡²˜éW(E\fásŒºX(E\f^ê|-Y(E\f? rþY(E\fPÚeqZ(E\f:_\B[(E\f`RP\(E\fS*F†\(E\f„•;W](E\fv*2Ê](E\f8U(›^(E\fMO_(E\f5› ß_(E\f]ÌR`(E\fµø#a(E\fôJí –a(E\f@¹Ó!gb(E\f'pÈ"Úb(E\fNÞ½#«c(E\f†Ë¯$d(E\fê$©%ïd(E\fÎ�¦&be(E\fá™'3f(E\fÒÊ�(¦f(E\fkDx)wg(E\fÉp*êg(E\f� h+»h(E\fj],Œi(E\fF-ÿi(E\fûX<.Ðj(E\fÀ2/Ck(E\f‰+0¶k(E\fVR$1)l(E\fÊ82œl(E\fªx 3m(E\fOÒò3‚m(E\f‹Ðì4õm(E\f��æ5hn(E\fU†Ð6Ûn(E\f’eË7No(E\f#¥Ã8Áo(E\fÆ­94p(E\f„§:§p)E\fÀq)E\fëîëq)E\fÑ,å^r)E\fNcÜÑr)E\fpÉÔDs)E\fì[¿·s)E\f„»*t)E\fÍ6§�t)E\f>ê¢u)E\f,A�ƒu)E\f,…‰ öu)E\fÁ<‚ iv)E\fü÷k Üv)E\fıc Ow)E\fK^ Âw)E\f´(U5x)E\f5Ô>¨x)E\fÈD8y)E\f¨¯/Žy)E\f<«z)E\f{Stz)E\f!µ çz)E\f¬-öZ{)E\fi©îÍ{)E\fÛ"ã@|)E\f;wÚ³|)E\fØÛÄ&})E\fȃÁ™})E\f¼P± ~)E\fg(«~)E\foÕ£ò~)E\f™7�e)E\fŃ6€)E\fðu©€)E\fszn z�)E\f”»d!í�)E\fGAL"¾‚)E\f'zB#1ƒ)E\fÚñ7$„)E\f],%Ó„)E\f²&&F…)E\f“s'†)E\fV*(І)E\f@ )[‡)E\fóWñ)·)E\f-3é*Ÿˆ)E\fö ß+‰)E\fX}Õ,ã‰)E\f—øÌ-VŠ)E\fÑÙ±.'‹)E\fa°³/š‹)E\fF4§0kŒ)E\f#›1ÞŒ)E\fO§ƒ2¯�)E\fzy3"Ž)E\fú÷t4óŽ)E\fzƒi5f�)E\f!,_67�)E\f±Q7‘)E\foH8{‘)E\f÷-99L’)E\f‡….:¿’)E\f1^!;�“*E\fv»|”*E\fÆ�qÔ”*E\f€eG•*E\fOÑN–*E\fÚ¸D‹–*E\f2‰;\—*E\f½§.Ï—*E\f›A$ ˜*E\f<ë™*E\f(” ä™*E\fÔí Wš*E\foñ (›*E\f´¼å ››*E\fÂÑÜ lœ*E\fý Ö =�*E\f:VÀ°�*E\f½´À�ž*E\fÿì©ôž*E\f<%¡ÅŸ*E\f¨B–8 *E\f©Å� ¡*E\f±�„|¡*E\fQvyM¢*E\f6�pÀ¢*E\f‘øW‘£*E\fTØJ¤*E\fݹ?Õ¤*E\fÜÝ6H¥*E\f:û1¦*E\f`E&Œ¦*E\fg]§*E\f½Ч*E\f_�ü¡¨*E\f¿jñ©*E\fËZì å©*E\fÊ©à!¶ª*E\f Ê")«*E\fbÙ¿#ú«*E\fæ¾µ$m¬*E\fC%§%>­*E\fîy—&±­*E\f­–'‚®*E\f àˆ(õ®*E\f(Í|)Ư*E\f��q*9°*E\ftFf+ ±*E\f£ê[,}±*E\f£ùR-ð±*E\foµ;.c²*E\f„€2/4³*E\fñ®*0§³*E\fË1´*E\f ”2�´*E\f@Ü 3µ*E\f(Où3sµ*E\f”1ô4æµ*E\fh„ß5Y¶*E\fsÙ6̶*E\fV‡Ã7?·*E\f\þ¿8²·*E\f¸+¬9%¸*E\fEj§:˜¸+E\fÖð ¹+E\fÌ¿ó~¹+E\f ðñ¹+E\fªCÛdº+E\fôË׺+E\fY€ÇJ»+E\fñ¬³½»+E\f¼ž®0¼+E\fQ¸ª£¼+E\f à•½+E\fTÐ� ‰½+E\fkw} ü½+E\f›Ïx o¾+E\fì.d â¾+E\f ^ U¿+E\fÂHÈ¿+E\f×½C;À+E\f£Ž=®À+E\f§û'!Á+E\fŒí!òÁ+E\fø¥eÂ+E\fVÿ 6Ã+E\f½ý÷©Ã+E\fT!õzÄ+E\f¯lÜKÅ+E\fŠùÖ¾Å+E\fQÇË�Æ+E\fŸµÅÇ+E\fY¶°ÓÇ+E\fy¤©FÈ+E\f›ç¡É+E\fÁŒŠÉ+E\fI‰[Ê+E\f®]qÎÊ+E\f:?j ŸË+E\fɶ^!Ì+E\f~V"ãÌ+E\fJeM#VÍ+E\fÀ÷6$'Î+E\f&Ÿ,%šÎ+E\f'Ó%&kÏ+E\fœ'ÞÏ+E\f&H(¯Ð+E\fÃ)"Ñ+E\f5þ)•Ñ+E\f†Âè*Ò+E\fëLá+{Ò+E\f¾eÍ,îÒ+E\fšvÅ-aÓ+E\fÁ³¾.ÔÓ+E\fŸ©/GÔ+E\fëBŸ0ºÔ+E\fÒ›1-Õ+E\f’w�2 Õ+E\f.‡3Ö+E\fHøp4†Ö+E\fØj5ùÖ+E\f‹Hc6l×+E\fͱL7ß×+E\fõ(G8RØ+E\fÊT>9ÅØ+E\f8]&:8Ù+E\f^ý!;«Ù,E\f0~Ú,E\f"h‘Ú,E\f6$aÛ,E\f™ZwÛ,E\fÎ…EêÛ,E\fPà?]Ü,E\f/9ÐÜ,E\fPñ"CÝ,E\fìø¶Ý,E\fs¨ )Þ,E\f®Hþ úÞ,E\fniø mß,E\fhEð >à,E\fP8è ±à,E\f°ÌÏ ‚á,E\f}»Éõá,E\füá´Æâ,E\f}Õ¨9ã,E\fÐ|Ÿ ä,E\fs6—}ä,E\fŠÉ‹Nå,E\fÉ€~Áå,E\f,Îv’æ,E\fÒ°jç,E\f¯ŒcÖç,E\fµÔW§è,E\fe?é,E\fG:5ëé,E\f@w+^ê,E\f*;#/ë,E\f¢ë,E\fbœsì,E\fAUøæì,E\f‰ï·í,E\fý°ä *î,E\fn<Û!ûî,E\fôÌ"nï,E\f¼—Á#?ð,E\fê�»$²ð,E\fõ޳%ƒñ,E\fž¾Ÿ&öñ,E\fD——'%ó,E\f&À‰(˜ó,E\f©() ô,E\f„lv*~ô,E\föø^+ñô,E\f5Y,dõ,E\f‚AS-×õ,E\f�—@.Jö,E\fYx9/½ö,E\f% /00÷,E\fA 1£÷,E\f‘2ø,E\fc| 3‰ø,E\f�Jó3üø,E\f2î4où,E\fë_é5âù,E\fèÕ6Uú,E\f;�Ð7Èú,E\fU¬¼8;û,E\fŠO¸9®û,E\fc,¥:!ü-E\f(\”ü-E\f°îý-E\fr îzý-E\f\SÜíý-E\f—$×`þ-E\fÂ?ÃÓþ-E\fü¾Fÿ-E\f0‰ª¹ÿ-E\f¨ˆ¥,-E\fM“Ÿ-E\fíg� p-E\fXí… ã-E\f!n ´-E\f·^ '-E\f³ËS ø-E\f=1Jk-E\f¦f?<-E\fúý5¯-E\fE4,"-E\f:8&ó-E\fŠ9 f-E\fOÆÙ-E\fºŸûL-E\fubó¿-E\fFBÝ2 -E\fd2Õ¥ -E\fãˆÑ -E\fe�º‹ -E\fž´þ -E\f™†®q -E\fQ˜ä -E\f÷=”W -E\f{Û}Ê -E\f^žx= -E\fÆ—r ° -E\f*d]!#-E\f?ÕU"–-E\fßïN# -E\f^æ9$|-E\fÆ\5%ï-E\fx¤-&b-E\fíV'Õ-E\fè7(H-E\fD )»-E\f$ó).-E\f]Õï*¡-E\f¬Û+-E\f›Ø,‡-E\f²ƒÁ-ú-E\f1Ú½.m-E\fj³³/>-E\fn œ0±-E\f^õ–1‚-E\f�‘2õ-E\fÄ~3Æ-E\f@[o49-E\fæ–a5 -E\f[@W6}-E\f“çK7N-E\fT@8Á-E\fGª59’-E\fM.:-E\f…%;Ö.E\f¿xI.E\f÷‰f.E\fŸ†[�.E\f1£S^.E\fÑmKÑ.E\fY‡D¢ .E\f’9s!.E\fÀ4!æ!.E\f½ž·".E\fÜB *#.E\fØ^ û#.E\fqý n$.E\fS?æ ?%.E\fèÝ ²%.E\fÇ‡Ñ ƒ&.E\fè Êö&.E\f¾þÂÇ'.E\fÅ2­:(.E\f™ê¢i).E\fæd˜Ü).E\fB’O*.E\fáÊ{Â*.E\f5!t5+.E\f "p¨+.E\fÓ¼Y,.E\f‘xSŽ,.E\fPÀ?-.E\fÓ9t-.E\f³º4ç-.E\f…h Z..E\f‚Í..E\f]Ÿ@/.E\f£7³/.E\fdYï&0.E\fd�ê ™0.E\fg½Õ! 1.E\f šÑ"1.E\f9ý¿#ò1.E\fq¦¯$e2.E\fÊ\°%Ø2.E\fO&¡&K3.E\fG¯Ž'¾3.E\fòCŒ(14.E\fªQw)¤4.E\f88t*5.E\fÜê`+Š5.E\få\_,ý5.E\f4°I-p6.E\fÜ}@.ã6.E\fYÝ7/´7.E\f9É,0'8.E\fA“$1ø8.E\f_22k9.E\fv3<:.E\fKù3¯:.E\fÍÖñ4€;.E\f5·æ5ó;.E\f‡?Ñ6Ä<.E\fBÊ77=.E\fûòÄ8>.E\fS¬9{>.E\f?“¦:L?/E\fŒb¿?/E\fÖ]ö�@/E\f—>éA/E\föÅâvA/E\f©ÂÌGB/E\f‹_ĺB/E\f p¼-C/E\fqT© C/E\f ¢D/E\fÖV™†D/E\f0[� ùD/E\f¬Üz lE/E\fýPt ßE/E\f¹¹k RF/E\fw9U ÅF/E\f±"N8G/E\fžG«G/E\f½à.H/E\f¡½#‘H/E\f‚I/E\f…wI/E\f9Ä êI/E\f;Õö]J/E\fgPôÐJ/E\foÜCK/E\f‰ÕÓ¶K/E\f9cÏ)L/E\fLÈœL/E\fÆ¿³M/E\fl@­‚M/E\fÄ(—õM/E\fF>’hN/E\f´IÛN/E\f™¸xNO/E\f®Dr ÁO/E\fIXZ!’P/E\fŒÜM"Q/E\fFD#ÖQ/E\f– ;$IR/E\f¾61%S/E\fÎÏ&ëS/E\fv�'^T/E\fÝ (/U/E\fxPý(¢U/E\fDfñ)sV/E\f¤ýç*æV/E\fÞ+·W/E\f„ÃÐ,*X/E\f†Æ-ûX/E\fÒ1¼.nY/E\f]O²/?Z/E\f&¨¦0²Z/E\f;'œ1ƒ[/E\f“wŽ2ö[/E\fÁ…3Ç\/E\f7z4˜]/E\fƒDb5 ^/E\f tW6Ü^/E\f?lM7O_/E\fgäC8 `/E\féX99“`/E\fÖ71:da/E\f+P;5b0E\f“w¨b0E\f�,sc0E\fµ6^Žc0E\fjEWd0E\f2GNtd0E\frm8çd0E\fZ>5Ze0E\fÌ™!Íe0E\fަ@f0E\fÁ¿ ³f0E\fpë &g0E\f©ò ™g0E\f¿¢ê h0E\fTxç h0E\f†Ó òh0E\f›ŠÃei0E\fª7ÀØi0E\fŠ­Kj0E\f^¨¾j0E\fqN”1k0E\f7R�¤k0E\fèy|l0E\fÎüxŠl0E\fh#eýl0E\fþ`pm0E\fYÌLãm0E\f2CIVn0E\f¸‹4Én0E\fäz.�1E\fܱ8±�1E\f�å#‚�1E\f,µõ�1E\fIÆ‘1E\fîÿ —’1E\f±¯÷ “1E\f²ZïÛ“1E\fbèN”1E\fѮѕ1E\f͋̒•1E\f÷Æc–1E\fón°Ö–1E\f”«§—1E\f Y¡˜1E\fyíˆë˜1E\fn€^™1E\f¥hz/š1E\f¸lh ¢š1E\f¶jb!s›1E\ftƒ\"æ›1E\fKæJ#·œ1E\f„@$*�1E\f É(%û�1E\fÕK,&Ìž1E\fº'?Ÿ1E\fë( 1E\fÜ )ƒ 1E\f#æï)T¡1E\fÍë*Ç¡1E\f œå+˜¢1E\fȳË, £1E\f|Ã-~£1E\f™».ñ£1E\f)]³/d¤1E\f�Ÿ0פ1E\f–ò˜1J¥1E\fX?†2½¥1E\fl�30¦1E\f%+z4£¦1E\f¥(d5§1E\f^ç]6‰§1E\f$ÐV7ü§1E\f ò?8o¨1E\fù›69â¨1E\fÓ.:U©1E\fV%;È©2E\f"ss;ª2E\fQ`n®ª2E\fËh!«2E\f{£V”«2E\fÑòN¬2E\f9z¬2E\f3î2í¬2E\fD-`­2E\fÛóÓ­2E\f5å F®2E\fý ¹®2E\fHPö ,¯2E\f¦‹ñ Ÿ¯2E\f«lå °2E\fͪРã°2E\fh-ÈV±2E\fq›´'²2E\f‚­š²2E\f^§k³2E\f}`ŸÞ³2E\fKÒ…¯´2E\fÝÍz€µ2E\f¨œróµ2E\f_©kĶ2E\fâ#V7·2E\f°XX¸2E\fµõ?{¸2E\få7L¹2E\fì,1¿¹2E\f‚â(�º2E\fìY»2E\f\LÔ»2E\fMàÿG¼2E\fÑRõ½2E\fÉ4ê ‹½2E\fJá!\¾2E\f^�Ö"Ͼ2E\f¥’½# ¿2E\fX¿±$qÀ2E\fMТ%äÀ2E\f|Y˜&µÁ2E\f._Ž'(Â2E\fS±‡(ùÂ2E\fz—€)lÃ2E\fV\i*=Ä2E\f±®a+°Ä2E\f˜V,�Å2E\f¾ZE-ôÅ2E\f2Ù7.ÅÆ2E\f {:/8Ç2E\f“‰!0 È2E\fè,1|È2E\f8Ú2MÉ2E\fï' 3ÀÉ2E\fƒ4‘Ê2E\f˜Ïè4Ë2E\fyâ5ÕË2E\fµüÔ6HÌ2E\fÐ_Ë7Í2E\fÓ»8êÍ2E\fݰ9]Î2E\f{ ©:.Ï3E\fKŸ¡Ï3E\fò÷rÐ3E\føìåÐ3E\f`Ðâ¶Ñ3E\f»ÁË)Ò3E\fµŸÁúÒ3E\f«k¹mÓ3E\f�X®>Ô3E\f›l¤±Ô3E\fÔ£˜‚Õ3E\f“Њ õÕ3E\f¦b| ÆÖ3E\füöm 9×3E\fÄ€d Ø3E\fD¦[ }Ø3E\f\FNÙ3E\fN|HÚ3E\fS=’Ú3E\fÙÃ#cÛ3E\fóðÖÛ3E\fqH§Ü3E\f¹­Ý3E\fÝ{ÿëÝ3E\fZè^Þ3E\f†åß/ß3E\fTÙ¢ß3E\f¦Äsà3E\f½;¼æà3E\f‘W¶·á3E\fð«*â3E\f²D”ûâ3E\f!Šnã3E\f5…?ä3E\f‘}²ä3E\f_4f ƒå3E\fuð]!Tæ3E\fËäT"Çæ3E\fSéK#˜ç3E\f`{C$ è3E\fÖ—)%Üè3E\f¼Æ(&Oé3E\fžæ' ê3E\f"â(“ê3E\fAZ)dë3E\f<;û)×ë3E\f¨?ä*¨ì3E\fJÛ+í3E\f>iÔ,ìí3E\fÓÊ-_î3E\f_�À.0ï3E\fu´¨/£ï3E\fÈã¥0tð3E\f”÷›1Eñ3E\f©-†2¸ñ3E\fÚö3‰ò3E\f"Æv4üò3E\f«úm5Íó3E\f _U6@ô3E\f°«H7õ3E\fs J8„õ3E\fFæ<9Uö3E\fôÁ3:Èö3E\f6¯;™÷4E\f¼¤v ø4E\f8ÙlÝø4E\fôD`Pù4E\f�*X!ú4E\f4¬N”ú4E\f( 7eû4E\fÓæ76ü4E\f¨-©ü4E\f!zý4E\f+ä íý4E\f!$þ ¾þ4E\fŤñ 1ÿ4E\f(è 4E\f!Íæ u4E\f;GÍ F4E\fW"ù4E\fnö·Š4E\fî·³ý4E\fæ�Î4E\f|#—A4E\fñ…4E\f>’z¶4E\f’ƒoV4E\fj{g'4E\fC`š4E\f7ÚSk4E\f»ÜJÞ4E\f“t2¯ 4E\f K(" 4E\fì ó 4E\f1]f 4E\fôs 7 4E\fÞúª 4E\fwæï{ 4E\f˜Úå î 4E\f�iÛ!¿4E\fáÑ"24E\fÄ�Ç#4E\fãgº$v4E\fžŒ±%G4E\fà\£&4E\f˜d”'‹4E\f Ü‚(\4E\f]Æu)Ï4E\fqöj* 4E\fé®b+4E\f»¨Z,ä4E\fB:S-W4E\fÀ§:.(4E\fÚ}-/›4E\fV!0l4E\f(1ß4E\fØ@2°4E\f©Ö3#4E\f?Éÿ3ô4E\fCÔå4g4E\f%ˆà584E\fx8Ó6«4E\fz”Ç7|4E\fŒÚ¼8M4E\f…iµ9À4E\fÌÀª:‘4E\fÂÏ’; 5E\fÿ�ìÕ 5E\fSæH!5E\fõ‚ß"5E\f $׌"5E\fQ¥¿]#5E\f’È´Ð#5E\f™½©¡$5E\f‚‘¢%5E\f!óšå%5E\fŸƒ X&5E\f·{ )'5E\f_5E\f“žÎ-Â>5E\fÆ¥¶.“?5E\fŠ^¨/d@5E\fdD�0×@5E\fð”1JA5E\fx4‹2½A5E\f±<ƒ30B5E\fUn4£B5E\fÓÂg5C5E\fªIU6‰C5E\f8®O7üC5E\f…uE8ÍD5E\fˆ:9@E5E\fƒ0:³E5E\fÔ';&F6E\fLjv™F6E\f:p G6E\fä™jG6E\fZ¼SòG6E\fMeH6E\fNÙAØH6E\fN;KI6E\f§m%¾I6E\f› !1J6E\f* ¤J6E\fÖv K6E\felý ŠK6E\fk"è ýK6E\f''à pL6E\f:äÔ ãL6E\fJZÂVM6E\f¥1¼ÉM6E\f¦¶‹2<�7E\f‚3¯�7E\f5Ðl4"‚7E\f†Øe5•‚7E\fªq_6ƒ7E\f?\K7{ƒ7E\f !D8îƒ7E\fi£=9a„7E\fÃÙ*:Ô„7E\fEÛ&;G…8E\f_Áxº…8E\f�r-†8E\f/Â] †8E\fAd[‡8E\föÔE†‡8E\fæ@ù‡8E\fÜY,ʈ8E\f}ˆ$=‰8E\fТ°‰8E\fÌð #Š8E\f™ô –Š8E\fÝ5ü ‹8E\fØÄå |‹8E\fv¬Þ ï‹8E\fV�× bŒ8E\f‰ÂÕŒ8E\fŸJ»H�8E\f�¯²»�8E\f"U«.Ž8E\f=œ”¡Ž8E\fï‘�8E\f$Î}‡�8E\f�@wú�8E\fþ•pm�8E\fÌóYà�8E\fNðTS‘8E\f°KÆ‘8E\f[á?9’8E\fýp5¬’8E\fL3“8E\fAä’“8E\fD”8E\fÍŽx”8E\f —ñë”8E\f¯Òé ^•8E\fâ!Ñ•8E\faË"D–8E\fÆÂ#—8E\f ½µ$ˆ—8E\f–Æ®%û—8E\f´S™&n˜8E\fT”'á˜8E\fë=Š(T™8E\fιƒ)Ç™8E\feío*:š8E\fœlj+­š8E\f[¹U, ›8E\f3ZQ-“›8E\f=L<.œ8E\f]g8/yœ8E\fu#0ìœ8E\f;Ä1_�8E\f%õ 2Ò�8E\fýÅ3Ež8E\fòšó3¸ž8E\f@4ï4+Ÿ8E\fYŠÜ5žŸ8E\fvrä6 8E\f ÃÄ7â 8E\fЃ¸8U¡8E\f�5¯9È¡8E\fkð¦:;¢9E\f2箢9E\fV�ð!£9E\fí_딣9E\f©ñá¤9E\f¥~Ìz¤9E\fGÉí¤9E\f7Þ³`¥9E\f.)­Ó¥9E\fÇ7šF¦9E\f/•¹¦9E\f:|� ,§9E\f=Êz Ÿ§9E\f�t ¨9E\fŠÆl …¨9E\f­æV ø¨9E\f¿|Qk©9E\fwÔIÞ©9E\fA‚3Qª9E\fM-Ī9E\fðK$7«9E\f¾Ðª«9E\f½ï¬9E\f·|ÿ�¬9E\fD]ê­9E\fiäv­9E\fó}Ýé­9E\fèÆ\®9E\f½¿¾-¯9E\fç° ¯9E\fóÅ©q°9E\ft°žä°9E\f›Ã•µ±9E\f ÷‹(²9E\f Åuù²9E\f{!n ʳ9E\fX d!=´9E\fG¡V"µ9E\f±ÇK#�µ9E\f~µB$R¶9E\fVŽ,%Ŷ9E\f > &–·9E\f ' ¸9E\f¦ô (Ú¸9E\fRNø(M¹9E\fšMù)º9E\frkï*‘º9E\fëë×+b»9E\fb~É,Õ»9E\fÀ-¦¼9E\fß¹.½9E\f0²/ê½9E\fÜŧ0]¾9E\fñ�1о9E\f<ø‡2C¿9E\f²·�3¶¿9E\fÁœx4‡À9E\f­úm5úÀ9E\f0šT6mÁ9E\fá%M7àÁ9E\f¸ F8SÂ9E\fñ29ÆÂ9E\fëi.:9Ã9E\fÁ ;¬Ã:E\fƒÄ~Ä:E\fnQi’Ä:E\fœbdÅ:E\f»’[xÅ:E\fèƒQëÅ:E\fFÏ:^Æ:E\f}_3/Ç:E\fWò(¢Ç:E\fy) È:E\f\Ÿ ˆÈ:E\fÆNü ûÈ:E\föæó nÉ:E\fË·ð áÉ:E\fARÙ TÊ:E\fÅÑ ÇÊ:E\f+ñÈ:Ë:E\fLʵ­Ë:E\fs¿² Ì:E\fF¬“Ì:E\fÓ=•Í:E\f²J�yÍ:E\fQË{ìÍ:E\f:{v_Î:E\fž¹nÒÎ:E\fÙYEÏ:E\fÅSS¸Ï:E\fänL+Ð:E\fãÂ7žÐ:E\fíQ2Ñ:E\f ‘„Ñ:E\fS8÷Ñ:E\fÆžjÒ:E\f6IùÝÒ:E\fžLòPÓ:E\fœÉê ÃÓ:E\fÿäÔ!6Ô:E\f›ÁÐ"©Ô:E\fÀ_Æ#zÕ:E\fëw»$íÕ:E\fýå¥%¾Ö:E\fuÍœ&b×:E\fÿ³’'Ø:E\f†(uØ:E\f‡Á)FÙ:E\fh}v*Ú:E\fŸk+ŠÚ:E\fä™S,[Û:E\fÀ©J-ÎÛ:E\fäŽB.ŸÜ:E\fž69/Ý:E\f-S,0ãÝ:E\fëÁ1VÞ:E\fj~2'ß:E\fN3šß:E\fÎ.ÿ3kà:E\fêõ4Þà:E\f˜ÜÝ5¯á:E\f¡bÓ6"â:E\fL5Ê7óâ:E\fêÝ¿8fã:E\f¹Ìµ97ä:E\f¹(ª:ªä:E\f߯’;{å;E\flþíîå;E\fØàä¿æ;E\fòÒÜ�ç;E\f!~Òè;E\fû¡ËÔè;E\f©¹³Gé;E\f;úªê;E\f*Þ£‹ê;E\fK™\ë;E\fa‹‚ Ïë;E\f’Ñ{ Bì;E\fÝ;t µì;E\fÓÆj (í;E\f©%S ›í;E\f‹=Lî;E\fÖG�î;E\fÙÿ3ôî;E\f-Z.gï;E\f¦]Úï;E\fêL«ð;E\fÂ] ñ;E\f\†ô‘ñ;E\fïïò;E\fäÃéwò;E\f²øÒêò;E\f)Ì]ó;E\fuüÂÐó;E\f¼’¬Cô;E\f\V¤¶ô;E\fè® )õ;E\f¨—Šœõ;E\fùLƒö;E\f“Ì|‚ö;E\f'Ãt õö;E\f°^!h÷;E\fØWW"Û÷;E\f† C#Nø;E\fw�@$Áø;E\f3[9%4ù;E\f‡ë!&§ù;E\fA˜'ú;E\f> (�ú;E\f!ý(û;E\fóðö)sû;E\fè#ð*æû;E\fœ¾Ù+Yü;E\f Õ,Ìü;E\f—‹Î-?ý;E\f¯Â».²ý;E\fÆñ´/%þ;E\f·ož0öþ;E\fJΕ1iÿ;E\föÌ�2:;E\f”S}3­;E\fÅ>v4~;E\fçE`5ñ;E\frNV6Â;E\fnAM7“;E\fêžD8;E\fB?9y;E\f/Å-:ì;E\f^';_�&†!0Ú $-=E\fÒ3| —-=E\fzCi h.=E\fëõf Û.=E\f±V ¬/=E\f.lJ0=E\f7â=ð0=E\f�“3c1=E\fm4(42=E\f½§2=E\fYx3=E\f@ë3=E\fUzÿ¼4=E\fh%é/5=E\f«µà6=E\fV3ÖÑ6=E\fX!ÏD7=E\f¶¯Ç8=E\fZñ´ˆ8=E\f¬£û8=E\fJ–¡n9=E\fŽ:=E\f³‡‰T:=E\fyvwÇ:=E\f÷=E\f±6(Ò>=E\fªz)E?=E\f û)¸?=E\fæ*+@=E\f‹oß+ž@=E\fssÚ,A=E\f¸Ç-„A=E\fÛ Ã.÷A=E\fl¬¯/jB=E\f#a©0ÝB=E\f ©•1PC=E\fÈû„2ÃC=E\f7T‚36D=E\f±Fn4©D=E\f?Ih5E=E\f$a6�E=E\fØûK7`F=E\f«@8ÓF=E\f}'99¤G=E\fèá2:H=E\f!;èH>E\f:ûv[I>E\fÎùkŠJ>E\f'¤_ýJ>E\fÚ1WpK>E\f7rPãK>E\f,:VL>E\fè©4ÉL>E\fc-E\f®u¯M>E\f-� "N>E\fõÖ •N>E\fßcó O>E\f’7í {O>E\fbsÛ îO>E\fžÖ aP>E\fš‰ÏÔP>E\fØC½GQ>E\f÷€·ºQ>E\fy›£-R>E\f<�œ R>E\f”é…S>E\f“¢‚†S>E\f°»{ùS>E\fítelT>E\fý²]ßT>E\fàKURU>E\fñŠ?ÅU>E\f¨¸:8V>E\f³4«V>E\f°ç W>E\fEN‘W>E\fvþX>E\fßÐûÕX>E\f�"ðHY>E\fÿÁç »Y>E\f”â!.Z>E\fà(Í"¡Z>E\f ©É#[>E\fÃ7µ$‡[>E\f%\¯%ú[>E\f¿=¦&m\>E\fÄ‹'à\>E\fV‡(S]>E\fA¨u)Æ]>E\f‚at*9^>E\f›Ûf+¬^>E\fè],_>E\fùGF-’_>E\f4½@.`>E\f·E\fbH)0ë`>E\fÜ$1^a>E\f²I2Ña>E\fì 3Db>E\fà£ö3·b>E\f™Zò4*c>E\f�UÜ5�c>E\f^¨Ó6d>E\f$±Ì7ƒd>E\f)ùÅ8öd>E\f]bµ9ie>E\fC'¤:Üe>E\fÆ›—;Of?E\fÎ5ïÂf?E\f3£ê5g?E\f›BÕ¨g?E\f³µÊh?E\fØßÅŽh?E\f©ñ¾i?E\f¢&«ti?E\fä¨çi?E\f¼V–Zj?E\fs ‘ Íj?E\f»i| @k?E\fáw ³k?E\f„Ša &l?E\f³¸\ ™l?E\fé*J m?E\f²�Fm?E\f^2òm?E\f]-&en?E\fOâØn?E\fuKo?E\f Y ¾o?E\f€Jù1p?E\fú½ô¤p?E\f4àq?E\f"yÜŠq?E\f| Èýq?E\fÂÅpr?E\fÍW°ãr?E\f‚­Vs?E\f@¥™És?E\fí�”ó&E\fÎ6f&E\f°Ù&E\fcRL&E\fh¿&E\fiDûÇ&E\f}wõ:&E\fð·í &E\f¤Ô!~&E\f/.Ë"O &E\f½éÃ# &E\fW¥¹$“!&E\fq·¬%"&E\f‡Œ¤&×"&E\fLÁ™'J#&E\f¶÷ƒ($&E\f« |)Ž$&E\ff�n*_%&E\fê`+Ò%&E\fÜu^,£&&E\fmCN-'&E\fJD.ç'&E\feY;/Z(&E\f&1*0+)&E\fŠ»o1ž)&E\fQú2o*&E\fÇ[p3â*&E\fD5ò3³+&E\fý÷ó4&,&E\fáÛ5™,&E\f­0Ñ6 -&E\fqË7-&E\fßïÅ8ò-&E\fêÒ´9e.&E\f�½�:Ø.&E\f‘§”;K/'E\fYó¾/'E\f:�ã10'E\fbÄà¤0'E\fººÌ1'E\f.ÍÉŠ1'E\fWdµý1'E\f‘ɯp2'E\fŠö§ã2'E\f‘“V3'E\fÄ÷� É3'E\fÓy <4'E\f°t ¯4'E\f —o "5'E\f=–Z •5'E\fE÷T6'E\fXö@{6'E\fÞ?î6'E\fñq+a7'E\f&Ô7'E\f‰nG8'E\fɺ8'E\fÌÿ-9'E\f«Æë 9'E\f£qç:'E\füßц:'E\fL+Ìù:'E\f�ül;'E\f©õ¸ß;'E\fù†¦R<'E\f˜¡Å<'E\fó£8='E\fbe€«='E\f‰R||>'E\fÆÍi ï>'E\f…‹d!b?'E\f4.["Õ?'E\fª*@#H@'E\f› C$»@'E\f‚é9%.A'E\fE#&¡A'E\fýY'B'E\fć(‡B'E\fL-)úB'E\f(Úö)mC'E\fÄê*àC'E\f;Ïã+SD'E\fáÌ,ÆD'E\fg�Æ-9E'E\fWbÂ.¬E'E\f#3¬/F'E\f²¢¨0’F'E\f¼1’1G'E\f¬ÌŒ2xG'E\f¬Ì‡3ëG'E\f®p4^H'E\fVËi5ÑH'E\fƒe6DI'E\fM7·I'E\fDéD8*J'E\fÎ�=9�J'E\f&ö(:K'E\fî#;ƒK(E\f²)€öK(E\fô×iÇL(E\fC{^:M(E\fÜSU N(E\fw—G~N(E\fê¾>OO(E\f€G5ÂO(E\f°Ž,“P(E\f±e!dQ(E\fÅÄ ×Q(E\fnÿ ¨R(E\f B÷ S(E\f¡&ò ìS(E\fx›ç _T(E\f_HÏ 0U(E\feŽÅ£U(E\fU¹tV(E\f.ø­çV(E\fí¥¸W(E\f‚;™+X(E\fЬŒüX(E\fF^}oY(E\fuýr@Z(E\fÞf³Z(E\fü]„[(E\f%|QU\(E\f›‹FÈ\(E\f¾J<™](E\f™¡2 ^(E\f?¾(Ý^(E\f×ÝP_(E\f¸ø !`(E\f>O”`(E\f ,øea(E\f=‰í Øa(E\faøÓ!©b(E\f¹È"c(E\f$.¾#íc(E\fýG°$`d(E\fˆ©©%1e(E\f §&¤e(E\fÖ¡™'uf(E\fÌÛ�(èf(E\f«x)¹g(E\f;or*,h(E\f…Lh+ýh(E\f‡y],Îi(E\f¾¡F-Aj(E\f{ö<.k(E\f43/…k(E\fé°+0øk(E\f/ú%1kl(E\f²}2Þl(E\fÁ 3Qm(E\f„‘ó3Äm(E\få²í47n(E\f¿æ5ªn(E\fð!Ó6o(E\f„ÿË7�o(E\fþ2Ä8p(E\fû`®9vp(E\fÎ…©:ép)E\f³\q)E\f~€î-r)E\f®å r)E\fãÚÝs)E\fK\Õ†s)E\f.Àùs)E\fP³»lt)E\fn¨ßt)E\fD�£Ru)E\f_–�Åu)E\fq–‰ 8v)E\f˜Ó‚ «v)E\f8)l w)E\f«te ‘w)E\fc‘^ x)E\f‡”Uwx)E\fÊw?êx)E\fƒÏ8]y)E\f®+0Ðy)E\fCDCz)E\fÛ3¶z)E\f¤:){)E\f]øöœ{)E\fTï|)E\fvìã‚|)E\fþÜõ|)E\fáÒÇh})E\fÈ4ÂÛ})E\fœ±N~)E\f¤Â«Á~)E\fMj¤4)E\fž^ާ)E\fîƒx€)E\fé�uë€)E\f¸Ûn ¼�)E\fœ;e!/‚)E\fÔ—L"ƒ)E\fÑêB#sƒ)E\f A8$D„)E\f­n,%…)E\f—&&ˆ…)E\f=À'Y†)E\f+©(̆)E\fîà )�‡)E\ffÞñ)ˆ)E\fä ê*áˆ)E\f{ß+T‰)E\f%ÿÕ,%Š)E\fqJÍ-˜Š)E\f—².i‹)E\f?¼³/Ü‹)E\fm›§0­Œ)E\f(.›1 �)E\f,+„2ñ�)E\f)z3dŽ)E\fd�u45�)E\fì^j5¨�)E\fns_6y�)E\fØ€Q7J‘)E\f|ƒH8½‘)E\fš˜99Ž’)E\fGq/:“)E\f¸ ";Ò“*E\f¨H}E”*E\f¬¾q•*E\fxf‰•*E\fOZ–*E\f£CEÍ–*E\f‘Ü;ž—*E\fÅ/˜*E\f’G$â˜*E\fÔdU™*E\f0 &š*E\f°O ™š*E\f™Íñ j›*E\fE*æ Ý›*E\f_OÝ ®œ*E\f|eÖ �*E\fΧÀò�*E\f0QÁÞ*E\f0bª6Ÿ*E\f>”¡ *E\f0¿–z *E\f¤÷�K¡*E\fy…¾¡*E\fUéy�¢*E\fþmq£*E\feNXÓ£*E\f*3KF¤*E\f©.@¥*E\fmt7Š¥*E\fqi2[¦*E\föÀ&Φ*E\f“Ÿ§*E\fh ¨*E\f6ýã¨*E\f°.ó´©*E\f]Òì 'ª*E\f*á!øª*E\fuoÊ"k«*E\fÏSÀ#<¬*E\f|;¶$¯¬*E\f¼n§%€­*E\f“¼—&ó­*E\fê^–'Ä®*E\fD�‰(7¯*E\fõI})°*E\fÙq*{°*E\ft¸f+L±*E\f�m\,¿±*E\fk~S-2²*E\fH<.¥²*E\f3/v³*E\fF0+0é³*E\fz^1\´*E\fÇ"2Ï´*E\fºõ 3Bµ*E\f–ªù3µµ*E\fµô4(¶*E\f¢ß5›¶*E\fÿêÙ6·*E\f½ Ä7�·*E\f„>À8ô·*E\fMR¬9g¸*E\fýܧ:Ú¸+E\fJ!M¹+E\f;óôÀ¹+E\fFÑð3º+E\f?êÛ¦º+E\fX)Ë»+E\f]ÈŒ»+E\fk1´ÿ»+E\fй®r¼+E\fA«å¼+E\f —X½+E\f ‘ ˽+E\fgô~ >¾+E\f`y ±¾+E\fíGd $¿+E\fè“^ —¿+E\f4I À+E\f1bD}À+E\f2œ=ðÀ+E\fvz(cÁ+E\fz "4Â+E\fª§Â+E\fù&xÃ+E\f¥�øëÃ+E\f 8õ¼Ä+E\f`ZÝ�Å+E\f§Nׯ+E\fÖ�ÌÑÆ+E\f8)ÆDÇ+E\f?ذÈ+E\f婈È+E\f­ ¢YÉ+E\fõ‚ŒÌÉ+E\fÆ·‰�Ê+E\fr rË+E\f²Mj áË+E\f|6_!TÌ+E\fØýV"%Í+E\fyáM#˜Í+E\fÔ7$iÎ+E\f[-%ÜÎ+E\f,â%&­Ï+E\fY¶' Ð+E\f¬(ñÐ+E\fro)dÑ+E\ftÆþ)×Ñ+E\f”éè*JÒ+E\f`Üá+½Ò+E\f£Í,0Ó+E\f0’Å-£Ó+E\f³OÀ.Ô+E\fm©/‰Ô+E\fTߟ0üÔ+E\fœ•œ1oÕ+E\f•î�2âÕ+E\f ¶‡3UÖ+E\fÜ—r4ÈÖ+E\fá÷j5;×+E\fçâc6®×+E\fÖCM7!Ø+E\f™G8”Ø+E\fçÕ>9Ù+E\f\ò&:zÙ+E\f[Z";íÙ,E\fMÎ`Ú,E\fÜWhÓÚ,E\fÑ?aFÛ,E\f(¡[¹Û,E\fF,Ü,E\fÛ}@ŸÜ,E\fBa9Ý,E\fû�#…Ý,E\f•�øÝ,E\f1& kÞ,E\f©äþ <ß,E\f óø ¯ß,E\fP‡ð €à,E\fkfè óà,E\f £Ð Äá,E\f±?Ê7â,E\fµã,E\fU3©{ã,E\f. Lä,E\f�׿ä,E\f1êŒ�å,E\fð~æ,E\fL>wÔæ,E\fZ¢kGç,E\fKæcè,E\f=YXéè,E\f�‡?\é,E\f(œ5-ê,E\f…è+ ê,E\f7¶#që,E\fÇ?äë,E\f‚Qµì,E\fbÊø(í,E\fU ïùí,E\füËä lî,E\fµ™Û!=ï,E\f7?Í"°ï,E\fÂ#�ð,E\f�ù»$ôð,E\f�1´%Åñ,E\fT &8ò,E\fËÈ—'gó,E\f±Ñ‰(Úó,E\f;£€)Mô,E\fÎãv*Àô,E\f 0_+3õ,E\føY,¦õ,E\fž®S-ö,E\fò¿@.Œö,E\fˆî9/ÿö,E\fæ00r÷,E\f A1å÷,E\fá2Xø,E\f“� 3Ëø,E\fÔÖó3>ù,E\fCÆï4±ù,E\fûšé5$ú,E\fÏÕ6—ú,E\f’Ñ7 û,E\fdͼ8}û,E\f²•¸9ðû,E\fJB¥:cü-E\fÙ‰Öü-E\f)�îIý-E\fÉ£î¼ý-E\fýîÜ/þ-E\fLT×¢þ-E\f"TÃÿ-E\fS*¾ˆÿ-E\f÷«ûÿ-E\f¦n-E\fY(“á-E\f1� ²-E\fJr† %-E\f@n ö-E\fï_ i-E\f¼ÜS :-E\fð¥J­-E\fIÎ?~-E\fJP6ñ-E\fŒ,d-E\fÙÂ&5-E\f�¨ ¨-E\fäß-E\fÃnüŽ-E\f ô -E\f—¿Ýt -E\f _Öç -E\f“ÃÑZ -E\fb»Í -E\fÓPµ@ -E\fµ®³ -E\f×ï˜& -E\f”²”™ -E\fúo~ -E\fÎx -E\f”#s ò -E\fûó^!e-E\fbRV"Ø-E\fíO#K-E\fƒ:$¾-E\f®á5%1-E\fØ).&¤-E\fýÖ'-E\fNÜ(Š-E\f— )ý-E\f Åó)p-E\f(9ð*ã-E\fƳÛ+V-E\f|ŸØ,É-E\féÂ-<-E\f/m¾.¯-E\fê´/€-E\f¢´œ0ó-E\fl—1Ä-E\fy ’27-E\fn~3-E\fC©o4{-E\f‰¿a5L-E\fÇ]W6¿-E\f[�L7�-E\fÃ�@8-E\fi69Ô-E\f0 /:G-E\fïÞ%;.E\fæë‹.E\f£æf\.E\fÒò[Ï.E\f[äS .E\f/L .E\fPÃDä .E\f/�9µ!.E\f©¼!(".E\fE4ù".E\f½Ê l#.E\fŒÃ =$.E\f+ þ °$.E\fMŸæ �%.E\f iÝ ô%.E\fp Ò Å&.E\fQ™Ê8'.E\fvvà (.E\ft±­|(.E\fÞ2¤«).E\f`%™*.E\f)’‘*.E\f3|+.E\f8®vw+.E\f(×pê+.E\f¤D[],.E\f\ýTÐ,.E\f@C-.E\fiï9¶-.E\fà4)..E\fíº œ..E\fQ9/.E\f0õ‚/.E\ftDõ/.E\f+ìïh0.E\fÚë Û0.E\fÒAÖ!N1.E\f#-Ò"Á1.E\fZDÀ#42.E\fjŸ°$§2.E\f�›°%3.E\fZ»¡&�3.E\f�'4.E\fQšŒ(s4.E\f7Âw)æ4.E\f{gt*Y5.E\fˆ:a+Ì5.E\fºª_,?6.E\f:åI-²6.E\fÀ—@.%7.E\f·8/ö7.E\få,0i8.E\f°Ù$1:9.E\fã¸2­9.E\fÀº3~:.E\fâÇù3ñ:.E\fÃûñ4Â;.E\fo)ç55<.E\fUÑ6=.E\fÎYÊ7y=.E\f+Å8J>.E\f•^¬9½>.E\fµç¬:Ž?/E\f§@/E\fÖröÒ@/E\fÑaéEA/E\fܼä¸A/E\fF͉B/E\fðÄüB/E\f@ù¼oC/E\f3T«âC/E\fß—¢UD/E\f¹ñ™ÈD/E\f¹‘ ;E/E\fôp{ ®E/E\fåÓt !F/E\fPl ”F/E\fcU G/E\fþ}OzG/E\fÚHíG/E\fö@/`H/E\f\A$ÓH/E\fñÚFI/E\fÓ¹I/E\fßÓ ,J/E\fšf÷ŸJ/E\f¢èôK/E\fØÜ…K/E\fîÔøK/E\fÝÏkL/E\fß‚ÈÞL/E\fó{´QM/E\fá­ÄM/E\f¹—7N/E\fƒ ”ªN/E\fÒåO/E\f@£y�O/E\f­Zr P/E\f`ÅZ!ÔP/E\fÀ§N"GQ/E\f´GE#R/E\f&˜;$‹R/E\f�³1%\S/E\fÐ&-T/E\f¶Ö' T/E\f?õ (qU/E\fÊ…ý(äU/E\fGÑñ)µV/E\f­è*(W/E\f6ˆÞ+ùW/E\fËÍÐ,lX/E\f„æÆ-=Y/E\f¿‰¼.°Y/E\fж²/�Z/E\fÈÿ¦0ôZ/E\f¨„œ1Å[/E\fî�28\/E\fæ †3 ]/E\f±¾z4Ú]/E\fbÎb5M^/E\fRÜW6_/E\füÖN7‘_/E\fkMD8b`/E\f�):9Õ`/E\f²¢1:¦a/E\f$Å;wb0E\f+"wêb0E\fq]s]c0E\fc¼^Ðc0E\føYWCd0E\f�YN¶d0E\f˃8)e0E\fƒä5œe0E\fõØ!f0E\f Âf0E\fkö õf0E\fÝ‚ hg0E\fê÷ó Ûg0E\fÊ©ë Nh0E\fèç Áh0E\fˆÔ 4i0E\f ħi0E\fF]Àj0E\fW­�j0E\fþ´¨k0E\fzj”sk0E\f3è�æk0E\f¹Á|Yl0E\fænyÌl0E\f–we?m0E\fšŸa²m0E\f* M%n0E\f¶ãI˜n0E\fËÔ4 o0E\f +/~o0E\fhño0E\f WÂp0E\f8Y 5q0E\flÃ÷r0E\fy:ðyr0E\f1ç Js0E\f™ÆÛ!½s0E\f°Ô"Žt0E\f¿#u0E\f‚v¹$Òu0E\f͘²%Ev0E\fÍp�&w0E\f&“'‰w0E\fä7‹(Zx0E\f Mw)Íx0E\f0q*žy0E\f ßg+z0E\fMX],âz0E\fáÜI-U{0E\fÞC.&|0E\f¤á7/÷|0E\fË*0j}0E\f52"1;~0E\fWB2®~0E\f/8 30E\f ¥4ò0E\fðïé4À0E\fNÁÞ56�0E\fÀvÙ6‚0E\f›Ä7z‚0E\f÷K¼8Kƒ0E\flxµ9¾ƒ0E\fŽ«£:�„1E\fÁT…1E\f–øíÓ…1E\fO�ÞF†1E\fO^؇1E\f­RÌè‡1E\fZ]È[ˆ1E\fÚ6¾,‰1E\f&f©Ÿ‰1E\f£pŠ1E\f¢šãŠ1E\f4„ ´‹1E\f4{ 'Œ1E\f$¬p øŒ1E\fc k�1E\fëTX <Ž1E\f8N¯Ž1E\fzUC€�1E\f¹89ó�1E\f�6$Ä�1E\f¹ñ7‘1E\fúÊ’1E\f£'Ù’1E\fÐÞ÷L“1E\fÓ³ï”1E\fgXè�”1E\fÐ/Òa•1E\fäœÌÔ•1E\f‘"Æ¥–1E\f ±—1E\f «é—1E\fúÚ¡\˜1E\föB‰-™1E\f¹Š€ ™1E\f-”zqš1E\f`úh äš1E\fcéb!µ›1E\fc«\"(œ1E\fþ K#ùœ1E\fÐLA$l�1E\f /)%=ž1E\fe½,&Ÿ1E\få¤'�Ÿ1E\fþø(R 1E\fàe)Å 1E\fhœð)–¡1E\fùgì* ¢1E\fôæ+Ú¢1E\f…bÍ,M£1E\fü¢Ã-À£1E\f°½.3¤1E\f‚̳/¦¤1E\fS 0¥1E\fîЙ1Œ¥1E\fhˆ2ÿ¥1E\fªó�3r¦1E\f·pz4å¦1E\fŸDd5X§1E\f£n^6˧1E\fïV7>¨1E\fj@8±¨1E\fë79$©1E\fȽ1:—©1E\fúÉ%; ª2E\fÀ.u}ª2E\fö oðª2E\fåBic«2E\fn8WÖ«2E\fŽÍPI¬2E\fuÖ9¼¬2E\fŽŽ3/­2E\f=b-¢­2E\fÕ�®2E\f8é ˆ®2E\f¦šþ û®2E\fÓ\÷ n¯2E\fíÓñ á¯2E\fDûå T°2E\fZÑ %±2E\fӎȘ±2E\f…µi²2E\f·­ܲ2E\f‰Í§­³2E\f©èŸ ´2E\fù…ñ´2E\fFÙzµ2E\fs5¶2E\f?Ll·2E\f§|Vy·2E\fÌÐXJ¸2E\fg§@½¸2E\fe›7޹2E\f�Æ1º2E\f}s)Òº2E\f»E»2E\f–ļ2E\f12E\fúªõZ½2E\f@ë ͽ2E\fl±á!ž¾2E\f¯×"¿2E\f¶0¾#â¿2E\fçý±$³À2E\få:£%&Á2E\f¢z˜&÷Á2E\fÔ¡Ž'jÂ2E\fœ:ˆ(;Ã2E\f�:�)®Ã2E\f-ãi*Ä2E\f_lc+òÄ2E\fÝV,ÃÅ2E\fv›E-6Æ2E\ff<8.Ç2E\fYÉ:/zÇ2E\f’"0KÈ2E\fй1¾È2E\frü2�É2E\f­ 3Ê2E\f�h4ÓÊ2E\fêè4FË2E\fîÝâ5Ì2E\fκÕ6ŠÌ2E\fF¨Ë7[Í2E\f‰r¼8,Î2E\fÅM±9ŸÎ2E\f"é:pÏ3E\fñ4ãÏ3E\frIø´Ð3E\fí.ì'Ñ3E\fNœãøÑ3E\fò`ÌkÒ3E\f× Â<Ó3E\f/﹯Ó3E\f·ï®€Ô3E\fØò¤óÔ3E\fgî˜ÄÕ3E\fß*‹ 7Ö3E\f­u| ×3E\f8ln {×3E\fE=e LØ3E\fÆ=\ ¿Ø3E\fÉ:F�Ù3E\fƒéHaÚ3E\fœ=ÔÚ3E\f6$¥Û3E\fŠ[Ü3E\fCˆéÜ3E\fZ3 \Ý3E\fL-Þ3E\fÅ„è Þ3E\fRlàqß3E\f«Ùäß3E\fqëĵà3E\fí±¼(á3E\fvº¶ùá3E\fëˬlâ3E\f"«”=ã3E\f)šŠ°ã3E\f/±…�ä3E\f]£}ôä3E\f–žf Åå3E\fnƒ^!–æ3E\fOU" ç3E\f�ó3E\f„n5ô3E\fëáU6‚ô3E\f5øH7Sõ3E\f¢�J8Æõ3E\fðK>9—ö3E\fÚ3: ÷3E\fhÃ;Û÷4E\fÕ°wNø4E\f —mù4E\f-|`’ù4E\f°�Xcú4E\f¦7OÖú4E\fcT7§û4E\f›b8xü4E\fë©-ëü4E\f@r¼ý4E\f¿z /þ4E\fÝ|þ ÿ4E\f§ò sÿ4E\f0¢è D4E\fgç ·4E\fªòÍ ˆ4E\feUÃû4E\fT6¸Ì4E\ft*´?4E\fÈ´�4E\f ˜ƒ4E\f=†T4E\f¶Žz…4E\fædp˜4E\f£¹gi4E\f)~`Ü4E\fÈ“;F 5E\f5í!5E\f¶¿æŠ!5E\f‰Þß["5E\f“è×Î"5E\f‘Þ¿Ÿ#5E\f{-µ$5E\f *ªã$5E\f•¢V%5E\f>{›'&5E\f<4„ š&5E\fÛÈ{ k'5E\f¤Æo Þ'5E\f$f ¯(5E\f^ ")5E\fÐ…Ió)5E\f8u@f*5E\f-¡:7+5E\fX:2,5E\fg®{,5E\fýL-5E\f°ò¿-5E\f�.5E\f,C÷/5E\f¥YÞÔ/5E\f»ôÒG05E\f�®Ç15E\f¶!º‹15E\fï±\25E\f½Í¦Ï25E\fÏ35E\f(Ÿ�45E\fÞm‹ä45E\f|W55E\fLh (65E\f²Ì\!›65E\fCÏS"l75E\f`]I#=85E\f‚@$°85E\fÑ.7%�95E\fýè+&ô95E\fo 'Å:5E\f¼ù (8;5E\f{¡) <5E\f.Uô)|<5E\fßë*M=5E\f,–á+À=5E\fÞ_×,‘>5E\f¬4Ï-?5E\f‰ô¶.Õ?5E\f~{¨/¦@5E\fl¶�0A5E\fÑ•1ŒA5E\fˆ¬‹2ÿA5E\f6ˆ„3rB5E\f.Èn4åB5E\fMh5XC5E\f«U6ËC5E\fTEP7>D5E\f®ÏE8E5E\fF¯:9‚E5E\f½Ý0:õE5E\fæR(;hF6E\flúvÛF6E\fϪqNG6E\fâ2kÁG6E\f9´V4H6E\f]‰M§H6E\ff›CI6E\fšJ;�I6E\fµƒ%J6E\fvø!sJ6E\f-¢ æJ6E\f—ü YK6E\fþ ÌK6E\f­è ?L6E\fCÚà ²L6E\fcÕ %M6E\f‰¼Â˜M6E\fÞº¼ N6E\fƒ+·~N6E\fÿë ñN6E\fIkšdO6E\fçÖ’×O6E\f¶R}JP6E\f\nv½P6E\fxm0Q6E\fͳaR6E\fâ$KtR6E\f¥˜DçR6E\f_d>ZS6E\f¦ˆ*ÍS6E\fÈ'@T6E\f¬2³T6E\f:w &U6E\foz™U6E\f'Ïò V6E\f9íî V6E\f�öÛ!òV6E\fäŒÈ"eW6E\f“Ä#ØW6E\fVh»$KX6E\f�°%¾X6E\fP™&1Y6E\f£Î�'¤Y6E\f¥ü‰(Z6E\fƒŠv)ŠZ6E\fs3p*ýZ6E\fÍói+p[6E\f‚aT,ã[6E\f¤ðS-V\6E\f‹A.É\6E\f¿Q;/<]6E\fÁ”'0¯]6E\fšþ"1"^6E\f$2•^6E\fì 3_6E\fÔëö3{_6E\f´î4L`6E\f,yã5¿`6E\fá`Ú6�a6E\f§ÎÏ7b6E\fÃä¸8vb6E\fÿj7E\fO‰8rk7E\f|0åk7E\fÈ_Xl7E\fòIËl7E\f¯G>m7E\fɾû±m7E\fRZõ$n7E\fRß—n7E\fyHÛ o7E\fZÓÐÛo7E\f¤@ÄNp7E\f<«q7E\f•­’q7E\f}w—cr7E\fp�Ör7E\f«¿ˆ§s7E\f>&~6t7E\fS3g ët7E\fa¢^!¼u7E\fÞW"/v7E\f½lK#w7E\fÍ;$sw7E\fm/%Dx7E\f+-'&·x7E\f.k'ˆy7E\f¤ (ûy7E\f¿ùÿ(Ìz7E\flìò)?{7E\f¾›è*|7E\fŽ÷Ü+ƒ|7E\fI×,T}7E\f¼úÌ-Ç}7E\f¤^´.˜~7E\f%\±/i7E\fÆŸž0Ü7E\fÀŽ”1 �7E\fÖÌ‹2~�7E\f¥"‚3ñ�7E\fu m4d‚7E\fBýe5ׂ7E\f#B`6Jƒ7E\f•¹K7½ƒ7E\f•·D80„7E\fYÍ?9£„7E\fè*:…7E\fœ.';‰…8E\fÏæxü…8E\fQ—ro†8E\fèI^â†8E\f�ž[U‡8E\f¥kFȇ8E\f8€A;ˆ8E\f{, ‰8E\fCw%‰8E\fFöò‰8E\fè< eŠ8E\feã ØŠ8E\fx{ü K‹8E\fuIæ ¾‹8E\f‚�ß 1Œ8E\f-Ø ¤Œ8E\f§§Â�8E\fË,¼Š�8E\f·a³ý�8E\f€˜¬pŽ8E\fÖ%•ãŽ8E\fñ�‘V�8E\fŽY~É�8E\fQ y<�8E\fÊ-q¯�8E\f_j["‘8E\fÑvU•‘8E\f"CM’8E\fm0@{’8E\f˜ä5î’8E\f<§a“8E\fTðÔ“8E\fÁÅG”8E\fÓº”8E\fÃò-•8E\fä‚ë  •8E\fasâ!–8E\fµÎ"†–8E\fÂ#W—8E\f :¶$Ê—8E\faD¯%=˜8E\f«É™&°˜8E\fc‚”'#™8E\f¡;‹(–™8E\f·3„) š8E\fÏHp*|š8E\fí±j+ïš8E\f6·X,b›8E\frQ-Õ›8E\f× =.Hœ8E\f+ý8/»œ8E\f½#0.�8E\f¯d 1¡�8E\fYN 2ž8E\f]3‡ž8E\fªýó3úž8E\f+Ëï4mŸ8E\fà¯Ü5àŸ8E\fr å6S 8E\fñ4Å7$¡8E\f£î¸8—¡8E\f\¯9 ¢8E\fz§:}¢9E\fkð¢9E\f:/ñc£9E\f–#íÖ£9E\föoâI¤9E\fx ͼ¤9E\f€ÐÉ/¥9E\f(Öµ¢¥9E\fWí¦9E\f�y›ˆ¦9E\fY²•û¦9E\fÐJ� n§9E\fvd{ á§9E\fWcu T¨9E\fiUm Ǩ9E\f~eX :©9E\füR­©9E\fá_J ª9E\f-4“ª9E\fþµ-«9E\frÑ$y«9E\f~`ì«9E\f†_¬9E\fshÒ¬9E\f0£êE­9E\f´2渭9E\f  Þ+®9E\fHPËž®9E\f42¿o¯9E\fXd°â¯9E\fUª³°9E\f'@Ÿ&±9E\fÚ,–÷±9E\f§†Œj²9E\f:v;³9E\f÷]n ´9E\fYod!´9E\f´W"Pµ9E\fCUL#õ9E\f¬:C$”¶9E\f~-%·9E\fsc &Ø·9E\f'K¸9E\fß* (¹9E\f}‘ø(�¹9E\f_(ú)`º9E\f…ð*Óº9E\f˜5Ø+¤»9E\fÔâÉ,¼9E\fãzÀ-è¼9E\f�„¹.[½9E\f1¨²/,¾9E\fÚû§0Ÿ¾9E\f3˜�1¿9E\fß‹ˆ2…¿9E\fCvƒ3ø¿9E\fÞ©x4ÉÀ9E\fi0n5<Á9E\fîÿT6¯Á9E\f•M7"Â9E\f@G8•Â9E\f®39Ã9E\f|/:{Ã9E\fß¼;îÃ:E\f”î~aÄ:E\fàˆiÔÄ:E\fáÞdGÅ:E\f%í[ºÅ:E\fŽMR-Æ:E\fД< Æ:E\fÒò3qÇ:E\ft)äÇ:E\f3ž WÈ:E\f>ó ÊÈ:E\fæÖü =É:E\fõ²ô °É:E\fKñ #Ê:E\f:õÙ –Ê:E\f¹MÒ Ë:E\fSúÉ|Ë:E\fªø¶ïË:E\f\^³bÌ:E\fgάÕÌ:E\faø•HÍ:E\fÖ‘»Í:E\fWF|.Î:E\f\¯v¡Î:E\fXJoÏ:E\fú£Y‡Ï:E\fªSúÏ:E\f<êMmÐ:E\f¨\8àÐ:E\f9Ò2SÑ:E\f`bÆÑ:E\fïb9Ò:E\fÏ ¬Ò:E\f‡ùÓ:E\f.ó’Ó:E\fàaë Ô:E\ftÕ!xÔ:E\f´Ò"ëÔ:E\fµ¸Æ#¼Õ:E\fAr¿$/Ö:E\f„f¦%×:E\furœ&1×:E\fêm“'DØ:E\fQ�†(·Ø:E\fG€)ˆÙ:E\fÞv*YÚ:E\fÈ©l+ÌÚ:E\fT,�Û:E\fz"K-Ü:E\f C.áÜ:E\f·L9/TÝ:E\f�–,0%Þ:E\fÌ1˜Þ:E\fŠî2iß:E\fS˜3Üß:E\f†·ÿ3­à:E\fp{ö4 á:E\fÖTÞ5ñá:E\fôÏÓ6dâ:E\fXöÊ75ã:E\fuQÁ8¨ã:E\fl*¶9yä:E\fz°ª:ìä:E\fW“;½å;E\f´“î0æ;E\fa{åç;E\f»NÝÒç;E\fÀÓEè;E\f gÌé;E\fŸ=´‰é;E\fŒ¯«Zê;E\fQ¤Íê;E\fêË™žë;E\fò‚ ì;E\füò{ „ì;E\f¯›t ÷ì;E\f{ðj jí;E\f(GS Ýí;E\f¯LPî;E\f‰fHÃî;E\f’&46ï;E\f—.©ï;E\fÇzð;E\f’Ëíð;E\f&Ô `ñ;E\f£�õÓñ;E\f¼ïFò;E\fS9ê¹ò;E\f[Ô,ó;E\fªÌŸó;E\fÙÄô;E\f�ᬅô;E\fæ¥øô;E\fê kõ;E\fÄäŠÞõ;E\fß„Qö;E\fág}Äö;E\f3Ru 7÷;E\fª’^!ª÷;E\f!LX"ø;E\f"ÕD#�ø;E\fãB$ù;E\fÙæ9%vù;E\fM"&éù;E\fw%'\ú;E\f•(Ïú;E\fÙtý(Bû;E\fÜ„÷)µû;E\fàíð*(ü;E\fÔ^Ú+›ü;E\f¼�Õ,ý;E\föÏ-�ý;E\fà½.ôý;E\fùwµ/gþ;E\fŽŸ08ÿ;E\f¤í•1«ÿ;E\f_ú21=E\fá 4¥1=E\ft(v2=E\fßé2=E\f‡º3=E\fg�-4=E\féêÿþ4=E\f·aéq5=E\f_"áB6=E\fV×7=E\f¹’φ7=E\fáÃÈW8=E\fÄ|µÊ8=E\f+¤=9=E\fr¼¡°9=E\fõ Žá9=E\fY²‰–:=E\f‚¨w ;=E\frts |;=E\f\`!ï;=E\fåÏT"b<=E\f¢†L#Õ<=E\fLšD$H==E\fdÊ-%»==E\f *&.>=E\f<`'¡>=E\fü‘(?=E\f?Œ)‡?=E\fÜü)ú?=E\f1kæ*m@=E\f€à+à@=E\fTêÚ,SA=E\fÈ5È-ÆA=E\f{­Ã.9B=E\f´°/¬B=E\f)ˆª0C=E\fp:–1’C=E\fÈs†2D=E\f‹Á‚3xD=E\f­un4ëD=E\fZ³h5^E=E\f®Ta6ÑE=E\fÂÙL7¢F=E\f©Í@8G=E\f+“99æG=E\fXþ2:YH=E\f×X;*I>E\f Aw�I>E\f‰hlÌJ>E\f�`?K>E\fs²W²K>E\fêQ%L>E\f5};˜L>E\fh>5 M>E\fÄæ-~M>E\fY ñM>E\fõX dN>E\fsl ×N>E\f^0õ JO>E\fLÎí ½O>E\fýÏÞ 0P>E\fóÚ× £P>E\fÒQ>E\f å½‰Q>E\f7ó·üQ>E\fòP¤oR>E\fh�âR>E\fà~†US>E\fÂü‚ÈS>E\fL|;T>E\fÙïe®T>E\fÏ8^!U>E\f1XV”U>E\f¬%@V>E\fÞÆ;zV>E\fk­4íV>E\f’¼#`W>E\fZØÓW>E\fQFX>E\fZÿûY>E\f˜\ðŠY>E\f¥-è ýY>E\fEfâ!pZ>E\f uÍ"ãZ>E\f–Ê#V[>E\fZbµ$É[>E\f\ƒ¯%<\>E\f6›¦&¯\>E\f¶!‹'"]>E\fûŒ‡(•]>E\fK¿u)^>E\f>ñt*{^>E\fág+î^>E\fµ‚^,a_>E\f³¢F-Ô_>E\fçß@.G`>E\f)pE\f r)0-a>E\flN$1 a>E\fÓ{2b>E\f4… 3†b>E\f· ÷3ùb>E\f«’ò4lc>E\f©ÓÜ5ßc>E\flèÓ6Rd>E\f1Í7Åd>E\féÆ88e>E\f}µ9«e>E\fK*¤:f>E\f8 —;‘f?E\f®¼ïg?E\fŠ=ëwg?E\f†wÕêg?E\fsbË]h?E\f“ÆÐh?E\f'¿Ci?E\f칫¶i?E\fL\¨)j?E\f¿¾–œj?E\fk$‘ k?E\fà$} ‚k?E\fà#w õk?E\fùa hl?E\f•t] Ûl?E\f}¿JNm?E\fÀ¯FÁm?E\f÷õ24n?E\fvT&§n?E\f¥£o?E\fæ��o?E\fi{p?E\fßÖùsp?E\f6Jõæp?E\feàYq?E\f‡³ÜÌq?E\f§É?r?E\f¶“Ųr?E\füа%s?E\f‰É­˜s?E\fH>š t?E\frÖ”~t?E\f¥€ñt/ conn= count=£op=ver=¤&E\fGè'&E\f2· k&E\fîe†"¯&E\fè7_$ó &E\f‡)&7"&E\fBÁþ'{#&E\f¼Ë)¿$&E\fÈŠ¡+&&E\fá’-G'&E\f‚Y¥/‹(&E\fÏС1Ï)&E\fëW›3+'E\f3g¢Ü=(E\f‚µ×'L(E\fK¼¬kM(E\f…t{¯N(E\fcáLóO(E\f¹�ÄP(E\fúð R(E\f#ܶ LS(E\fb®‡ �T(E\fi½BÔU(E\f–W(E\fÎ3ä\X(E\f m£ Y(E\f@ÃwäZ(E\f’ÞIµ[(E\f_uù\(E\fRÞí=^(E\fFà¹�_(E\fOŠÅ`(E\fÝÈ[! b(E\f…”4#Mc(E\f]¦%‘d(E\fÓkè&Õe(E\f’�§(g(E\f(Ó|*]h(E\f+QK,.i(E\fàF.rj)E\f·/�q)E\fžŠäØ)E\fšÛ›�)E\f˜q!`‚)E\f9§D#¤ƒ)E\fz %u„)E\f³uè&¹…)E\fŒä¥(ý†)E\fÜ~*Aˆ)E\f:Q,…‰)E\f5/.ÉŠ)E\fï/ Œ)E\fK}Ð1Q�)E\fß`¦3•Ž)E\fuáu5Ù�)E\fîO;7ª�)E\f‘D9î‘)E\fàº×:2“*E\f¦$v”*E\f'v⺕*E\fÿÍÊþ–*E\fU¨”B˜*E\f Ým†™*E\fèTE Êš*E\fÚM œ*E\fk:Ï ßœ*E\fÌ«#ž*E\fã/€gŸ*E\f¨;G« *E\fq5ï¡*E\fôýê3£*E\fEñw¤*E\fØJ‘»¥*E\fIÿ¦*E\fú",C¨*E\f’tòV©*E\f±Ä!Xª*E\f.4†#œ«*E\f¦Y)%à¬*E\f¤'$®*E\f©ðã(h¯*E\f”ð­*¬°*E\fk"2/Ö²+E\f¯z”Á+E\f/3ØÂ+E\fQÄ+E\f‰ÛíÄ+E\fQI™1Æ+E\f„iuÇ+E\f4A¹È+E\f9¤ýÉ+E\f—GíAË+E\fˆë©!…Ì+E\fàƒ#ÉÍ+E\fŒÉS% Ï+E\fÆ¥'QÐ,E\fÚlà œÞ,E\fh$° àß,E\fy…i $á,E\f(éNhâ,E\f¡¬ã,E\fÔìåðä,E\fœì°4æ,E\f¥xxç,E\fJIè,E\fÖ�é,E\fFÁâÑê,E\f™µ°ì,E\f‹:“Yí,E\f» Z!�î,E\fç· #áï,E\fÖ ë$%ñ,E\fŽSÁ&iò,E\f¸{'Çò-E\fv$^ -E\fN6 V-E\fŠÒö š-E\fÌKÒÞ-E\f�¶»•-E\fz^˜/à-E\f!¾b1$-E\fu2,3h-E\f5�ï4¬-E\fZÇ6ð-E\f•l“84-E\fàšs:x.E\f带¼.E\fã†r.E\fkyVD .E\fÕ}!.E\f)ÀåY".E\fäS¢ �#.E\f÷~ á$.E\fµŒ\ %&.E\fuè.i'.E\fˆ ­(.E\f˜ð: ).E\fÐ9/V7.E\f½×0š8.E\f¼ÿš2Þ9.E\f£yy4";.E\fŒQ6f<.E\f\=48ª=.E\f™›ü9î>/E\fŸ*;2@/E\fk„ëéA/E\f(¶É 4P/E\fÑ}"xQ/E\fêÁW$¼R/E\fÎÿ%�S/E\f-ìÙ'ÑT/E\fÄš´)V/E\fO}}+YW/E\fçÊP-�X/E\f º/áY/E\frߨ0%[/E\fÒ0¤2i\/E\ftBx4:]/E\fgÔ56~^/E\f†ø8Â_/E\f¡íñ9a/E\fü™¯:×a0E\fCsã"p0E\fÆË¡fq0E\f×åƒ ªr0E\fy×_"îs0E\fäþ:$2u0E\f�—&vv0E\f £Ü'ºw0E\fá»±)þx0E\fIíz+Bz0E\fMT-†{0E\fÎB/W|0E\f°M×0›}0E\f È©2ß~0E\fÁJŠ4#€0E\fòòU6g�0E\fD´:8«‚0E\fr»:ïƒ1E\fåÔC3…1E\f:žùw†1E\f{ƒËH‡1E\fø¦šŒˆ1E\f©%nЉ1E\f|œ. ‹1E\f c XŒ1E\f©åÅ œ�1E\fr™àŽ1E\fØ¢c$�1E\f<Ã/h‘1E\f>9’1E\fBœÈ}“1E\fº%‰Á”1E\fMüR–1E\f h2I—1E\f;Jü�˜1E\fg­ÉÑ™1E\fËzœ ›1E\fÃG{"Yœ1E\fl‡A$��1E\fÙå&nž1E\f­ø'²Ÿ1E\fd.»)ö 1E\f Éì*:¢2E\f�ë* …°2E\fÄuóɱ2E\fDÏ ³2E\fë  Q´2E\f9+o"µ2E\f«ÂQf¶2E\f/"ª·2E\fÊžçî¸2E\f ¶2º2E\fxv»2E\fÆ.Lº¼2E\f1ù!þ½2E\fñ¡ß"B¿2E\fŠl‰$À2E\f½Ói&WÁ2E\f¼T(›Â2E\f6:-*ßÃ2E\fãj,#Å2E\fâx¿-gÆ2E\fÑ�’/«Ç2E\fÜÜh1ïÈ2E\fä´F33Ê2E\f¿À!5wË2E\f9Þ6»Ì2E\f ±8ŒÍ2E\f\Š:ÐÎ3E\f íÁÐ3E\f|&ˆXÑ3E\fd»UœÒ3E\fÆ`+àÓ3E\f:Ðò$Õ3E\f±¦ hÖ3E\fÊY ¬×3E\f‘‘_ ðØ3E\fBs*ÁÙ3E\f ÍúÛ3E\f¶F¿IÜ3E\f¬m•�Ý3E\fù+iÑÞ3E\fÕtGà3E\fEpYá3E\fæ�â3E\fµ5¸áã3E\f,•‚%å3E\f�^J!öå3E\fs�#:ç3E\fqç$~è3E\f©µ©&Âé3E\fÇf‚(ë3E\fÙ»B*Jì3E\fƒR,Ží3E\f¥îÖ-Òî3E\f 4°/ð3E\fó�‰1çð3E\fãö\3+ò3E\fb65oó3E\fD6ô6³ô3E\f†h«8÷õ3E\fñÙ|:;÷4E\fž'¨ø4E\fË®vÃù4E\f+FTû4E\f(vØû4E\f5+Þý4E\fzg� `þ4E\f´äe ¤ÿ4E\fÕáL è4E\fö¤ ,4E\f6ïÞp4E\f2d½´4E\f<æzø4E\fQS]É4E\f¸Ð# 4E\f¸/ÿQ 4E\f>ÆÑ• 4E\fä™Ù 4E\fä£] 4E\fŸ˜)!a4E\fëÌ #¥4E\fª³Ô$é4E\fÊñ&º4E\f]Ý\(þ4E\fäf=*B4E\fÅ ,†4E\føãá-Ê4E\fV�/4E\f¶¶y1R4E\f¸|D3–4E\fP5Ú4E\f,6é64E\fc„·8ï4E\fšqŽ:35E\f«Í·w 5E\fua�»!5E\f–©lÿ"5E\fä:C$5E\f{E‡%5E\f.ÍÜ Ë&5E\flѤ (5E\f*w‚ S)5E\fÔÉK—*5E\fâh+5E\fU¨Ô¬,5E\fåÍ¥ð-5E\f"šu4/5E\fQx05E\f导15E\fº5ù35E\f ·ÄD45E\fÌÊ­ˆ55E\fßìw!Ì65E\fVTF#�75E\fdÞ!%á85E\f�óè&%:5E\ff.¿(i;5E\fÒ ‰*­<5E\fÃaX,ñ=5E\f�t..5?5E\f\&¸.@5E\fBŒÁ7oD6E\fÒÐvaQ6E\fÔEH4¬_6E\f-ßã5ð`7E\fe;o7E\fK(ép7E\f¯°Ãq7E\fã°�s7E\fTm\Øs7E\fß,!u7E\fè¿ü"`v7E\fÓqÀ$¤w7E\fl{š&èx7E\fœ^(,z7E\fØ}+*p{7E\fÝu,´|7E\f¤^Ó-ø}7E\fÉú«/ 7E\fò�{1 €7E\f¼ÕŽ1k€8E\fÒ4Jlˆ8E\fðjç"·–8E\f£åè6„ 9E\fœ'Ï®9E\féöÞ°9E\f)€µW±9E\fzÕ™›²9E\f¤d l³9E\f-y+"°´9E\fýt$ôµ9E\f«Ó%8·9E\fîào'|¸9E\fæ5M)À¹9E\fPU&+»9E\fDçå,H¼9E\f¦^Ë.Œ½9E\f˜@þ3)À:E\f)çOÑÆ:E\fr-&#Õ:E\fÔ]â$`Ö:E\f¼&¤×:E\f©…Š(èØ:E\f±f*¹Ù:E\fÛù7,ýÚ:E\fe.AÜ:E\fæBë/…Ý:E\fèw¶1ÉÞ:E\f/TŒ3 à:E\f{m5Qá:E\fq.87•â:E\fÚ9Ùã:E\fA�Ý:å;E\f×Faæ;E\f£¨Ì2ç;E\f6œvè;E\f5€ºé;E\fIþê;E\f Ä›Mð;E\f@Tb0˜þ;E\fÚK2Üÿ;E\f¯‰4 ;E\f…rä5d;E\f<àÚ65*=E\f¡i�‚+=E\f€3 Æ,=E\f%Pû .=E\f|ïÉ N/=E\f–³’0=E\f¥„Ö1=E\fþUJ3=E\fVƒ^4=E\fÉZò¢5=E\f‰ÿ²s6=E\fŠ—O·7=E\f]–7F=E\f—hò8FG=E\f9¾¾:ŠH>E\f%ÅïÎI>E\fÒ­ú,J>E\f”!šwX& conn=op= topic=/rosoutú$callerid=/record_1717323045885203753 latching=1'md5sum=acffd30cd6b6de30f120938c17c593fbjmessage_definition=## ## Severity level constants ## byte DEBUG=1 #debug level byte INFO=2 #general level byte WARN=4 #warning level byte ERROR=8 #error level byte FATAL=16 #fatal/critical level ## ## Fields ## Header header byte level string name # name of the node string msg # message string file # file the message came from string function # function the message came from uint32 line # line the message came from string[] topics # topic names that the node publishes ================================================================================ MSG: std_msgs/Header # Standard metadata for higher-level stamped data types. # This is generally used to communicate timestamped data # in a particular coordinate frame. # # sequence ID: consecutively increasing ID uint32 seq #Two-integer timestamp that is expressed as: # * stamp.sec: seconds (stamp_secs) since epoch (in Python the variable is called 'secs') # * stamp.nsec: nanoseconds since stamp_secs (in Python the variable is called 'nsecs') # time-handling sugar is provided by the client library time stamp #Frame this data is associated with string frame_id topic=/rosouttype=rosgraph_msgs/Log& conn=op= topic=/rosoutécallerid=/turtlesim latching=1'md5sum=acffd30cd6b6de30f120938c17c593fbjmessage_definition=## ## Severity level constants ## byte DEBUG=1 #debug level byte INFO=2 #general level byte WARN=4 #warning level byte ERROR=8 #error level byte FATAL=16 #fatal/critical level ## ## Fields ## Header header byte level string name # name of the node string msg # message string file # file the message came from string function # function the message came from uint32 line # line the message came from string[] topics # topic names that the node publishes ================================================================================ MSG: std_msgs/Header # Standard metadata for higher-level stamped data types. # This is generally used to communicate timestamped data # in a particular coordinate frame. # # sequence ID: consecutively increasing ID uint32 seq #Two-integer timestamp that is expressed as: # * stamp.sec: seconds (stamp_secs) since epoch (in Python the variable is called 'secs') # * stamp.nsec: nanoseconds since stamp_secs (in Python the variable is called 'nsecs') # time-handling sugar is provided by the client library time stamp #Frame this data is associated with string frame_id topic=/rosouttype=rosgraph_msgs/Log, conn=op=topic=/turtle1/poseécallerid=/turtlesim latching=0'md5sum=863b248d5016ca62ea2e895ae5265cf9gmessage_definition=float32 x float32 y float32 theta float32 linear_velocity float32 angular_velocity topic=/turtle1/posetype=turtlesim/Pose4 conn=op=topic=/turtle1/color_sensor¶callerid=/turtlesim latching=0'md5sum=353891e354491c51aabe32df673fb446+message_definition=uint8 r uint8 g uint8 b topic=/turtle1/color_sensortype=turtlesim/Color/ conn=op=topic=/turtle1/cmd_velcallerid=/teleop_turtle latching=0'md5sum=9f195f881246fdfa2798d1d3eebca84armessage_definition=# This expresses velocity in free space broken into its linear and angular parts. Vector3 linear Vector3 angular ================================================================================ MSG: geometry_msgs/Vector3 # This represents a vector in free space. # It is only meant to represent a direction. Therefore, it does not # make sense to apply a translation to it (e.g., when applying a # generic rigid transformation to a Vector3, tf2 will only apply the # rotation). If you want your data to be translatable too, use the # geometry_msgs/Point message instead. float64 x float64 y float64 z topic=/turtle1/cmd_veltype=geometry_msgs/Twistdchunk_pos= count=end_time=?E\f¥€op=start_time=%E\fúŸ7ver=(00£someipy-2.1.2/example_apps/send_events_tcp.py000066400000000000000000000072321513043235100214150ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( TransportLayerProtocol, ServiceBuilder, EventGroup, connect_to_someipy_daemon, ServerServiceInstance, Event, ) from someipy.someipy_logging import set_someipy_log_level from someipy.serialization import Uint8, Uint64, Float32 from temperature_msg import TemparatureMsg DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 # dec 4660 SAMPLE_INSTANCE_ID = 0x5678 # dec 22136 SAMPLE_EVENTGROUP_ID = 0x0321 # dec 801 SAMPLE_EVENT_ID = 0x0123 # dec 291 async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.TCP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) # For sending events use a ServerServiceInstance service_instance_temperature = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) # After constructing a ServerServiceInstances the start_offer method has to be called. This will start an internal timer, # which will periodically send Offer service entries with a period of "cyclic_offer_delay_ms" which has been passed above print("Start offering service..") await service_instance_temperature.start_offer() tmp_msg = TemparatureMsg() # Reminder: Do NOT use "tmp_msg.version.major = 1". Always use the provided classes in someipy like Uint8, # so that the data can be properly serialized. Python literals won't be serialized properly tmp_msg.version.major = Uint8(1) tmp_msg.version.minor = Uint8(0) tmp_msg.measurements.data[0] = Float32(20.0) tmp_msg.measurements.data[1] = Float32(21.0) tmp_msg.measurements.data[2] = Float32(22.0) tmp_msg.measurements.data[3] = Float32(23.0) try: # Either cyclically send events in an endless loop.. while True: await asyncio.sleep(1) tmp_msg.timestamp = Uint64(tmp_msg.timestamp.value + 1) payload = tmp_msg.serialize() service_instance_temperature.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) # .. or in case your app is waiting for external events, use await asyncio.Future() to # keep the task alive # await asyncio.Future() except asyncio.CancelledError: print("Stop offering service..") await service_instance_temperature.stop_offer() finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/send_events_udp.py000066400000000000000000000072311513043235100214160ustar00rootroot00000000000000import asyncio import logging import sys from someipy import ( TransportLayerProtocol, ServiceBuilder, EventGroup, connect_to_someipy_daemon, ServerServiceInstance, Event, ) from someipy.someipy_logging import set_someipy_log_level from someipy.serialization import Uint8, Uint64, Float32 from temperature_msg import TemparatureMsg DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 # dec 4660 SAMPLE_INSTANCE_ID = 0x5678 # dec 22136 SAMPLE_EVENTGROUP_ID = 0x0321 # dec 801 SAMPLE_EVENT_ID = 0x0123 # dec 291 async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) # Get interface ip to use from command line argument (--interface_ip) or use default interface_ip = DEFAULT_INTERFACE_IP for i, arg in enumerate(sys.argv): if arg == "--interface_ip": if i + 1 < len(sys.argv): interface_ip = sys.argv[i + 1] break someipy_daemon = await connect_to_someipy_daemon() # For Windows use: # someipy_daemon = await connect_to_someipy_daemon( # {"use_tcp": True, "tcp_host": interface_ip, "tcp_port": 30500} # ) temperature_event = Event(id=SAMPLE_EVENT_ID, protocol=TransportLayerProtocol.UDP) temperature_eventgroup = EventGroup( id=SAMPLE_EVENTGROUP_ID, events=[temperature_event] ) temperature_service = ( ServiceBuilder() .with_service_id(SAMPLE_SERVICE_ID) .with_major_version(1) .with_eventgroup(temperature_eventgroup) .build() ) # For sending events use a ServerServiceInstance service_instance_temperature = ServerServiceInstance( daemon=someipy_daemon, service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, endpoint_ip=interface_ip, endpoint_port=3000, ttl=5, cyclic_offer_delay_ms=2000, ) # After constructing a ServerServiceInstances the start_offer method has to be called. This will start an internal timer, # which will periodically send Offer service entries with a period of "cyclic_offer_delay_ms" which has been passed above print("Start offering service..") await service_instance_temperature.start_offer() tmp_msg = TemparatureMsg() # Reminder: Do NOT use "tmp_msg.version.major = 1". Always use the provided classes in someipy like Uint8, # so that the data can be properly serialized. Python literals won't be serialized properly tmp_msg.version.major = Uint8(1) tmp_msg.version.minor = Uint8(0) tmp_msg.measurements.data[0] = Float32(20.0) tmp_msg.measurements.data[1] = Float32(21.0) tmp_msg.measurements.data[2] = Float32(22.0) tmp_msg.measurements.data[3] = Float32(23.0) try: # Either cyclically send events in an endless loop.. while True: await asyncio.sleep(1) tmp_msg.timestamp = Uint64(tmp_msg.timestamp.value + 1) payload = tmp_msg.serialize() service_instance_temperature.send_event( SAMPLE_EVENTGROUP_ID, SAMPLE_EVENT_ID, payload ) # .. or in case your app is waiting for external events, use await asyncio.Future() to # keep the task alive # await asyncio.Future() except asyncio.CancelledError: print("Stop offering service..") await service_instance_temperature.stop_offer() finally: print("Disconnect from daemon..") await someipy_daemon.disconnect_from_daemon() print("End main task..") if __name__ == "__main__": asyncio.run(main()) someipy-2.1.2/example_apps/temperature_msg.py000066400000000000000000000065061513043235100214400ustar00rootroot00000000000000from dataclasses import dataclass from someipy.serialization import ( SomeIpPayload, SomeIpFixedSizeArray, Uint8, Uint64, Float32, ) # With someipy it's possible to either send and receive payloads unserialized simply as bytes-objects. This is useful # when you don't care about the content, e.g. reading binary data and simply sending it. # However, you can also define the SOME/IP payload structure directly as Python classes and serialize your Python object # to a bytes-payload which can be sent. You can also deserialize a received bytes-object into your defined # Python object structure. # In this example we define a "temperature message" that consists of another SOME/IP struct and of a fixed size # SOME/IP array @dataclass class Version(SomeIpPayload): major: Uint8 minor: Uint8 def __init__(self): # Ensure that you always write an __init__ function for each struct so that the variables # are instance variables owned by each object self.major = Uint8() self.minor = Uint8() # Reminder: Do NOT write "self.major = 1". Always use the provided classes in someipy like Uint8, # so that the data can be propery serialized. Python literals won't be serialized properly # Instead use self.major = Uint8(1) @dataclass class TemparatureMsg(SomeIpPayload): # Always define payloads with the @dataclass decorator. This leads to the __eq__ being # generated which makes it easy to compare the content of two messages. # For defining a payload struct simply derive from the SomeIpPayload class. This will ensure # the Python object can be serialized and deserialized and supports e.g. len() calls which # will return the length of the payload in bytes version: Version timestamp: Uint64 measurements: SomeIpFixedSizeArray def __init__(self): self.version = Version() self.timestamp = Uint64() self.measurements = SomeIpFixedSizeArray(Float32, 4) # Arrays can be modelled using the SomeIpFixedSizeArray class which gets the type that # the array shall hold (e.g. Float32) and the number of elements # The len(self.measurements) call will return the number of bytes (4*len(Float32)). # If you need to now the number of elements use len(self.measurements.data). # Simple example how to instantiate a payload, change values, serialize and deserialize if __name__ == "__main__": tmp_msg = TemparatureMsg() tmp_msg.version.major = Uint8(2) tmp_msg.version.minor = Uint8(0) # Reminder: Do NOT use "tmp_msg.version.major = 2". Always use the provided classes by someipy like Uint8, # so that the data can be propery serialized. Python literals won't be serialized into SOME/IP payload. tmp_msg.timestamp = Uint64(100) tmp_msg.measurements.data[0] = Float32(20.0) tmp_msg.measurements.data[1] = Float32(20.1) tmp_msg.measurements.data[2] = Float32(20.2) tmp_msg.measurements.data[3] = Float32(20.3) # The @dataclass decorator will also generate a __repr__ function print(tmp_msg) # serialize() will return a bytes object output = tmp_msg.serialize() print(output.hex()) # Create a new TemperatureMsg from the serialized bytes tmp_msg_again = TemparatureMsg().deserialize(output) print(tmp_msg_again) assert tmp_msg_again == tmp_msg someipy-2.1.2/integration_tests/000077500000000000000000000000001513043235100167435ustar00rootroot00000000000000someipy-2.1.2/integration_tests/CMakeLists.txt000066400000000000000000000021231513043235100215010ustar00rootroot00000000000000cmake_minimum_required (VERSION 3.13) project(someipy_test_apps) set(CMAKE_BUILD_TYPE Debug) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") find_package(vsomeip3 CONFIG REQUIRED) set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install") function(create_test_target target_name) add_executable(${target_name} ${target_name}/${target_name}.cpp) target_link_libraries(${target_name} ${VSOMEIP_LIBRARIES} pthread) install(TARGETS ${target_name} RUNTIME DESTINATION ${target_name}) file(GLOB ADDITIONAL_FILES "${CMAKE_SOURCE_DIR}/${target_name}/*.json" "${CMAKE_SOURCE_DIR}/${target_name}/*.sh") install(FILES ${ADDITIONAL_FILES} DESTINATION ${target_name}) endfunction() # The same app can be used for UDP and TCP for the "send_events" example app create_test_target("send_events") create_test_target("receive_events_udp") create_test_target("receive_events_tcp") create_test_target("offer_method_udp") create_test_target("offer_method_tcp") create_test_target("call_method_udp") create_test_target("call_method_tcp") create_test_target("offer_multiple_services")someipy-2.1.2/integration_tests/README.md000066400000000000000000000015551513043235100202300ustar00rootroot00000000000000# Integration Test Applications The integration test applications use the vsomeip library in order to stimulate the someipy applications. Each test application has a corresponding someipy example application, which are started together. The test applications can be either started manually or run automatically using the scripts `run_all.py` in `automated_tests`. The script will launch each pair of applications (a someipy app and a vsomeip app). After running both applications, the script will evaluate the logfiles. ## Build Test Applications using CMake ```bash rm -rf build install && mkdir -p build && cd build && cmake .. && make && make install && cd .. ``` ## Setup Python Pip Package from Source ```bash python3 -m pip install -e . ``` ### Network Setup Linux ```bash sudo ip addr add 127.0.0.2/8 dev lo sudo ip addr add 224.224.224.245 dev lo autojoin ``` someipy-2.1.2/integration_tests/automated_tests/000077500000000000000000000000001513043235100221505ustar00rootroot00000000000000someipy-2.1.2/integration_tests/automated_tests/call_method_tcp.py000066400000000000000000000030121513043235100256370ustar00rootroot00000000000000from test_base import TestBase class TestCallMethodTcp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.2"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/call_method_tcp/call_method_tcp" ] self.someipy_app = [ "python3", f"{repository}/example_apps/call_method_tcp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/call_method_tcp/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: method_calls = 0 responses = 0 for l in self.output_someipy_app: if "Received result for method" in l: responses += 1 if "Trying to call method " in l: method_calls += 1 print(f"Method calls: {method_calls}. Responses: {responses}") difference = method_calls - responses tolerance = max(0.1 * method_calls, 1) if abs(difference) <= tolerance and method_calls > 0 and responses > 0: return True else: print(f"Method calls: {method_calls}. Responses: {responses}") self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/call_method_udp.py000066400000000000000000000030111513043235100256400ustar00rootroot00000000000000from test_base import TestBase class TestCallMethodUdp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/call_method_udp/call_method_udp" ] self.someipy_app = [ "python3", f"{repository}/example_apps/call_method_udp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/call_method_udp/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: method_calls = 0 responses = 0 for l in self.output_someipy_app: if "Received result for method" in l: responses += 1 if "Trying to call method" in l: method_calls += 1 print(f"Method calls: {method_calls}. Responses: {responses}") difference = method_calls - responses tolerance = max(0.1 * method_calls, 1) if abs(difference) <= tolerance and method_calls > 0 and responses > 0: return True else: print(f"Method calls: {method_calls}. Responses: {responses}") self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/offer_method_tcp.py000066400000000000000000000030301513043235100260250ustar00rootroot00000000000000from test_base import TestBase class TestOfferMethodTcp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.2"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/offer_method_tcp/offer_method_tcp" ] self.someipy_app = [ "python3", f"{repository}/example_apps/offer_method_tcp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/offer_method_tcp/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: method_calls = 0 responses = 0 for l in self.output_vsomeip_app: if "Received a response from Service" in l: responses += 1 if "sent a request to Service" in l: method_calls += 1 print(f"Method calls: {method_calls}. Responses: {responses}") difference = method_calls - responses tolerance = max(0.1 * method_calls, 1) if abs(difference) <= tolerance and method_calls > 0 and responses > 0: return True else: print(f"Method calls: {method_calls}. Responses: {responses}") self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/offer_method_udp.py000066400000000000000000000027151513043235100260400ustar00rootroot00000000000000from test_base import TestBase class TestOfferMethodUdp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/offer_method_udp/offer_method_udp" ] self.someipy_app = [ "python3", f"{repository}/example_apps/offer_method_udp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/offer_method_udp/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: method_calls = 0 responses = 0 for l in self.output_vsomeip_app: if "Received a response from Service" in l: responses += 1 if "sent a request to Service" in l: method_calls += 1 print(f"Method calls: {method_calls}. Responses: {responses}") difference = method_calls - responses tolerance = max(0.1 * method_calls, 1) if abs(difference) <= tolerance and method_calls > 0 and responses > 0: return True else: self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/offer_multiple_services.py000066400000000000000000000032351513043235100274440ustar00rootroot00000000000000from test_base import TestBase class TestOfferMultipleServices(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/offer_multiple_services/offer_multiple_services" ] self.someipy_app = [ "python3", f"{repository}/example_apps/offer_multiple_services.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/offer_multiple_services/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: sent_events = 0 received_events = 0 for l in self.output_someipy_app: if "Transmitting message: {'type': 'SendEventRequest'" in l: sent_events += 1 for l in self.output_vsomeip_app: if "received a notification for event" in l: received_events += 1 print(f"Received events: {received_events}. Sent events: {sent_events}") difference_sent_received = sent_events - received_events tolerance = max(0.1 * sent_events, 1) if ( abs(difference_sent_received) <= tolerance and sent_events > 0 and received_events > 0 ): return True else: self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/receive_events_tcp.py000066400000000000000000000034231513043235100264000ustar00rootroot00000000000000from test_base import TestBase import re class TestReceiveEventsTcp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/receive_events_tcp/receive_events_tcp" ] self.someipy_app = [ "python3", f"{repository}/example_apps/receive_events_tcp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/receive_events_tcp/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: sent_events = 0 received_events = 0 for l in self.output_someipy_app: received_bytes_pattern = r"Received (\d+) bytes" match = re.search(received_bytes_pattern, l) if match: received_events += 1 for l in self.output_vsomeip_app: if "Setting event" in l: sent_events += 1 print(f"Received events: {received_events}. Sent events: {sent_events}") difference_sent_received = sent_events - received_events tolerance = max(0.1 * sent_events, 1) if ( abs(difference_sent_received) <= tolerance and sent_events > 0 and received_events > 0 ): return True else: print(f"Received events: {received_events}. Sent events: {sent_events}") self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/receive_events_udp.py000066400000000000000000000034231513043235100264020ustar00rootroot00000000000000from test_base import TestBase import re class TestReceiveEventsUdp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/receive_events_udp/receive_events_udp" ] self.someipy_app = [ "python3", f"{repository}/example_apps/receive_events_udp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = f"{repository}/integration_tests/install/receive_events_udp/vsomeip-client.json" self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: sent_events = 0 received_events = 0 for l in self.output_someipy_app: received_bytes_pattern = r"Received (\d+) bytes" match = re.search(received_bytes_pattern, l) if match: received_events += 1 for l in self.output_vsomeip_app: if "Setting event" in l: sent_events += 1 print(f"Received events: {received_events}. Sent events: {sent_events}") difference_sent_received = sent_events - received_events tolerance = max(0.1 * sent_events, 1) if ( abs(difference_sent_received) <= tolerance and sent_events > 0 and received_events > 0 ): return True else: print(f"Received events: {received_events}. Sent events: {sent_events}") self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/run_all.py000066400000000000000000000035061513043235100241620ustar00rootroot00000000000000import os import sys import time from send_events_udp import TestSendEventsUdp from send_events_tcp import TestSendEventsTcp from receive_events_udp import TestReceiveEventsUdp from receive_events_tcp import TestReceiveEventsTcp from call_method_udp import TestCallMethodUdp from call_method_tcp import TestCallMethodTcp from offer_method_udp import TestOfferMethodUdp from offer_method_tcp import TestOfferMethodTcp from offer_multiple_services import TestOfferMultipleServices vsomeip_library_path = "/home/christian/projects/someip/vsomeip_install/lib/" current_file_path = os.path.abspath(__file__) repository = os.path.dirname(os.path.dirname(os.path.dirname(current_file_path))) test_durations = 60 # duration of each test in seconds # Get test_durations as argument if len(sys.argv) > 1: test_durations = int(sys.argv[1]) print(f"Test duration: {test_durations} seconds") tests = { "send_events_udp": TestSendEventsUdp, "send_events_tcp": TestSendEventsTcp, "receive_events_udp": TestReceiveEventsUdp, "receive_events_tcp": TestReceiveEventsTcp, "call_method_udp": TestCallMethodUdp, "call_method_tcp": TestCallMethodTcp, "offer_method_udp": TestOfferMethodUdp, "offer_method_tcp": TestOfferMethodTcp, "offer_multiple_services": TestOfferMultipleServices, } test_summary = {} for test_name, test_class in tests.items(): print(f"Starting test: {test_name}") test = test_class( repository, ld_library_path=vsomeip_library_path, interface_ip="127.0.0.2" ) test.run(test_durations) success = test.evaluate() print(f"{test_name}: {'Success' if success else 'Failure'}\n---\n") test_summary[test_name] = success time.sleep(1) print("\n\nTest summary:") for test_name, success in test_summary.items(): print(f"{test_name}:\t\t{'Success' if success else 'Failure'}") someipy-2.1.2/integration_tests/automated_tests/send_events_tcp.py000066400000000000000000000032011513043235100257010ustar00rootroot00000000000000from test_base import TestBase class TestSendEventsTcp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/send_events/send_events" ] self.someipy_app = [ "python3", f"{repository}/example_apps/send_events_tcp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = ( f"{repository}/integration_tests/install/send_events/vsomeip-client.json" ) self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: sent_events = 0 received_events = 0 for l in self.output_someipy_app: if "Transmitting message: {'type': 'SendEventRequest'" in l: sent_events += 1 for l in self.output_vsomeip_app: if "received a notification for event" in l: received_events += 1 print(f"Received events: {received_events}. Sent events: {sent_events}") difference_sent_received = sent_events - received_events tolerance = max(0.1 * sent_events, 1) if ( abs(difference_sent_received) <= tolerance and sent_events > 0 and received_events > 0 ): return True else: self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/send_events_udp.py000066400000000000000000000032021513043235100257040ustar00rootroot00000000000000from test_base import TestBase class TestSendEventsUdp(TestBase): def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): super().__init__() self.ld_library_path = ld_library_path self.vsomeip_app = [ f"{repository}/integration_tests/install/send_events/send_events" ] self.someipy_app = [ "python3", f"{repository}/example_apps/send_events_udp.py", f"--interface_ip", f"{interface_ip}", ] self.vsomeip_config = ( f"{repository}/integration_tests/install/send_events/vsomeip-client.json" ) self.someipydaemon_app = [ "python3", f"{repository}/src/someipy/someipyd.py", "--config", f"{repository}/src/someipy/someipyd.json", ] def evaluate(self) -> bool: sent_events = 0 received_events = 0 for l in self.output_someipy_app: if "Transmitting message: {'type': 'SendEventRequest'" in l: sent_events += 1 for l in self.output_vsomeip_app: if "received a notification for event" in l: received_events += 1 print(f"Received events: {received_events}. Sent events: {sent_events}") difference_sent_received = sent_events - received_events tolerance = max(0.1 * sent_events, 1) if ( abs(difference_sent_received) <= tolerance and sent_events > 0 and received_events > 0 ): return True else: self.print_outputs() return False someipy-2.1.2/integration_tests/automated_tests/test_base.py000066400000000000000000000067441513043235100245060ustar00rootroot00000000000000import subprocess import time import fcntl import os import signal import threading import queue import select from abc import abstractmethod class TestBase: def __init__(self): self.ld_library_path = None self.vsomeip_app = None self.vsomeip_config = None self.someipy_app = None self.someipydaemon_app = "someipyd" self.output_daemon = None self.output_someipy_app = None self.output_vsomeip_app = None @abstractmethod def evaluate(self) -> bool: pass def run(self, duration=5): env = dict(os.environ, VSOMEIP_CONFIGURATION=self.vsomeip_config) if self.ld_library_path is not None: env["LD_LIBRARY_PATH"] = self.ld_library_path thread_daemon, output_queue_daemon = self.run_in_thread( self.someipydaemon_app, duration + 1.0, env ) thread_vsomeip, output_queue_vsomeip = self.run_in_thread( self.vsomeip_app, duration, env ) thread_python, output_queue_python = self.run_in_thread( self.someipy_app, duration, env ) thread_daemon.start() thread_vsomeip.start() thread_python.start() thread_vsomeip.join() thread_python.join() thread_daemon.join() self.output_vsomeip_app = list(output_queue_vsomeip.queue) self.output_someipy_app = list(output_queue_python.queue) self.output_daemon = list(output_queue_daemon.queue) def start_process(self, command, output_queue, env, timeout=5): """Starts a subprocess and puts its stdout lines in a queue.""" process = subprocess.Popen( command, shell=False, stdout=subprocess.PIPE, env=env ) # Set non-blocking mode for stdout fcntl.fcntl(process.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) # Collect output for timeout seconds start_time = time.time() while time.time() - start_time < timeout: readable, _, _ = select.select( [process.stdout], [], [], 0.1 ) # Non-blocking read with timeout if readable: line = process.stdout.readline().decode().strip() if line: output_queue.put(line) process.send_signal(signal.SIGINT) # Collect output for 1 seconds after sending the sigint start_time = time.time() while time.time() - start_time < 1: readable, _, _ = select.select( [process.stdout], [], [], 0.1 ) # Non-blocking read with timeout if readable: line = process.stdout.readline().decode().strip() if line: output_queue.put(line) else: break # No more output available process.wait() def run_in_thread(self, command, duration, env): output_queue = queue.Queue() thread = threading.Thread( target=TestBase.start_process, args=(self, command, output_queue, env, duration), ) return thread, output_queue def print_outputs(self): print("-------- Output from someipy app --------") for l in self.output_someipy_app: print(l) print("-------- Output from vsomeip app --------") for l in self.output_vsomeip_app: print(l) print("-------- Output from someipy daemon --------") for l in self.output_daemon: print(l) someipy-2.1.2/integration_tests/build_test_apps.sh000077500000000000000000000001301513043235100224550ustar00rootroot00000000000000#!/bin/sh rm -rf build install mkdir -p build cd build cmake .. make make install cd ..someipy-2.1.2/integration_tests/call_method_tcp/000077500000000000000000000000001513043235100220645ustar00rootroot00000000000000someipy-2.1.2/integration_tests/call_method_tcp/call_method_tcp.cpp000066400000000000000000000115261513043235100257160ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_METHOD_ID 0x0123 class service_sample { public: service_sample(bool _use_static_routing) : app_(vsomeip::runtime::get()->create_application("Hello")), is_registered_(false), use_static_routing_(_use_static_routing), blocked_(false), running_(true), offer_thread_(std::bind(&service_sample::run, this)) { } bool init() { std::lock_guard its_lock(mutex_); if (!app_->init()) { std::cerr << "Couldn't initialize application" << std::endl; return false; } app_->register_state_handler( std::bind(&service_sample::on_state, this, std::placeholders::_1)); app_->register_message_handler( SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&service_sample::on_message, this, std::placeholders::_1)); return true; } void start() { app_->start(); } void stop() { running_ = false; blocked_ = true; app_->clear_all_handler(); stop_offer(); condition_.notify_one(); if (std::this_thread::get_id() != offer_thread_.get_id()) { if (offer_thread_.joinable()) { offer_thread_.join(); } } else { offer_thread_.detach(); } app_->stop(); } void offer() { app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 0x1); } void stop_offer() { app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 0x1); } void on_state(vsomeip::state_type_e _state) { std::cout << "Application " << app_->get_name() << " is " << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : "deregistered.") << std::endl; if (_state == vsomeip::state_type_e::ST_REGISTERED) { if (!is_registered_) { is_registered_ = true; blocked_ = true; condition_.notify_one(); } } else { is_registered_ = false; } } void on_message(const std::shared_ptr &_request) { // Log the current time. auto now = std::chrono::system_clock::now(); auto now_time_t = std::chrono::system_clock::to_time_t(now); auto now_ms = std::chrono::duration_cast( now.time_since_epoch()).count(); auto now_ms_remainder = now_ms % 1000; auto now_tm = std::localtime(&now_time_t); std::stringstream now_ss; now_ss << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << "." << std::setfill('0') << std::setw(3) << now_ms_remainder; std::cout << now_ss.str() << " Received a message with Client/Session [" << std::setfill('0') << std::hex << std::setw(4) << _request->get_client() << "/" << std::setw(4) << _request->get_session() << "]" << std::endl; std::shared_ptr its_response = vsomeip::runtime::get()->create_response(_request); std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); std::vector its_payload_data; for (std::size_t i = 0; i < 4; ++i) its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); its_response->set_payload(its_payload); app_->send(its_response); } void run() { std::unique_lock its_lock(mutex_); while (!blocked_) condition_.wait(its_lock); offer(); } private: std::shared_ptr app_; bool is_registered_; bool use_static_routing_; std::mutex mutex_; std::condition_variable condition_; bool blocked_; bool running_; // blocked_ must be initialized before the thread is started. std::thread offer_thread_; }; service_sample *its_sample_ptr(nullptr); void handle_signal(int _signal) { if (its_sample_ptr != nullptr && (_signal == SIGINT || _signal == SIGTERM)) its_sample_ptr->stop(); } int main(int argc, char **argv) { bool use_static_routing(false); service_sample its_sample(use_static_routing); its_sample_ptr = &its_sample; signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); if (its_sample.init()) { its_sample.start(); return 0; } else { return 1; } } someipy-2.1.2/integration_tests/call_method_tcp/start_app.sh000077500000000000000000000003231513043235100244160ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/call_method_tcp"someipy-2.1.2/integration_tests/call_method_tcp/vsomeip-client.json000066400000000000000000000017701513043235100257220ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "services": [ { "service": "0x1234", "instance": "0x5678", "reliable": "30509", "multicast": { "address": "224.225.226.234", "port": "32344" } } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/call_method_udp/000077500000000000000000000000001513043235100220665ustar00rootroot00000000000000someipy-2.1.2/integration_tests/call_method_udp/call_method_udp.cpp000066400000000000000000000115531513043235100257220ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_METHOD_ID 0x0123 class service_sample { public: service_sample(bool _use_static_routing) : app_(vsomeip::runtime::get()->create_application("Hello")), is_registered_(false), use_static_routing_(_use_static_routing), blocked_(false), running_(true), offer_thread_(std::bind(&service_sample::run, this)) { } bool init() { std::lock_guard its_lock(mutex_); if (!app_->init()) { std::cerr << "Couldn't initialize application" << std::endl; return false; } app_->register_state_handler( std::bind(&service_sample::on_state, this, std::placeholders::_1)); app_->register_message_handler( SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&service_sample::on_message, this, std::placeholders::_1)); return true; } void start() { app_->start(); } void stop() { running_ = false; blocked_ = true; app_->clear_all_handler(); stop_offer(); condition_.notify_one(); if (std::this_thread::get_id() != offer_thread_.get_id()) { if (offer_thread_.joinable()) { offer_thread_.join(); } } else { offer_thread_.detach(); } app_->stop(); } void offer() { app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 0x1); // major version 0x1 } void stop_offer() { app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 0x1); } void on_state(vsomeip::state_type_e _state) { std::cout << "Application " << app_->get_name() << " is " << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : "deregistered.") << std::endl; if (_state == vsomeip::state_type_e::ST_REGISTERED) { if (!is_registered_) { is_registered_ = true; blocked_ = true; condition_.notify_one(); } } else { is_registered_ = false; } } void on_message(const std::shared_ptr &_request) { // Log the current time. auto now = std::chrono::system_clock::now(); auto now_time_t = std::chrono::system_clock::to_time_t(now); auto now_ms = std::chrono::duration_cast( now.time_since_epoch()).count(); auto now_ms_remainder = now_ms % 1000; auto now_tm = std::localtime(&now_time_t); std::stringstream now_ss; now_ss << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << "." << std::setfill('0') << std::setw(3) << now_ms_remainder; std::cout << now_ss.str() << " Received a message with Client/Session [" << std::setfill('0') << std::hex << std::setw(4) << _request->get_client() << "/" << std::setw(4) << _request->get_session() << "]" << std::endl; std::shared_ptr its_response = vsomeip::runtime::get()->create_response(_request); std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); std::vector its_payload_data; for (std::size_t i = 0; i < 4; ++i) its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); its_response->set_payload(its_payload); app_->send(its_response); } void run() { std::unique_lock its_lock(mutex_); while (!blocked_) condition_.wait(its_lock); offer(); } private: std::shared_ptr app_; bool is_registered_; bool use_static_routing_; std::mutex mutex_; std::condition_variable condition_; bool blocked_; bool running_; // blocked_ must be initialized before the thread is started. std::thread offer_thread_; }; service_sample *its_sample_ptr(nullptr); void handle_signal(int _signal) { if (its_sample_ptr != nullptr && (_signal == SIGINT || _signal == SIGTERM)) its_sample_ptr->stop(); } int main(int argc, char **argv) { bool use_static_routing(false); service_sample its_sample(use_static_routing); its_sample_ptr = &its_sample; signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); if (its_sample.init()) { its_sample.start(); return 0; } else { return 1; } } someipy-2.1.2/integration_tests/call_method_udp/start_app.sh000077500000000000000000000003231513043235100244200ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/call_method_udp"someipy-2.1.2/integration_tests/call_method_udp/vsomeip-client.json000066400000000000000000000017721513043235100257260ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "services": [ { "service": "0x1234", "instance": "0x5678", "unreliable": "30509", "multicast": { "address": "224.225.226.234", "port": "32344" } } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/offer_method_tcp/000077500000000000000000000000001513043235100222525ustar00rootroot00000000000000someipy-2.1.2/integration_tests/offer_method_tcp/offer_method_tcp.cpp000066400000000000000000000150571513043235100262750ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_METHOD_ID 0x0123 class client_sample { public: client_sample(bool _use_tcp, uint32_t _cycle) : app_(vsomeip::runtime::get()->create_application("Hello")), request_(vsomeip::runtime::get()->create_request(_use_tcp)), use_tcp_(_use_tcp), cycle_(_cycle), is_available_(false), sender_(std::bind(&client_sample::run, this)) { } bool init() { if (!app_->init()) { std::cerr << "Couldn't initialize application" << std::endl; return false; } std::cout << "Client settings [protocol=" << (use_tcp_ ? "TCP" : "UDP") << ":cycle=" << cycle_ << "]" << std::endl; app_->register_state_handler( std::bind( &client_sample::on_state, this, std::placeholders::_1)); app_->register_message_handler( vsomeip::ANY_SERVICE, SAMPLE_INSTANCE_ID, vsomeip::ANY_METHOD, std::bind(&client_sample::on_message, this, std::placeholders::_1)); request_->set_service(SAMPLE_SERVICE_ID); request_->set_instance(SAMPLE_INSTANCE_ID); request_->set_method(SAMPLE_METHOD_ID); request_->set_interface_version(1); std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); std::vector its_payload_data; for (std::size_t i = 0; i < 10; ++i) its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); request_->set_payload(its_payload); app_->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, std::bind(&client_sample::on_availability, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); app_->register_availability_handler(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID, std::bind(&client_sample::on_availability, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); return true; } void start() { app_->start(); } void on_state(vsomeip::state_type_e _state) { if (_state == vsomeip::state_type_e::ST_REGISTERED) { app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); } } void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { std::cout << "Service [" << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance << "] is " << (_is_available ? "available." : "NOT available.") << std::endl; if (SAMPLE_SERVICE_ID == _service && SAMPLE_INSTANCE_ID == _instance) { std::lock_guard its_lock(mutex_); if (is_available_ && !_is_available) { is_available_ = false; } else if (_is_available && !is_available_) { is_available_ = true; } } } void on_message(const std::shared_ptr &_response) { std::cout << "Received a response from Service [" << std::setfill('0') << std::hex << std::setw(4) << _response->get_service() << "." << std::setw(4) << _response->get_instance() << "] to Client/Session [" << std::setw(4) << _response->get_client() << "/" << std::setw(4) << _response->get_session() << "]" << std::endl; } void run() { while (true) { bool send_data = false; { std::lock_guard its_lock(mutex_); if (is_available_) { send_data = true; } } if (send_data) { app_->send(request_); std::cout << "Client/Session [" << std::setfill('0') << std::hex << std::setw(4) << request_->get_client() << "/" << std::setw(4) << request_->get_session() << "] sent a request to Service [" << std::setw(4) << request_->get_service() << "." << std::setw(4) << request_->get_instance() << "]" << std::endl; } std::cout << "sleep for " << std::to_string(cycle_) << " ms" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(cycle_)); } } private: std::shared_ptr app_; std::shared_ptr request_; bool use_tcp_; uint32_t cycle_; std::mutex mutex_; std::condition_variable condition_; bool running_; bool is_available_; std::thread sender_; }; client_sample *its_sample_ptr(nullptr); int main(int argc, char **argv) { bool use_tcp = true; uint32_t cycle = 1000; // Default: 1s std::string tcp_enable("--tcp"); std::string udp_enable("--udp"); std::string cycle_arg("--cycle"); int i = 1; while (i < argc) { if (tcp_enable == argv[i]) { use_tcp = true; } else if (udp_enable == argv[i]) { use_tcp = false; } else if (cycle_arg == argv[i] && i + 1 < argc) { i++; std::stringstream converter; converter << argv[i]; converter >> cycle; } i++; } client_sample its_sample(use_tcp, cycle); its_sample_ptr = &its_sample; if (its_sample.init()) { its_sample.start(); return 0; } else { return 1; } } someipy-2.1.2/integration_tests/offer_method_tcp/start_app.sh000077500000000000000000000003241513043235100246050ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/offer_method_tcp"someipy-2.1.2/integration_tests/offer_method_tcp/vsomeip-client.json000066400000000000000000000013601513043235100261030ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/offer_method_udp/000077500000000000000000000000001513043235100222545ustar00rootroot00000000000000someipy-2.1.2/integration_tests/offer_method_udp/offer_method_udp.cpp000066400000000000000000000150601513043235100262730ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_METHOD_ID 0x0123 class client_sample { public: client_sample(bool _use_tcp, uint32_t _cycle) : app_(vsomeip::runtime::get()->create_application("Hello")), request_(vsomeip::runtime::get()->create_request(_use_tcp)), use_tcp_(_use_tcp), cycle_(_cycle), is_available_(false), sender_(std::bind(&client_sample::run, this)) { } bool init() { if (!app_->init()) { std::cerr << "Couldn't initialize application" << std::endl; return false; } std::cout << "Client settings [protocol=" << (use_tcp_ ? "TCP" : "UDP") << ":cycle=" << cycle_ << "]" << std::endl; app_->register_state_handler( std::bind( &client_sample::on_state, this, std::placeholders::_1)); app_->register_message_handler( vsomeip::ANY_SERVICE, SAMPLE_INSTANCE_ID, vsomeip::ANY_METHOD, std::bind(&client_sample::on_message, this, std::placeholders::_1)); request_->set_service(SAMPLE_SERVICE_ID); request_->set_instance(SAMPLE_INSTANCE_ID); request_->set_method(SAMPLE_METHOD_ID); request_->set_interface_version(1); std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); std::vector its_payload_data; for (std::size_t i = 0; i < 10; ++i) its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); request_->set_payload(its_payload); app_->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, std::bind(&client_sample::on_availability, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); app_->register_availability_handler(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID, std::bind(&client_sample::on_availability, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); return true; } void start() { app_->start(); } void on_state(vsomeip::state_type_e _state) { if (_state == vsomeip::state_type_e::ST_REGISTERED) { app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); } } void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { std::cout << "Service [" << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance << "] is " << (_is_available ? "available." : "NOT available.") << std::endl; if (SAMPLE_SERVICE_ID == _service && SAMPLE_INSTANCE_ID == _instance) { std::lock_guard its_lock(mutex_); if (is_available_ && !_is_available) { is_available_ = false; } else if (_is_available && !is_available_) { is_available_ = true; } } } void on_message(const std::shared_ptr &_response) { std::cout << "Received a response from Service [" << std::setfill('0') << std::hex << std::setw(4) << _response->get_service() << "." << std::setw(4) << _response->get_instance() << "] to Client/Session [" << std::setw(4) << _response->get_client() << "/" << std::setw(4) << _response->get_session() << "]" << std::endl; } void run() { while (true) { bool send_data = false; { std::lock_guard its_lock(mutex_); if (is_available_) { send_data = true; } } if (send_data) { app_->send(request_); std::cout << "Client/Session [" << std::setfill('0') << std::hex << std::setw(4) << request_->get_client() << "/" << std::setw(4) << request_->get_session() << "] sent a request to Service [" << std::setw(4) << request_->get_service() << "." << std::setw(4) << request_->get_instance() << "]" << std::endl; } std::cout << "sleep for " << std::to_string(cycle_) << " ms" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(cycle_)); } } private: std::shared_ptr app_; std::shared_ptr request_; bool use_tcp_; uint32_t cycle_; std::mutex mutex_; std::condition_variable condition_; bool running_; bool is_available_; std::thread sender_; }; client_sample *its_sample_ptr(nullptr); int main(int argc, char **argv) { bool use_tcp = false; uint32_t cycle = 1000; // Default: 1s std::string tcp_enable("--tcp"); std::string udp_enable("--udp"); std::string cycle_arg("--cycle"); int i = 1; while (i < argc) { if (tcp_enable == argv[i]) { use_tcp = true; } else if (udp_enable == argv[i]) { use_tcp = false; } else if (cycle_arg == argv[i] && i + 1 < argc) { i++; std::stringstream converter; converter << argv[i]; converter >> cycle; } i++; } client_sample its_sample(use_tcp, cycle); its_sample_ptr = &its_sample; if (its_sample.init()) { its_sample.start(); return 0; } else { return 1; } } someipy-2.1.2/integration_tests/offer_method_udp/start_app.sh000077500000000000000000000003241513043235100246070ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/offer_method_udp"someipy-2.1.2/integration_tests/offer_method_udp/vsomeip-client.json000066400000000000000000000013601513043235100261050ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/offer_multiple_services/000077500000000000000000000000001513043235100236625ustar00rootroot00000000000000someipy-2.1.2/integration_tests/offer_multiple_services/offer_multiple_services.cpp000066400000000000000000000077351513043235100313210ustar00rootroot00000000000000#include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID_1 0x5678 #define SAMPLE_INSTANCE_ID_2 0x6789 #define SAMPLE_EVENTGROUP_ID 0x0321 #define SAMPLE_EVENT_ID 0x0123 #define MAJOR_VERSION 1 std::shared_ptr app; std::mutex mutex; std::condition_variable condition; bool service_instance_available_1 = false; bool service_instance_available_2 = false; void run() { while (true) { std::unique_lock its_lock(mutex); condition.wait(its_lock, [] { return service_instance_available_1 || service_instance_available_2; }); std::cout << "Run triggered." << std::endl; std::set its_groups; its_groups.insert(SAMPLE_EVENTGROUP_ID); if (service_instance_available_1) { app->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_1, SAMPLE_EVENT_ID, its_groups); app->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_1, SAMPLE_EVENTGROUP_ID, MAJOR_VERSION); service_instance_available_1 = false; } if (service_instance_available_2) { app->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_2, SAMPLE_EVENT_ID, its_groups); app->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_2, SAMPLE_EVENTGROUP_ID, MAJOR_VERSION); service_instance_available_2 = false; } its_lock.unlock(); } } void on_message(const std::shared_ptr &_response) { std::stringstream its_message; its_message << "CLIENT: received a notification for event [" << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() << "." << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() << "." << std::setw(4) << std::setfill('0') << std::hex << _response->get_method() << "] to Client/Session [" << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() << "/" << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() << "] = "; std::shared_ptr its_payload = _response->get_payload(); its_message << "(" << std::dec << its_payload->get_length() << ") "; for (uint32_t i = 0; i < its_payload->get_length(); ++i) its_message << std::hex << std::setw(2) << std::setfill('0') << (int)its_payload->get_data()[i] << " "; std::cout << its_message.str() << std::endl; } void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { std::cout << "CLIENT: Service ID / Instance ID [" << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance << "] is " << (_is_available ? "available." : "NOT available.") << std::endl; { std::lock_guard l{mutex}; if (_instance == SAMPLE_INSTANCE_ID_1) service_instance_available_1 = _is_available; else if (_instance == SAMPLE_INSTANCE_ID_2) service_instance_available_2 = _is_available; else return; } condition.notify_one(); } int main() { app = vsomeip::runtime::get()->create_application("Hello"); app->init(); app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_1, on_availability); app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_2, on_availability); app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_1); app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID_2); app->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, on_message); std::thread receiver(run); app->start(); }someipy-2.1.2/integration_tests/offer_multiple_services/start_app.sh000077500000000000000000000003331513043235100262150ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/offer_multiple_services"someipy-2.1.2/integration_tests/offer_multiple_services/vsomeip-client.json000066400000000000000000000013601513043235100275130ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/receive_events_tcp/000077500000000000000000000000001513043235100226175ustar00rootroot00000000000000someipy-2.1.2/integration_tests/receive_events_tcp/receive_events_tcp.cpp000066400000000000000000000035771513043235100272130ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_EVENTGROUP_ID 0x0321 #define SAMPLE_EVENT_ID 0x0123 std::shared_ptr payload_; std::shared_ptr app_; std::set its_groups; void offer() { app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 1, 0); app_->offer_event( SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups, vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), false, true, nullptr, vsomeip::reliability_type_e::RT_RELIABLE); } void stop_offer() { app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); } void run() { std::this_thread::sleep_for(std::chrono::milliseconds(3000)); vsomeip::byte_t its_data[10]; uint32_t its_size = 1; uint32_t loop_counter = 0; while (true) { for (uint32_t i = 0; i < its_size; ++i) { its_data[i] = static_cast((loop_counter + i) % 255); } loop_counter++; payload_->set_data(its_data, its_size); std::cout << "Setting event (Length=" << std::dec << its_size << ")." << std::endl; app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload_); std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } int main(int argc, char **argv) { its_groups.insert(SAMPLE_EVENTGROUP_ID); app_ = vsomeip::runtime::get()->create_application("Hello"); app_->init(); payload_ = vsomeip::runtime::get()->create_payload(); offer(); std::thread receiver(run); app_->start(); }someipy-2.1.2/integration_tests/receive_events_tcp/start_app.sh000077500000000000000000000003731513043235100251560ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ export VSOMEIP_CLIENTSIDELOGGING="1" VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/receive_events_tcp"someipy-2.1.2/integration_tests/receive_events_tcp/vsomeip-client.json000066400000000000000000000026211513043235100264510ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "debug", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "services": [ { "service": "0x1234", "instance": "0x5678", "reliable": { "port": "30509", "magic-cookies": "false" }, "events": [ { "event": "0x0123", "is_field": "false", "is_reliable": "true", "update-cycle": "1" } ], "eventgroups": [ { "eventgroup": "0x0321", "events": [ "0x0123" ] } ] } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/receive_events_udp/000077500000000000000000000000001513043235100226215ustar00rootroot00000000000000someipy-2.1.2/integration_tests/receive_events_udp/receive_events_udp.cpp000066400000000000000000000034621513043235100272100ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_EVENTGROUP_ID 0x0321 #define SAMPLE_EVENT_ID 0x0123 std::shared_ptr payload_; std::shared_ptr app_; std::set its_groups; void offer() { app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 1, 0); app_->offer_event( SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); } void stop_offer() { app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); } void run() { vsomeip::byte_t its_data[10]; uint32_t its_size = 1; uint32_t loop_counter = 0; while (true) { for (uint32_t i = 0; i < its_size; ++i) { its_data[i] = static_cast((loop_counter + i) % 255); } loop_counter++; payload_->set_data(its_data, its_size); std::cout << "Setting event (Length=" << std::dec << its_size << ")." << std::endl; app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload_); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } } int main(int argc, char **argv) { its_groups.insert(SAMPLE_EVENTGROUP_ID); app_ = vsomeip::runtime::get()->create_application("Hello"); app_->init(); payload_ = vsomeip::runtime::get()->create_payload(); offer(); std::thread receiver(run); app_->start(); }someipy-2.1.2/integration_tests/receive_events_udp/start_app.sh000077500000000000000000000003261513043235100251560ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/receive_events_udp"someipy-2.1.2/integration_tests/receive_events_udp/vsomeip-client.json000066400000000000000000000025041513043235100264530ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "services": [ { "service": "0x1234", "instance": "0x5678", "unreliable": "30509", "events": [ { "event": "0x0123", "is_field": "false", "is_reliable": "false", "update-cycle": "0" } ], "eventgroups": [ { "eventgroup": "0x0321", "events": [ "0x0123" ] } ] } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/integration_tests/send_events/000077500000000000000000000000001513043235100212605ustar00rootroot00000000000000someipy-2.1.2/integration_tests/send_events/send_events.cpp000066400000000000000000000060361513043235100243060ustar00rootroot00000000000000#include #include #include #include #include #include #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 #define SAMPLE_EVENTGROUP_ID 0x0321 #define SAMPLE_EVENT_ID 0x0123 std::shared_ptr app; std::mutex mutex; std::condition_variable condition; bool service_available = false; void run() { while (true) { std::unique_lock its_lock(mutex); condition.wait(its_lock, [] { return service_available; }); service_available = false; its_lock.unlock(); std::cout << "Run triggered." << std::endl; std::set its_groups; its_groups.insert(SAMPLE_EVENTGROUP_ID); app->request_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, its_groups); app->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID, 1); } } void on_message(const std::shared_ptr &_response) { std::stringstream its_message; its_message << "CLIENT: received a notification for event [" << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() << "." << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() << "." << std::setw(4) << std::setfill('0') << std::hex << _response->get_method() << "] to Client/Session [" << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() << "/" << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() << "] = "; std::shared_ptr its_payload = _response->get_payload(); its_message << "(" << std::dec << its_payload->get_length() << ") "; for (uint32_t i = 0; i < its_payload->get_length(); ++i) its_message << std::hex << std::setw(2) << std::setfill('0') << (int)its_payload->get_data()[i] << " "; std::cout << its_message.str() << std::endl; } void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { std::cout << "CLIENT: Service ID / Instance ID [" << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance << "] is " << (_is_available ? "available." : "NOT available.") << std::endl; { std::lock_guard l{mutex}; service_available = _is_available; } condition.notify_one(); } int main() { app = vsomeip::runtime::get()->create_application("Hello"); app->init(); app->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, on_availability); app->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); app->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, on_message); std::thread receiver(run); app->start(); }someipy-2.1.2/integration_tests/send_events/start_app.sh000077500000000000000000000003171513043235100236150ustar00rootroot00000000000000#!/bin/bash script_dir="$(dirname "$0")" export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/projects/someip/vsomeip_install/lib/ VSOMEIP_CONFIGURATION="${script_dir}/vsomeip-client.json" "${script_dir}/send_events"someipy-2.1.2/integration_tests/send_events/vsomeip-client.json000066400000000000000000000013601513043235100251110ustar00rootroot00000000000000{ "unicast": "127.0.0.1", "logging": { "level": "verbose", "console": "true", "file": { "enable": "false", "path": "./vsomeip.log" }, "dlt": "false" }, "applications": [ { "name": "Hello", "id": "0x1313" } ], "routing": "Hello", "service-discovery": { "enable": "true", "multicast": "224.224.224.245", "port": "30490", "protocol": "udp", "initial_delay_min": "10", "initial_delay_max": "100", "repetitions_base_delay": "200", "repetitions_max": "3", "ttl": "3", "cyclic_offer_delay": "2000", "request_response_delay": "1500" } }someipy-2.1.2/pyproject.toml000066400000000000000000000001251513043235100161100ustar00rootroot00000000000000[build-system] requires = ['setuptools>=42'] build-backend = 'setuptools.build_meta' someipy-2.1.2/setup.cfg000066400000000000000000000014551513043235100150240ustar00rootroot00000000000000[metadata] name = someipy version = 2.1.2 author = Christian H. author_email = someipy.package@gmail.com description = A Python package implementing the SOME/IP protocol long_description = file: README.md long_description_content_type = text/markdown url = https://github.com/chrizog/someipy project_urls = Bug Tracker = https://github.com/chrizog/someipy/issues Repository = https://github.com/chrizog/someipy classifiers = Intended Audience :: Developers Operating System :: POSIX :: Linux Operating System :: Microsoft :: Windows Programming Language :: Python :: 3.8 license_files = LICENSE.md [options] package_dir = = src packages = find: python_requires = >=3.8 [options.packages.find] where = src [options.entry_points] console_scripts = someipyd = someipy.someipyd:mainsomeipy-2.1.2/src/000077500000000000000000000000001513043235100137655ustar00rootroot00000000000000someipy-2.1.2/src/someipy/000077500000000000000000000000001513043235100154525ustar00rootroot00000000000000someipy-2.1.2/src/someipy/__init__.py000066400000000000000000000012411513043235100175610ustar00rootroot00000000000000from ._internal.transport_layer_protocol import TransportLayerProtocol # noqa: F401 from .service import Service, ServiceBuilder, EventGroup, Method, Event # noqa: F401 from .server_service_instance import ServerServiceInstance # noqa: F401 from .client_service_instance import ClientServiceInstance # noqa: F401 from ._internal.someip_message import SomeIpMessage # noqa: F401 from ._internal.method_result import MethodResult # noqa: F401 from ._internal.return_codes import ReturnCode # noqa: F401 from ._internal.message_types import MessageType # noqa: F401 from ._internal._daemon.someipy_daemon_client import ( connect_to_someipy_daemon, ) # noqa: F401 someipy-2.1.2/src/someipy/_internal/000077500000000000000000000000001513043235100174255ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/__init__.py000066400000000000000000000000001513043235100215240ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_common/000077500000000000000000000000001513043235100210545ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_common/__init__.py000066400000000000000000000000001513043235100231530ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_common/endpoint.py000066400000000000000000000022061513043235100232460ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import ipaddress from typing import NamedTuple, Union class Endpoint(NamedTuple): """Represents a network endpoint with IP address and port.""" ip: Union[ipaddress.IPv4Address, ipaddress.IPv6Address] port: int @property def is_ipv4(self): return isinstance(self.ip, ipaddress.IPv4Address) def __str__(self): if isinstance(self.ip, ipaddress.IPv6Address): return f"[{self.ip}]:{self.port}" return f"{self.ip}:{self.port}" someipy-2.1.2/src/someipy/_internal/_common/event.py000066400000000000000000000034311513043235100225500ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio from typing import TypeVar, Generic, Optional, Callable, Any T = TypeVar("T") class Event(Generic[T]): def __init__(self): self._handlers: list[Callable[[object, Optional[T]], Any]] = [] def add_handler(self, handler: Callable[[object, Optional[T]], Any]) -> None: if handler not in self._handlers: self._handlers.append(handler) def remove_handler(self, handler: Callable[[object, Optional[T]], Any]) -> None: if handler in self._handlers: self._handlers.remove(handler) async def invoke(self, sender: object, e: Optional[T] = None) -> None: """Invoke all handlers, handling both sync and async automatically""" for handler in self._handlers[:]: result = handler(sender, e) if asyncio.iscoroutine(result): await result def __iadd__(self, handler: Callable[[object, Optional[T]], Any]) -> "Event[T]": self.add_handler(handler) return self def __isub__(self, handler: Callable[[object, Optional[T]], Any]) -> "Event[T]": self.remove_handler(handler) return self someipy-2.1.2/src/someipy/_internal/_daemon/000077500000000000000000000000001513043235100210275ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_daemon/__init__.py000066400000000000000000000000001513043235100231260ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_daemon/daemon_server.py000066400000000000000000000052611513043235100242360ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio import logging import os import platform from someipy._internal._common.event import Event from someipy._internal._daemon.daemon_server_client import DaemonServerClient class ClientConnectedEventArgs: def __init__(self, client: DaemonServerClient): self.client = client class DaemonServer: def __init__(self, logger: logging.Logger): self._logger = logger self.client_connected: Event[ClientConnectedEventArgs] = Event() self.client_disconnected: Event[ClientConnectedEventArgs] = Event() async def _handle_client(self, reader, writer): writer_id = id(writer) self._logger.info(f"New client connected: {writer_id}") client = DaemonServerClient(reader, writer, writer_id, self._logger) await self.client_connected.invoke(self, ClientConnectedEventArgs(client)) while True: message = await client.read_next_message() if message is None: break # Client disconnected await self.client_disconnected.invoke(self, ClientConnectedEventArgs(client)) async def start( self, use_tcp: bool = False, socket_path: str | None = None, tcp_port: int | None = None, host: str = "127.0.0.1", ): if not use_tcp: if os.path.exists(socket_path): os.unlink(socket_path) self._server = await asyncio.start_unix_server( self._handle_client, path=socket_path ) self._logger.info(f"Unix domain socket server started at {socket_path}") else: reuse_port = platform.system() == "Linux" self._server = await asyncio.start_server( self._handle_client, host=host, port=tcp_port, reuse_port=reuse_port, ) self._logger.info(f"TCP server started at {host}:{tcp_port}") async def serve_forever(self): async with self._server: await self._server.serve_forever() someipy-2.1.2/src/someipy/_internal/_daemon/daemon_server_client.py000066400000000000000000000075301513043235100255750ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio import json import logging import struct from typing import Optional from someipy._internal._common.event import Event class DaemonServerClient: def __init__( self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, client_id: int, logger: logging.Logger = None, ): self._reader = reader self._writer = writer self._id = client_id self._logger = logger self.message_received: Event[ClientMessageEventArgs] = Event() async def read_next_message(self) -> Optional[dict]: wait_for_header = True header_buffer = b"" message_buffer = b"" message_length = 0 while True: if wait_for_header: data = await self._reader.read(256 - len(header_buffer)) if not data: self._logger.debug( f"Reading data returned none. Client disconnected." ) break # Client disconnected header_buffer += data if len(header_buffer) == 256: try: message_length = struct.unpack(" 256: self._logger.error(f"Client sent too much header data.") break else: data = await self._reader.read(message_length - len(message_buffer)) if not data: self._logger.debug( f"Reading data returned none. Client disconnected." ) break # Client disconnected message_buffer += data if len(message_buffer) == message_length: self._logger.debug( f"Client {self.id} sent message: {message_buffer}" ) json_message = json.loads(message_buffer.decode("utf-8")) await self.message_received.invoke( self, ClientMessageEventArgs(self, json_message) ) return json_message elif len(message_buffer) > message_length: self._logger.error(f"Client sent too much message data.") raise Exception("Client sent too much message data.") return None async def send(self, data: bytes): self._writer.write(data) await self._writer.drain() async def close(self): self._writer.close() await self._writer.wait_closed() @property def id(self) -> int: return self._id class ClientMessageEventArgs: def __init__(self, client: DaemonServerClient, message: dict): self.client = client self.message = message someipy-2.1.2/src/someipy/_internal/_daemon/offer_service_storage.py000066400000000000000000000144341513043235100257540ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import List from someipy._internal._common.endpoint import Endpoint from someipy.service import Event, EventGroup, Method from someipy._internal.transport_layer_protocol import TransportLayerProtocol class ServiceToOffer: def __init__( self, client_writer_id: int, instance_id: int, service_id: int, major_version: int, minor_version: int, offer_ttl_seconds: int, cyclic_offer_delay_ms: int, endpoint: Endpoint, methods: List[Method], eventgroups: List[EventGroup], ): self.client_writer_id = client_writer_id self.instance_id = instance_id self.service_id = service_id self.major_version = major_version self.minor_version = minor_version self.offer_ttl_seconds = offer_ttl_seconds self.cyclic_offer_delay_ms = cyclic_offer_delay_ms self.endpoint = endpoint self.methods = methods self.eventgroups = eventgroups self.last_offer_time = None # Placeholder for last offer time def __eq__(self, other: object) -> bool: if not isinstance(other, ServiceToOffer): return False return ( self.client_writer_id == other.client_writer_id and self.instance_id == other.instance_id and self.service_id == other.service_id and self.major_version == other.major_version and self.minor_version == other.minor_version and self.offer_ttl_seconds == other.offer_ttl_seconds and self.cyclic_offer_delay_ms == other.cyclic_offer_delay_ms and self.endpoint == other.endpoint and self.methods == other.methods and self.eventgroups == other.eventgroups ) def __hash__(self) -> int: return hash( ( self.client_writer_id, self.instance_id, self.service_id, self.major_version, self.minor_version, self.offer_ttl_seconds, self.cyclic_offer_delay_ms, self.endpoint, tuple(self.methods), # Convert list to tuple for hashing tuple(self.eventgroups), # Convert list to tuple for hashing ) ) @property def has_udp(self) -> bool: has_method_udp = any( method.protocol == TransportLayerProtocol.UDP for method in self.methods ) events = [event for eg in self.eventgroups for event in eg.events] has_event_udp = any( event.protocol == TransportLayerProtocol.UDP for event in events ) return has_method_udp or has_event_udp @property def has_tcp(self) -> bool: has_method_tcp = any( method.protocol == TransportLayerProtocol.TCP for method in self.methods ) events = [event for eg in self.eventgroups for event in eg.events] has_event_tcp = any( event.protocol == TransportLayerProtocol.TCP for event in events ) return has_method_tcp or has_event_tcp @property def eventgroup_ids(self) -> List[int]: """Returns a list of all eventgroup IDs from the stored eventgroups""" return [eventgroup.id for eventgroup in self.eventgroups] @property def protocols(self) -> frozenset[TransportLayerProtocol]: result = set() if self.has_udp: result.add(TransportLayerProtocol.UDP) if self.has_tcp: result.add(TransportLayerProtocol.TCP) return frozenset(result) class OfferServiceStorage: def __init__(self): self._services: List[ServiceToOffer] = [] def add_service(self, service: ServiceToOffer) -> bool: """Add a new ServiceToOffer to the storage if it doesn't already exist. Returns True if the service was added, False if it was a duplicate.""" if service in self._services: return False self._services.append(service) return True def remove_service(self, service: ServiceToOffer) -> bool: """Remove a specific ServiceToOffer from the storage. Returns True if the service was found and removed, False otherwise.""" try: self._services.remove(service) return True except ValueError: return False def remove_client(self, client_writer_id: int) -> int: """Remove all services with the given client_writer_id. Returns the number of services removed.""" initial_count = len(self._services) self._services = [ service for service in self._services if service.client_writer_id != client_writer_id ] return initial_count - len(self._services) def services_by_cyclic_offer_delay( self, cyclic_offer_delay_ms: int ) -> List[ServiceToOffer]: """Return all services with the specified cyclic_offer_delay_ms""" return [ service for service in self._services if service.cyclic_offer_delay_ms == cyclic_offer_delay_ms ] def get_all_services(self) -> List[ServiceToOffer]: """Return all services in the storage""" return self._services.copy() def clear(self) -> None: """Remove all services from the storage""" self._services.clear() def __len__(self) -> int: return len(self._services) @property def cyclic_offer_delays(self) -> List[int]: """Returns a list of all unique cyclic_offer_delay_ms values from stored services""" return sorted({service.cyclic_offer_delay_ms for service in self._services}) someipy-2.1.2/src/someipy/_internal/_daemon/someipy_daemon_client.py000066400000000000000000000441071513043235100257550ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio import base64 import ipaddress import json import platform import struct from typing import Dict, List, TypedDict, cast from someipy._internal.daemon_client_abcs import ( ClientInstanceInterface, ServerInstanceInterface, ) from someipy._internal.logging import get_logger from someipy._internal.someip_sd_header import SdService from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy._internal._daemon.uds_messages import ( BaseMessage, InboundCallMethodRequest, InboundCallMethodResponse, FindServiceRequest, FindServiceResponse, OfferServiceRequest, OutboundCallMethodResponse, ReceivedEvent, StopOfferServiceRequest, create_uds_message, ) from someipy.service import EventGroup, Method _logger_name = "someipyd_client" async def connect_to_someipy_daemon(config: dict = None): """Connect to the someipy daemon. Parameters ---------- config : dict, optional Configuration dictionary. The following keys are supported: - socket_path: Path to the Unix domain socket. Default is /tmp/someipyd.sock Returns ------- SomeIpDaemonClient An instance of the SomeIpDaemonClient class. """ daemon_client = SomeIpDaemonClient(config) await daemon_client._connect_to_daemon() return daemon_client class DaemonMessage(TypedDict): type: str class SomeIpDaemonClient: def __init__(self, config: dict = None): self._config = config if self._config is None: self._use_tcp = platform.system() != "Linux" self._tcp_host = "127.0.0.1" self._tcp_port = 30500 self._socket_path = "/tmp/someipyd.sock" else: self._socket_path = self._config.get("socket_path", "/tmp/someipyd.sock") self._use_tcp = self._config.get("use_tcp", platform.system() != "Linux") self._tcp_port = self._config.get("tcp_port", 30500) self._tcp_host = self._config.get("tcp_host", "127.0.0.1") self._rx_message_queue: asyncio.Queue[DaemonMessage] = asyncio.Queue() self._rx_task: asyncio.Task = None self._tx_queue: asyncio.Queue = asyncio.Queue() self._tx_task: asyncio.Task = None self._server_service_instances: List[ServerInstanceInterface] = [] self._client_service_instances: List[ClientInstanceInterface] = [] self.reader: asyncio.StreamReader = None self.writer: asyncio.StreamWriter = None def _prepare_request(self, message: dict): payload = json.dumps(message).encode("utf-8") return struct.pack(" 0: num_retries -= 1 try: self._clear_rx_queue() self._rx_message_queue = asyncio.Queue() if self._use_tcp: self.reader, self.writer = await asyncio.open_connection( self._tcp_host, self._tcp_port ) else: self.reader, self.writer = await asyncio.open_unix_connection( self._socket_path ) success = True break except Exception as e: connection = "TCP" if self._use_tcp else "Unix Domain Socket" get_logger(_logger_name).error( f"Failed to connect to daemon via {connection}: {e}. Retries left: {num_retries}" ) await asyncio.sleep(1.0) if not success: raise Exception(f"Failed to connect to daemon after retries") else: self._rx_task = asyncio.create_task(self.receive_data_task(self.reader)) self._tx_task = asyncio.create_task(self.transmit_data_task(self.writer)) async def _wait_until_tx_queue_empty(self): while not self._tx_queue.empty(): await asyncio.sleep(0.1) async def disconnect_from_daemon(self): await asyncio.wait_for(self._wait_until_tx_queue_empty(), 0.5) await self._disconnected_from_daemon() async def transmit_data_task(self, writer: asyncio.StreamWriter): try: while True: try: # Wait on queue with timeout data = await asyncio.wait_for(self._tx_queue.get(), timeout=0.2) try: # Send the data writer.write(data) await writer.drain() self._tx_queue.task_done() except ConnectionError as e: get_logger(_logger_name).error(f"Connection error: {e}") break except asyncio.TimeoutError: # Periodic timeout for cancellation check continue except asyncio.CancelledError: get_logger(_logger_name).debug("Daemon client TX task cancelled") finally: get_logger(_logger_name).debug("Daemon client TX task finished") def transmit_message_to_daemon(self, message: dict): get_logger(_logger_name).debug(f"Transmitting message: {message}") request_bytes = self._prepare_request(message) self._tx_queue.put_nowait(request_bytes) async def handle_single_method_call( self, method_request: InboundCallMethodRequest, method: Method ): payload_decoded = base64.b64decode(method_request["payload"]) # check if the method handler is a coroutine function if asyncio.iscoroutinefunction(method.method_handler): # Call the method handler as a coroutine result = await method.method_handler( payload_decoded, ( method_request["src_endpoint_ip"], method_request["src_endpoint_port"], ), ) else: # Call the method handler as a regular function result = method.method_handler( payload_decoded, ( method_request["src_endpoint_ip"], method_request["src_endpoint_port"], ), ) encoded_result = base64.b64encode(result.payload).decode("utf-8") call_method_response = create_uds_message( InboundCallMethodResponse, service_id=method_request["service_id"], instance_id=method_request["instance_id"], method_id=method_request["method_id"], client_id=method_request["client_id"], session_id=method_request["session_id"], protocol_version=method_request["protocol_version"], interface_version=method_request["interface_version"], major_version=method_request["major_version"], minor_version=method_request["minor_version"], message_type=result.message_type.value, src_endpoint_ip=method_request["src_endpoint_ip"], src_endpoint_port=method_request["src_endpoint_port"], protocol=method_request["protocol"], payload=encoded_result, return_code=result.return_code.value, ) self.transmit_message_to_daemon(call_method_response) async def _handle_message(self, message: BaseMessage): if message["type"] == InboundCallMethodRequest.__name__: get_logger(_logger_name).debug(f"Received CallMethodRequest: {message}") message = cast(InboundCallMethodRequest, message) # Find the right method and call the method handler service_id = message["service_id"] instance_id = message["instance_id"] major_version = message["major_version"] minor_version = message["minor_version"] method_id = message["method_id"] protocol = message["protocol"] for service_instance in self._server_service_instances: if ( service_instance.service.id == service_id and service_instance.instance_id == instance_id and service_instance.service.major_version == major_version ): method = service_instance.service.methods.get(method_id, None) if method: get_logger(_logger_name).debug( f"Calling method handler for {method_id:04x} on service {service_id:04x}" ) # Call the method handler, eventually call it in a separate task # to avoid blocking the event loop asyncio.create_task( self.handle_single_method_call(message, method) ) elif message["type"] == OutboundCallMethodResponse.__name__: get_logger(_logger_name).debug( f"Received OutboundCallMethodResponse: {message}" ) message = cast(OutboundCallMethodResponse, message) for service_instance in self._client_service_instances: if ( service_instance.service.id == message["service_id"] and message["method_id"] in [m for m in service_instance.service.methods.keys()] and service_instance.endpoint[1] == message["dst_endpoint_port"] and service_instance.endpoint[0] == message["dst_endpoint_ip"] ): service_instance._method_call_data_received(message) elif message["type"] == ReceivedEvent.__name__: get_logger(_logger_name).debug(f"Received ReceivedEvent: {message}") for service_instance in self._client_service_instances: service_instance._event_data_received(cast(ReceivedEvent, message)) else: self._rx_message_queue.put_nowait(message) async def receive_data_task(self, reader: asyncio.StreamReader): while True: try: message = await self._read_next_message(reader) get_logger(_logger_name).debug(f"Received message: {message}") await self._handle_message(message) except Exception as e: get_logger(_logger_name).error(f"Error processing message: {e}") break async def _read_next_message( self, reader: asyncio.StreamReader, timeout=None ) -> dict: wait_for_header = True header_buffer = b"" message_buffer = b"" message_length = 0 while True: if wait_for_header: try: if timeout is not None: data = await asyncio.wait_for( reader.read(256 - len(header_buffer)), timeout ) else: data = await reader.read(256 - len(header_buffer)) if not data: get_logger(_logger_name).error("No data received") break except asyncio.TimeoutError as e: get_logger(_logger_name).error("Failed to read header: Timeout") raise e except Exception as e: raise Exception(f"Failed to read header: {e}") header_buffer += data if len(header_buffer) == 256: try: message_length = struct.unpack(" SdService: request = create_uds_message( FindServiceRequest, service_id=service_id, instance_id=instance_id, major_version=major_version, minor_version=minor_version, ) request_bytes = self._prepare_request(request) self._tx_queue.put_nowait(request_bytes) response = await self._rx_message_queue.get() if response["type"] != FindServiceResponse.__name__: self._rx_message_queue.task_done() raise Exception( f"Invalid response from daemon. Expected find_service_res and got {response['type']}" ) if not response["success"]: self._rx_message_queue.task_done() return None service = SdService( service_id=response["service_id"], instance_id=response["instance_id"], major_version=response["major_version"], minor_version=response["minor_version"], ttl=0, endpoint=( ipaddress.IPv4Address(response["endpoint_ip"]), response["endpoint_port"], ), protocol=TransportLayerProtocol.UDP, ) self._rx_message_queue.task_done() return service async def offer_service( self, service_id: int, instance_id: int, major_version: int, minor_version: int, ttl: int, endpoint_ip: str, endpoint_port: int, eventgroups: List[EventGroup], methods: List[Method], cyclic_offer_delay_ms: int, ): request = create_uds_message( OfferServiceRequest, service_id=service_id, instance_id=instance_id, major_version=major_version, minor_version=minor_version, endpoint_ip=endpoint_ip, endpoint_port=endpoint_port, ttl=ttl, eventgroup_list=[eventgroup.to_json() for eventgroup in eventgroups], method_list=[method.to_json() for method in methods], cyclic_offer_delay_ms=cyclic_offer_delay_ms, ) self.transmit_message_to_daemon(request) async def stop_offer_service( self, service_id: int, instance_id: int, major_version: int, minor_version: int, ttl: int, endpoint_ip: str, endpoint_port: int, eventgroups: List[EventGroup], methods: List[Method], cyclic_offer_delay_ms: int, ): request = create_uds_message( StopOfferServiceRequest, service_id=service_id, instance_id=instance_id, major_version=major_version, minor_version=minor_version, endpoint_ip=endpoint_ip, endpoint_port=endpoint_port, ttl=ttl, eventgroup_list=[eventgroup.to_json() for eventgroup in eventgroups], method_list=[method.to_json() for method in methods], cyclic_offer_delay_ms=cyclic_offer_delay_ms, ) self.transmit_message_to_daemon(request) someipy-2.1.2/src/someipy/_internal/_daemon/subscription.py000066400000000000000000000046441513043235100241350ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from someipy._internal._common.endpoint import Endpoint from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy.service import EventGroup class Subscription: def __init__( self, service_id: int, instance_id: int, major_version: int, eventgroup: EventGroup, ttl_seconds: int, client_endpoint: Endpoint, server_endpoint: Endpoint, protocols: frozenset[TransportLayerProtocol], timestamp_last_update: float = 0.0, ): self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.eventgroup = eventgroup self.ttl_seconds = ttl_seconds self.client_endpoint = client_endpoint self.server_endpoint = server_endpoint self.protocols = protocols self.timestamp_last_update = timestamp_last_update def __eq__(self, value: "Subscription") -> bool: return ( self.service_id == value.service_id and self.instance_id == value.instance_id and self.major_version == value.major_version and self.eventgroup == value.eventgroup and self.client_endpoint == value.client_endpoint and self.server_endpoint == value.server_endpoint and self.protocols == value.protocols ) def __hash__(self) -> int: # Do not include the timestamp and ttl in the hash calculation return hash( ( self.service_id, self.instance_id, self.major_version, self.eventgroup, self.client_endpoint, self.server_endpoint, self.protocols, ) ) someipy-2.1.2/src/someipy/_internal/_daemon/subscription_storage.py000066400000000000000000000073551513043235100256630ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import Dict, List, Tuple from someipy._internal._daemon.subscription import Subscription class SubscriptionStorage: def __init__(self): self._subscriptions_by_client: Dict[int, List[Subscription]] = {} def add_subscription(self, client_id: int, subscription: Subscription): if client_id not in self._subscriptions_by_client: self._subscriptions_by_client[client_id] = [] self._subscriptions_by_client[client_id].append(subscription) else: if subscription not in self._subscriptions_by_client[client_id]: self._subscriptions_by_client[client_id].append(subscription) def remove_subscription(self, client_id: int, subscription: Subscription): if client_id in self._subscriptions_by_client: if subscription in self._subscriptions_by_client[client_id]: self._subscriptions_by_client[client_id].remove(subscription) if len(self._subscriptions_by_client[client_id]) == 0: del self._subscriptions_by_client[client_id] @property def subscriptions(self) -> List[Subscription]: """ Get all subscriptions from all clients. """ subscriptions = [] for client_subscriptions in self._subscriptions_by_client.values(): subscriptions.extend(client_subscriptions) return subscriptions def __len__(self) -> int: """ Get the total number of subscriptions across all clients. """ total = 0 for client_subscriptions in self._subscriptions_by_client.values(): total += len(client_subscriptions) return total def get_client_ids(self, subscription: Subscription) -> List[int]: """ Get all client ids (writer ids) that have the given subscription. """ client_ids = [] for client_id, subscriptions in self._subscriptions_by_client.items(): if subscription in subscriptions: client_ids.append(client_id) return client_ids def has_subscriptions( self, service_id: int, instance_id: int, major_version: int, ) -> List[Tuple[Subscription, int]]: """ Check if there are any subscriptions for the given service id, instance id, major version and protocol. Returns a list of tuples containing the subscription and the writer id (UDS client). """ subscriptions_to_return = [] for writer_id, subscriptions in self._subscriptions_by_client.items(): for subscription in subscriptions: if ( subscription.service_id == service_id and subscription.instance_id == instance_id and subscription.major_version == major_version ): subscriptions_to_return.append((subscription, writer_id)) return subscriptions_to_return def remove_client(self, client_id: int): if client_id in self._subscriptions_by_client: del self._subscriptions_by_client[client_id] someipy-2.1.2/src/someipy/_internal/_daemon/uds_messages.py000066400000000000000000000103661513043235100240710ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import Any, List, TypeVar, TypedDict, get_type_hints class BaseMessage(TypedDict): type: str class OfferServiceRequest(BaseMessage): service_id: int instance_id: int major_version: int minor_version: int endpoint_ip: str endpoint_port: int ttl: int eventgroup_list: List[str] method_list: List[str] cyclic_offer_delay_ms: int class StopOfferServiceRequest(BaseMessage): service_id: int instance_id: int major_version: int minor_version: int endpoint_ip: str endpoint_port: int ttl: int eventgroup_list: List[str] method_list: List[str] cyclic_offer_delay_ms: int class FindServiceRequest(BaseMessage): service_id: int instance_id: int major_version: int minor_version: int class FindServiceResponse(BaseMessage): success: bool service_id: int instance_id: int major_version: int minor_version: int endpoint_ip: str endpoint_port: int class OutboundCallMethodRequest(BaseMessage): service_id: int instance_id: int method_id: int client_id: int session_id: int protocol_version: int major_version: int minor_version: int dst_endpoint_ip: str dst_endpoint_port: int src_endpoint_ip: str src_endpoint_port: int protocol: int payload: str class OutboundCallMethodResponse(BaseMessage): service_id: int method_id: int client_id: int session_id: int return_code: int dst_endpoint_ip: str dst_endpoint_port: int payload: str class InboundCallMethodRequest(BaseMessage): service_id: int instance_id: int method_id: int client_id: int session_id: int protocol_version: int interface_version: int major_version: int minor_version: int message_type: int src_endpoint_ip: str src_endpoint_port: int protocol: int payload: str class InboundCallMethodResponse(BaseMessage): service_id: int instance_id: int method_id: int client_id: int session_id: int protocol_version: int interface_version: int major_version: int minor_version: int message_type: int src_endpoint_ip: str src_endpoint_port: int protocol: int payload: str return_code: int class SendEventRequest(BaseMessage): service_id: int instance_id: int major_version: int client_id: int session_id: int eventgroup_id: int event: str # Serialized event object src_endpoint_ip: str src_endpoint_port: int payload: str class SubscribeEventGroupRequest(BaseMessage): service_id: int instance_id: int major_version: int ttl_subscription: int eventgroup: str client_endpoint_ip: str client_endpoint_port: int udp: bool tcp: bool class StopSubscribeEventGroupRequest(BaseMessage): service_id: int instance_id: int major_version: int eventgroup: str client_endpoint_ip: str client_endpoint_port: int udp: bool tcp: bool class ReceivedEvent(BaseMessage): service_id: int event_id: int src_endpoint_ip: str src_endpoint_port: str payload: str T = TypeVar("T", bound=BaseMessage) def create_uds_message(message_python_type: type[T], **kwargs: Any) -> T: type_value = message_python_type.__name__ message = {"type": type_value, **kwargs} # For development: Test if all keys are given using type inspection if set(message.keys()) != set(get_type_hints(message_python_type).keys()): raise RuntimeError( f"Invalid data passed to create_uds_message for type {type_value}" ) return message someipy-2.1.2/src/someipy/_internal/_sd/000077500000000000000000000000001513043235100201725ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/__init__.py000066400000000000000000000000001513043235100222710ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/deserialization/000077500000000000000000000000001513043235100233605ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/deserialization/__init__.py000066400000000000000000000000001513043235100254570ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/deserialization/sd_deserialization.py000066400000000000000000000524571513043235100276230ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from enum import Enum import ipaddress import socket import struct from someipy._internal._sd.entries.find_service_entry import FindServiceEntry from someipy._internal._sd.entries.offer_service_entry import OfferServiceEntry from someipy._internal._sd.entries.stop_offer_service_entry import StopOfferServiceEntry from someipy._internal._sd.entries.stop_subscribe_eventgroup_entry import ( StopSubscribeEventGroupEntry, ) from someipy._internal._sd.entries.subscribe_ack_entry import ( SubscribeAckEventGroupEntry, ) from someipy._internal._sd.entries.subscribe_eventgroup_entry import ( SubscribeEventGroupEntry, ) from someipy._internal._sd.entries.subscribe_eventgroup_nack import ( SubscribeEventGroupNackEntry, ) from someipy._internal._sd.options.configuration_option import ConfigurationOption from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) from someipy._internal._sd.options.load_balancing import LoadBalancingOption from someipy._internal._sd.options.multicast import ( IpV4MulticastOption, IpV6MulticastOption, ) from someipy._internal._sd.options.sd_endpoint import ( IpV4SdEndpointOption, IpV6SdEndpointOption, ) from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy._internal.utils import is_bit_set from someipy._internal._sd.sd_message import SdMessage SERVICE_ID_SD = 0xFFFF METHOD_ID_SD = 0x8100 CLIENT_ID_SD = 0x0000 PROTOCOL_VERSION_SD = 0x01 INTERFACE_VERSION_SD = 0x01 MESSAGE_TYPE_SD = 0x02 RETURN_CODE_SD = 0x00 MINIMAL_HEADER_SIZE = 16 class SdOptionOnWireType(Enum): CONFIGURATION = 0x01 LOAD_BALANCING = 0x02 IPV4_ENDPOINT = 0x04 IPV6_ENDPOINT = 0x06 IPV4_MULTICAST = 0x14 IPV6_MULTICAST = 0x16 IPV4_SD_ENDPOINT = 0x24 IPV6_SD_ENDPOINT = 0x26 class SdEntryOnWireType(Enum): FIND_SERVICE = 0x00 OFFER_SERVICE = 0x01 STOP_OFFER_SERVICE = 0x01 # with TTL to 0x000000 SUBSCRIBE_EVENT_GROUP = 0x06 STOP_SUBSCRIBE_EVENT_GROUP = 0x06 # with TTL to 0x000000 SUBSCRIBE_EVENT_GROUP_ACK = 0x07 SUBSCRIBE_EVENT_GROUP_NACK = 0x07 # with TTL to 0x000000 def is_sd_message(data: bytes) -> bool: if len(data) < MINIMAL_HEADER_SIZE: return False service_id, method_id, length = struct.unpack(">HHI", data[0:8]) if length < 12: return False if length > len(data) - 8: return False ( client_id, session_id, protocol_version, interface_version, message_type, return_code, ) = struct.unpack(">HHBBBB", data[8:16]) return ( service_id == SERVICE_ID_SD and method_id == METHOD_ID_SD and client_id == CLIENT_ID_SD and protocol_version == PROTOCOL_VERSION_SD and interface_version == INTERFACE_VERSION_SD and message_type == MESSAGE_TYPE_SD and return_code == RETURN_CODE_SD and session_id != 0 ) @dataclass class CommonEntryData: type_field_value: int index_first_option: int index_second_option: int num_options_1: int num_options_2: int service_id: int instance_id: int major_version: int ttl: int @dataclass class CommonOptionData: option_length: int option_type: SdOptionOnWireType discardable_flag: bool def deserialize_common_entry_data(data: bytes) -> CommonEntryData: type_field_value, index_first_option, index_second_option = struct.unpack( ">BBB", data[0:3] ) num_options_1 = struct.unpack(">B", data[3:4])[0] # higher 4 bits num_options_1 = (num_options_1 >> 4) & 0x0F num_options_2 = struct.unpack(">B", data[3:4])[0] # lower 4 bits num_options_2 = num_options_2 & 0x0F service_id, instance_id, major_version = struct.unpack(">HHB", data[4:9]) (ttl,) = struct.unpack(">I", data[8:12]) ttl = ttl & 0xFFFFFF return CommonEntryData( type_field_value, index_first_option, index_second_option, num_options_1, num_options_2, service_id, instance_id, major_version, ttl, ) def deserialize_common_option_data(data: bytes) -> CommonOptionData: option_length, option_type, discardable_flag_value = struct.unpack( ">HBB", data[0:4] ) option_type = SdOptionOnWireType(option_type) discardable_flag = is_bit_set(discardable_flag_value, 7) return CommonOptionData(option_length, option_type, discardable_flag) def deserialize_ipv4_endpoint_option(data: bytes) -> IpV4EndpointOption: ip1, ip2, ip3, ip4, _, protocol_value, port = struct.unpack(">BBBBBBH", data[0:8]) address = ipaddress.IPv4Address(f"{ip1}.{ip2}.{ip3}.{ip4}") protocol = TransportLayerProtocol(protocol_value) return IpV4EndpointOption(address=address, protocol=protocol, port=port) def deserialize_ipv6_endpoint_option(data: bytes) -> IpV6EndpointOption: packed = data[0:16] ipv6_str = socket.inet_ntop(socket.AF_INET6, packed) address = ipaddress.IPv6Address(ipv6_str) _, protocol_value, port = struct.unpack(">BBH", data[16:20]) protocol = TransportLayerProtocol(protocol_value) return IpV6EndpointOption(address=address, protocol=protocol, port=port) def deserialize_ipv4_multicast_option(data: bytes) -> IpV4MulticastOption: ip1, ip2, ip3, ip4, _, protocol_value, port = struct.unpack(">BBBBBBH", data[0:8]) address = ipaddress.IPv4Address(f"{ip1}.{ip2}.{ip3}.{ip4}") protocol = TransportLayerProtocol(protocol_value) return IpV4MulticastOption(address=address, protocol=protocol, port=port) def deserialize_ipv6_multicast_option(data: bytes) -> IpV6MulticastOption: packed = data[0:16] ipv6_str = socket.inet_ntop(socket.AF_INET6, packed) address = ipaddress.IPv6Address(ipv6_str) _, protocol_value, port = struct.unpack(">BBH", data[16:20]) protocol = TransportLayerProtocol(protocol_value) return IpV6MulticastOption(address=address, protocol=protocol, port=port) def deserialize_ipv4_sd_endpoint_option(data: bytes) -> IpV4SdEndpointOption: ip1, ip2, ip3, ip4, _, _, port = struct.unpack(">BBBBBBH", data[0:8]) address = ipaddress.IPv4Address(f"{ip1}.{ip2}.{ip3}.{ip4}") return IpV4SdEndpointOption(address=address, port=port) def deserialize_ipv6_sd_endpoint_option(data: bytes) -> IpV6SdEndpointOption: packed = data[0:16] ipv6_str = socket.inet_ntop(socket.AF_INET6, packed) address = ipaddress.IPv6Address(ipv6_str) _, _, port = struct.unpack(">BBH", data[16:20]) return IpV6SdEndpointOption(address=address, port=port) def deserialize_load_balancing_option(data: bytes) -> LoadBalancingOption: priority, weight = struct.unpack(">HH", data[0:4]) return LoadBalancingOption(priority=priority, weight=weight) def deserialize_sd_message( data: bytes, source: str, port: int, multicast: bool ) -> SdMessage: if not is_sd_message(data): raise ValueError("The provided data is not a valid SOME/IP-SD message.") service_id, method_id, length = struct.unpack(">HHI", data[0:8]) if length <= 0: raise ValueError(f"Length in SOME/IP header is <=0 ({length})") if length < 8: raise ValueError(f"Length in SOME/IP header is <8 ({length})") ( client_id, session_id, protocol_version, interface_version, message_type, return_code, ) = struct.unpack(">HHBBBB", data[8:16]) (flags,) = struct.unpack(">B", data[16:17]) reboot_flag = is_bit_set(flags, 7) unicast_flag = is_bit_set(flags, 6) # Constants for byte positions inside the SD header SD_POSITION_ENTRY_LENGTH = 20 SD_START_POSITION_ENTRIES = 24 # Constants for length of sections in the SD header SD_SINGLE_ENTRY_LENGTH_BYTES = 16 (length_entries,) = struct.unpack( ">I", data[SD_POSITION_ENTRY_LENGTH : SD_POSITION_ENTRY_LENGTH + 4] ) number_of_entries = int(length_entries / SD_SINGLE_ENTRY_LENGTH_BYTES) pos_length_options = SD_POSITION_ENTRY_LENGTH + 4 + length_entries (length_options,) = struct.unpack( ">I", data[pos_length_options : pos_length_options + 4] ) pos_start_options = pos_length_options + 4 current_pos_option = pos_start_options bytes_options_left = length_options options = [] while bytes_options_left > 0: common_option_data = deserialize_common_option_data( data[current_pos_option : current_pos_option + 4] ) option_type = common_option_data.option_type if option_type == SdOptionOnWireType.IPV4_ENDPOINT: sd_option = deserialize_ipv4_endpoint_option( data[current_pos_option + 4 : current_pos_option + 12] ) options.append(sd_option) elif option_type == SdOptionOnWireType.IPV6_ENDPOINT: sd_option = deserialize_ipv6_endpoint_option( data[current_pos_option + 4 : current_pos_option + 24] ) options.append(sd_option) elif option_type == SdOptionOnWireType.IPV4_MULTICAST: sd_option = deserialize_ipv4_multicast_option( data[current_pos_option + 4 : current_pos_option + 12] ) options.append(sd_option) elif option_type == SdOptionOnWireType.IPV6_MULTICAST: sd_option = deserialize_ipv6_multicast_option( data[current_pos_option + 4 : current_pos_option + 24] ) options.append(sd_option) elif option_type == SdOptionOnWireType.IPV4_SD_ENDPOINT: sd_option = deserialize_ipv4_sd_endpoint_option( data[current_pos_option + 4 : current_pos_option + 12] ) options.append(sd_option) elif option_type == SdOptionOnWireType.IPV6_SD_ENDPOINT: sd_option = deserialize_ipv6_sd_endpoint_option( data[current_pos_option + 4 : current_pos_option + 24] ) options.append(sd_option) elif option_type == SdOptionOnWireType.CONFIGURATION: dummy_config_option = ConfigurationOption() options.append(dummy_config_option) elif option_type == SdOptionOnWireType.LOAD_BALANCING: sd_option = deserialize_load_balancing_option( data[current_pos_option + 4 : current_pos_option + 8] ) options.append(sd_option) # Subtract 3 bytes first for length and type bytes_options_left -= common_option_data.option_length + 3 current_pos_option += common_option_data.option_length + 3 # Read in all Service and Event Group entries entries = [] for i in range(number_of_entries): start_entry = SD_START_POSITION_ENTRIES + (i * SD_SINGLE_ENTRY_LENGTH_BYTES) end_entry = start_entry + SD_SINGLE_ENTRY_LENGTH_BYTES common_entry_data = deserialize_common_entry_data( data[start_entry : start_entry + 12] ) if ( common_entry_data.type_field_value == SdEntryOnWireType.OFFER_SERVICE.value and common_entry_data.ttl != 0 ): (minor_version,) = struct.unpack( ">I", data[start_entry + 12 : start_entry + 16] ) applicable_options = [] for j in range(common_entry_data.num_options_1): applicable_options.append( options[common_entry_data.index_first_option + j] ) for j in range(common_entry_data.num_options_2): applicable_options.append( options[common_entry_data.index_second_option + j] ) offer_service_entry = OfferServiceEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, ttl=common_entry_data.ttl, ip_v4_endpoints=[ o for o in applicable_options if isinstance(o, IpV4EndpointOption) ], ip_v6_endpoints=[ o for o in applicable_options if isinstance(o, IpV6EndpointOption) ], ) entries.append(offer_service_entry) elif ( common_entry_data.type_field_value == SdEntryOnWireType.STOP_OFFER_SERVICE.value and common_entry_data.ttl == 0 ): (minor_version,) = struct.unpack( ">I", data[start_entry + 12 : start_entry + 16] ) applicable_options = [] for j in range(common_entry_data.num_options_1): applicable_options.append( options[common_entry_data.index_first_option + j] ) for j in range(common_entry_data.num_options_2): applicable_options.append( options[common_entry_data.index_second_option + j] ) stop_offer_service_entry = StopOfferServiceEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, ip_v4_endpoints=[ o for o in applicable_options if isinstance(o, IpV4EndpointOption) ], ip_v6_endpoints=[ o for o in applicable_options if isinstance(o, IpV6EndpointOption) ], ) entries.append(stop_offer_service_entry) elif common_entry_data.type_field_value == SdEntryOnWireType.FIND_SERVICE.value: (minor_version,) = struct.unpack( ">I", data[start_entry + 12 : start_entry + 16] ) find_service_entry = FindServiceEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, ) entries.append(find_service_entry) elif ( common_entry_data.type_field_value == SdEntryOnWireType.SUBSCRIBE_EVENT_GROUP.value and common_entry_data.ttl != 0 ): initial_data_requested_flag_counter_value, eventgroup_id = struct.unpack( ">BH", data[start_entry + 13 : start_entry + 16] ) initial_data_requested_flag = is_bit_set( initial_data_requested_flag_counter_value, 7 ) counter = initial_data_requested_flag_counter_value & 0xF applicable_options = [] for j in range(common_entry_data.num_options_1): applicable_options.append( options[common_entry_data.index_first_option + j] ) for j in range(common_entry_data.num_options_2): applicable_options.append( options[common_entry_data.index_second_option + j] ) subscribe_eventgroup_entry = SubscribeEventGroupEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, ttl=common_entry_data.ttl, eventgroup_id=eventgroup_id, counter=counter, ip_v4_endpoints=[ o for o in applicable_options if isinstance(o, IpV4EndpointOption) ], ip_v6_endpoints=[ o for o in applicable_options if isinstance(o, IpV6EndpointOption) ], ) entries.append(subscribe_eventgroup_entry) elif ( common_entry_data.type_field_value == SdEntryOnWireType.STOP_SUBSCRIBE_EVENT_GROUP.value and common_entry_data.ttl == 0 ): initial_data_requested_flag_counter_value, eventgroup_id = struct.unpack( ">BH", data[start_entry + 13 : start_entry + 16] ) initial_data_requested_flag = is_bit_set( initial_data_requested_flag_counter_value, 7 ) counter = initial_data_requested_flag_counter_value & 0xF applicable_options = [] for j in range(common_entry_data.num_options_1): applicable_options.append( options[common_entry_data.index_first_option + j] ) for j in range(common_entry_data.num_options_2): applicable_options.append( options[common_entry_data.index_second_option + j] ) stop_subscribe_eventgroup_entry = StopSubscribeEventGroupEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, ttl=common_entry_data.ttl, ip_v4_endpoints=[ o for o in applicable_options if isinstance(o, IpV4EndpointOption) ], ip_v6_endpoints=[ o for o in applicable_options if isinstance(o, IpV6EndpointOption) ], ) entries.append(stop_subscribe_eventgroup_entry) elif ( common_entry_data.type_field_value == SdEntryOnWireType.SUBSCRIBE_EVENT_GROUP_ACK.value and common_entry_data.ttl != 0 ): initial_data_requested_flag_counter_value, eventgroup_id = struct.unpack( ">BH", data[start_entry + 13 : start_entry + 16] ) initial_data_requested_flag = is_bit_set( initial_data_requested_flag_counter_value, 7 ) counter = initial_data_requested_flag_counter_value & 0xF applicable_options = [] for j in range(common_entry_data.num_options_1): applicable_options.append( options[common_entry_data.index_first_option + j] ) for j in range(common_entry_data.num_options_2): applicable_options.append( options[common_entry_data.index_second_option + j] ) subscribe_ack_eventgroup_entry = SubscribeAckEventGroupEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, ttl=common_entry_data.ttl, eventgroup_id=eventgroup_id, counter=counter, ip_v4_endpoints=[ o for o in applicable_options if isinstance(o, IpV4EndpointOption) ], ip_v6_endpoints=[ o for o in applicable_options if isinstance(o, IpV6EndpointOption) ], ) entries.append(subscribe_ack_eventgroup_entry) elif ( common_entry_data.type_field_value == SdEntryOnWireType.SUBSCRIBE_EVENT_GROUP_NACK.value and common_entry_data.ttl == 0 ): initial_data_requested_flag_counter_value, eventgroup_id = struct.unpack( ">BH", data[start_entry + 13 : start_entry + 16] ) initial_data_requested_flag = is_bit_set( initial_data_requested_flag_counter_value, 7 ) counter = initial_data_requested_flag_counter_value & 0xF applicable_options = [] for j in range(common_entry_data.num_options_1): applicable_options.append( options[common_entry_data.index_first_option + j] ) for j in range(common_entry_data.num_options_2): applicable_options.append( options[common_entry_data.index_second_option + j] ) subscribe_ack_eventgroup_entry = SubscribeEventGroupNackEntry( service_id=common_entry_data.service_id, instance_id=common_entry_data.instance_id, major_version=common_entry_data.major_version, minor_version=minor_version, eventgroup_id=eventgroup_id, counter=counter, ) entries.append(subscribe_ack_eventgroup_entry) sd_message = SdMessage() sd_message.source = source sd_message.source_port = port sd_message.multicast = multicast sd_message.session_id = session_id sd_message.reboot_flag = reboot_flag sd_message.entries = entries return sd_message someipy-2.1.2/src/someipy/_internal/_sd/deserialization/sd_serialization.py000066400000000000000000000212611513043235100272770ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import socket import struct from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) from someipy._internal._sd.entries.sd_entry import SdEntryType from someipy._internal.utils import set_bit_at_position from someipy._internal._sd.sd_message import SdMessage SERVICE_ID_SD = 0xFFFF METHOD_ID_SD = 0x8100 CLIENT_ID_SD = 0x0000 PROTOCOL_VERSION_SD = 0x01 INTERFACE_VERSION_SD = 0x01 MESSAGE_TYPE_SD = 0x02 RETURN_CODE_SD = 0x00 MINIMAL_HEADER_SIZE = 16 def entry_type_to_on_wire(entry_type: SdEntryType) -> int: lookup = { SdEntryType.FIND_SERVICE: 0x00, SdEntryType.OFFER_SERVICE: 0x01, SdEntryType.STOP_OFFER_SERVICE: 0x01, # with TTL to 0x000000 SdEntryType.SUBSCRIBE_EVENT_GROUP: 0x06, SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP: 0x06, # with TTL to 0x000000 SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK: 0x07, SdEntryType.SUBSCRIBE_EVENT_GROUP_NACK: 0x07, } if entry_type not in lookup: raise ValueError(f"Unsupported SdEntryType: {entry_type}") return lookup[entry_type] def serialize_ipv4_endpoint_option(option: IpV4EndpointOption) -> bytes: output = bytes() LENGTH = 0x0009 TYPE = 0x04 discardable_flag_value = set_bit_at_position(0, 7, False) output += struct.pack(">HBB", LENGTH, TYPE, discardable_flag_value) output += struct.pack( ">IBBH", int(option.address), 0, option.protocol.value, option.port ) return output def serialize_ipv6_endpoint_option(option: IpV6EndpointOption) -> bytes: output = bytes() LENGTH = 0x0015 TYPE = 0x06 ipv6_str = str(option.address) packed_ip = socket.inet_pton(socket.AF_INET6, ipv6_str) discardable_flag_value = set_bit_at_position(0, 7, False) output += struct.pack(">HBB", LENGTH, TYPE, discardable_flag_value) output += packed_ip output += struct.pack(">BBH", 0, option.protocol.value, option.port) return output def serialize_sd_message(sd_message: SdMessage) -> bytes: output = bytes() SERVICE_ID_SD = 0xFFFF METHOD_ID_SD = 0x8100 CLIENT_ID_SD = 0x0000 PROTOCOL_VERSION_SD = 0x01 INTERFACE_VERSION_SD = 0x01 MESSAGE_TYPE_SD = 0x02 RETURN_CODE_SD = 0x00 output += struct.pack( ">HHIHHBBBB", SERVICE_ID_SD, METHOD_ID_SD, 0, CLIENT_ID_SD, sd_message.session_id, PROTOCOL_VERSION_SD, INTERFACE_VERSION_SD, MESSAGE_TYPE_SD, RETURN_CODE_SD, ) # TODO: Set the reboot flag properly reboot_flag = False unicast_flag = True flags = 0 flags = set_bit_at_position(flags, 31, reboot_flag) flags = set_bit_at_position(flags, 30, unicast_flag) output += struct.pack(">I", flags) # 8 bit flags + 24 reserved bits options = [] option_set = set() for entry in sd_message.entries: if entry.type in [ SdEntryType.OFFER_SERVICE, SdEntryType.STOP_OFFER_SERVICE, SdEntryType.SUBSCRIBE_EVENT_GROUP, SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP, ]: for endpoint in entry.ip_v4_endpoints: if endpoint not in option_set: option_set.add(endpoint) options.append(endpoint) for endpoint in entry.ip_v6_endpoints: if endpoint not in option_set: option_set.add(endpoint) options.append(endpoint) # Length of the entries array SD_SINGLE_ENTRY_LENGTH_BYTES = 16 length_entries_array = len(sd_message.entries) * SD_SINGLE_ENTRY_LENGTH_BYTES output += struct.pack(">I", length_entries_array) for entry in sd_message.entries: if entry.type in [ SdEntryType.OFFER_SERVICE, SdEntryType.STOP_OFFER_SERVICE, SdEntryType.FIND_SERVICE, ]: if entry.type == SdEntryType.OFFER_SERVICE: ttl = entry.ttl else: ttl = 0 ttl_high = (ttl & 0xFF0000) >> 16 ttl_low = ttl & 0xFFFF index_first_option = 0 if entry.type == SdEntryType.FIND_SERVICE: num_options_1 = 0 index_first_option = 0 else: num_options_1 = len(entry.ip_v4_endpoints) + len(entry.ip_v6_endpoints) if num_options_1 > 2: raise ValueError("Too many options for entry configured.") entry_options = set(entry.ip_v4_endpoints + entry.ip_v6_endpoints) for i in range(len(options)): if options[i] in entry_options: index_first_option = i break num_options_2 = 0 # No second option in this implementation num_options = (num_options_1 << 4) | num_options_2 index_second_option = 0 # No second option in this implementation output += struct.pack( ">BBBBHHBBH", entry_type_to_on_wire(entry.type), index_first_option, index_second_option, num_options, entry.service_id, entry.instance_id, entry.major_version, ttl_high, ttl_low, ) output += struct.pack(">I", entry.minor_version) else: if entry.type in [ SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP, SdEntryType.SUBSCRIBE_EVENT_GROUP_NACK, ]: ttl = 0 else: ttl = entry.ttl ttl_high = (ttl & 0xFF0000) >> 16 ttl_low = ttl & 0xFFFF if entry.type in [ SdEntryType.SUBSCRIBE_EVENT_GROUP, SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP, ]: num_options_1 = len(entry.ip_v4_endpoints) + len(entry.ip_v6_endpoints) if num_options_1 > 2: raise ValueError("Too many options for entry configured.") entry_options = set(entry.ip_v4_endpoints + entry.ip_v6_endpoints) for i in range(len(options)): if options[i] in entry_options: index_first_option = i break else: num_options_1 = 0 index_first_option = 0 num_options_2 = 0 # No second option in this implementation num_options = (num_options_1 << 4) | num_options_2 index_second_option = 0 # No second option in this implementation output += struct.pack( ">BBBBHHBBH", entry_type_to_on_wire(entry.type), index_first_option, index_second_option, num_options, entry.service_id, entry.instance_id, entry.major_version, ttl_high, ttl_low, ) initial_data_requested_flag_counter_value = set_bit_at_position(0, 7, True) initial_data_requested_flag_counter_value = ( initial_data_requested_flag_counter_value | (entry.counter & 0xF) ) output += struct.pack( ">BBH", 0, initial_data_requested_flag_counter_value, entry.eventgroup_id, ) length_of_options = 0 for option in options: if isinstance(option, IpV4EndpointOption): length_of_options += 12 elif isinstance(option, IpV6EndpointOption): length_of_options += 24 output += struct.pack(">I", length_of_options) for option in options: if isinstance(option, IpV4EndpointOption): output += serialize_ipv4_endpoint_option(option) elif isinstance(option, IpV6EndpointOption): output += serialize_ipv6_endpoint_option(option) total_length = len(output) - 8 total_length_bytes = struct.pack(">I", total_length) output = output[:4] + total_length_bytes + output[8:] return output someipy-2.1.2/src/someipy/_internal/_sd/entries/000077500000000000000000000000001513043235100216435ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/entries/__init__.py000066400000000000000000000000001513043235100237420ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/entries/find_service_entry.py000066400000000000000000000023711513043235100261010ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType @dataclass class FindServiceEntry(SdEntry): service_id: int instance_id: int major_version: int minor_version: int def __init__( self, service_id: int, instance_id: int, major_version: int, minor_version: int, ): super().__init__(SdEntryType.FIND_SERVICE) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.minor_version = minor_version someipy-2.1.2/src/someipy/_internal/_sd/entries/offer_service_entry.py000066400000000000000000000033171513043235100262630ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from typing import List from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) @dataclass class OfferServiceEntry(SdEntry): service_id: int instance_id: int major_version: int minor_version: int ttl: int ip_v4_endpoints: List[IpV4EndpointOption] ip_v6_endpoints: List[IpV6EndpointOption] def __init__( self, service_id: int, instance_id: int, major_version: int, minor_version: int, ttl: int, ip_v4_endpoints: List[IpV4EndpointOption], ip_v6_endpoints: List[IpV6EndpointOption], ): super().__init__(SdEntryType.OFFER_SERVICE) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.minor_version = minor_version self.ttl = ttl self.ip_v4_endpoints = ip_v4_endpoints self.ip_v6_endpoints = ip_v6_endpoints someipy-2.1.2/src/someipy/_internal/_sd/entries/sd_entry.py000066400000000000000000000021501513043235100240420ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from enum import Enum, unique @unique class SdEntryType(Enum): FIND_SERVICE = 0 OFFER_SERVICE = 1 STOP_OFFER_SERVICE = 2 SUBSCRIBE_EVENT_GROUP = 3 STOP_SUBSCRIBE_EVENT_GROUP = 4 SUBSCRIBE_EVENT_GROUP_ACK = 5 SUBSCRIBE_EVENT_GROUP_NACK = 6 class SdEntry: def __init__(self, entry_type: SdEntryType): self._entry_type = entry_type @property def type(self) -> SdEntryType: return self._entry_type someipy-2.1.2/src/someipy/_internal/_sd/entries/stop_offer_service_entry.py000066400000000000000000000032601513043235100273250ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from typing import List from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) @dataclass class StopOfferServiceEntry(SdEntry): service_id: int instance_id: int major_version: int minor_version: int ttl: int ip_v4_endpoints: List[IpV4EndpointOption] ip_v6_endpoints: List[IpV6EndpointOption] def __init__( self, service_id: int, instance_id: int, major_version: int, minor_version: int, ip_v4_endpoints: List[IpV4EndpointOption], ip_v6_endpoints: List[IpV6EndpointOption], ): super().__init__(SdEntryType.STOP_OFFER_SERVICE) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.minor_version = minor_version self.ip_v4_endpoints = ip_v4_endpoints self.ip_v6_endpoints = ip_v6_endpoints someipy-2.1.2/src/someipy/_internal/_sd/entries/stop_subscribe_eventgroup_entry.py000066400000000000000000000033701513043235100307450ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from typing import List from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) @dataclass class StopSubscribeEventGroupEntry(SdEntry): service_id: int instance_id: int major_version: int eventgroup_id: int counter: int ip_v4_endpoints: List[IpV4EndpointOption] ip_v6_endpoints: List[IpV6EndpointOption] def __init__( self, service_id: int, instance_id: int, major_version: int, eventgroup_id: int, counter: int, ip_v4_endpoints: List[IpV4EndpointOption], ip_v6_endpoints: List[IpV6EndpointOption], ): super().__init__(SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.eventgroup_id = eventgroup_id self.counter = counter self.ip_v4_endpoints = ip_v4_endpoints self.ip_v6_endpoints = ip_v6_endpoints someipy-2.1.2/src/someipy/_internal/_sd/entries/subscribe_ack_entry.py000066400000000000000000000026441513043235100262430ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType @dataclass class SubscribeAckEventGroupEntry(SdEntry): service_id: int instance_id: int major_version: int minor_version: int ttl: int eventgroup_id: int counter: int def __init__( self, service_id: int, instance_id: int, major_version: int, ttl: int, eventgroup_id: int, counter: int, ): super().__init__(SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.ttl = ttl self.eventgroup_id = eventgroup_id self.counter = counter someipy-2.1.2/src/someipy/_internal/_sd/entries/subscribe_eventgroup_entry.py000066400000000000000000000034451513043235100277030ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from typing import List from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) @dataclass class SubscribeEventGroupEntry(SdEntry): service_id: int instance_id: int major_version: int ttl: int eventgroup_id: int counter: int ip_v4_endpoints: List[IpV4EndpointOption] ip_v6_endpoints: List[IpV6EndpointOption] def __init__( self, service_id: int, instance_id: int, major_version: int, ttl: int, eventgroup_id: int, counter: int, ip_v4_endpoints: List[IpV4EndpointOption], ip_v6_endpoints: List[IpV6EndpointOption], ): super().__init__(SdEntryType.SUBSCRIBE_EVENT_GROUP) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.ttl = ttl self.eventgroup_id = eventgroup_id self.counter = counter self.ip_v4_endpoints = ip_v4_endpoints self.ip_v6_endpoints = ip_v6_endpoints someipy-2.1.2/src/someipy/_internal/_sd/entries/subscribe_eventgroup_nack.py000066400000000000000000000025601513043235100274530ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from someipy._internal._sd.entries.sd_entry import SdEntry, SdEntryType @dataclass class SubscribeEventGroupNackEntry(SdEntry): service_id: int instance_id: int major_version: int minor_version: int eventgroup_id: int counter: int def __init__( self, service_id: int, instance_id: int, major_version: int, eventgroup_id: int, counter: int, ): super().__init__(SdEntryType.SUBSCRIBE_EVENT_GROUP_NACK) self.service_id = service_id self.instance_id = instance_id self.major_version = major_version self.eventgroup_id = eventgroup_id self.counter = counter someipy-2.1.2/src/someipy/_internal/_sd/options/000077500000000000000000000000001513043235100216655ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/options/__init__.py000066400000000000000000000000001513043235100237640ustar00rootroot00000000000000someipy-2.1.2/src/someipy/_internal/_sd/options/configuration_option.py000066400000000000000000000014061513043235100264770ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass @dataclass class ConfigurationOption: key: str value: str someipy-2.1.2/src/someipy/_internal/_sd/options/endpoint.py000066400000000000000000000021111513043235100240520ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass import ipaddress from someipy._internal.transport_layer_protocol import TransportLayerProtocol @dataclass(eq=True, frozen=True) class IpV4EndpointOption: address: ipaddress.IPv4Address protocol: TransportLayerProtocol port: int @dataclass(eq=True, frozen=True) class IpV6EndpointOption: address: ipaddress.IPv6Address protocol: TransportLayerProtocol port: int someipy-2.1.2/src/someipy/_internal/_sd/options/load_balancing.py000066400000000000000000000014151513043235100251550ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass @dataclass class LoadBalancingOption: priority: int weight: int someipy-2.1.2/src/someipy/_internal/_sd/options/multicast.py000066400000000000000000000020371513043235100242460ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass import ipaddress from someipy._internal.transport_layer_protocol import TransportLayerProtocol @dataclass class IpV4MulticastOption: address: ipaddress.IPv4Address protocol: TransportLayerProtocol port: int @dataclass class IpV6MulticastOption: address: ipaddress.IPv6Address protocol: TransportLayerProtocol port: int someipy-2.1.2/src/someipy/_internal/_sd/options/sd_endpoint.py000066400000000000000000000016101513043235100245430ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass import ipaddress @dataclass class IpV4SdEndpointOption: address: ipaddress.IPv4Address port: int @dataclass class IpV6SdEndpointOption: address: ipaddress.IPv6Address port: int someipy-2.1.2/src/someipy/_internal/_sd/sd_message.py000066400000000000000000000020321513043235100226530ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import List from someipy._internal._sd.entries.sd_entry import SdEntry class SdMessage: def __init__(self): self.source: str = "" self.source_port: int = 0 self.multicast: bool = True self.timestamp: float = 0.0 self.session_id: int = 0 self.reboot_flag: bool = False self.entries: List[SdEntry] = [] someipy-2.1.2/src/someipy/_internal/_sd/sd_message_creator.py000066400000000000000000000123051513043235100243760ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import Iterable from someipy._internal._daemon.offer_service_storage import ServiceToOffer from someipy._internal._sd.entries.offer_service_entry import OfferServiceEntry from someipy._internal._sd.entries.stop_offer_service_entry import StopOfferServiceEntry from someipy._internal._sd.options.endpoint import IpV4EndpointOption from someipy._internal._sd.sd_message import SdMessage from someipy._internal.transport_layer_protocol import TransportLayerProtocol def create_offer_service_message( services_to_offer: Iterable[ServiceToOffer], session_id: int, reboot_flag: bool ) -> SdMessage: options = set() for service in services_to_offer: if service.has_udp: options.add( IpV4EndpointOption( address=service.endpoint.ip, protocol=TransportLayerProtocol.UDP, port=service.endpoint.port, ) ) if service.has_tcp: options.add( IpV4EndpointOption( address=service.endpoint.ip, protocol=TransportLayerProtocol.TCP, port=service.endpoint.port, ) ) options = list(options) sd_message = SdMessage() sd_message.session_id = session_id sd_message.reboot_flag = reboot_flag for service in services_to_offer: endpoints = [] if service.has_udp: endpoints.extend( [ option for option in options if option.protocol == TransportLayerProtocol.UDP and option.address == service.endpoint.ip and option.port == service.endpoint.port ] ) if service.has_tcp: endpoints.extend( [ option for option in options if option.protocol == TransportLayerProtocol.TCP and option.address == service.endpoint.ip and option.port == service.endpoint.port ] ) new_entry = OfferServiceEntry( service_id=service.service_id, instance_id=service.instance_id, major_version=service.major_version, minor_version=service.minor_version, ttl=service.offer_ttl_seconds, ip_v4_endpoints=endpoints, ip_v6_endpoints=[], ) sd_message.entries.append(new_entry) return sd_message def create_stop_offer_service_message( services_to_stop: Iterable[ServiceToOffer], session_id: int, reboot_flag: bool ) -> SdMessage: options = set() for service in services_to_stop: if service.has_udp: options.add( IpV4EndpointOption( address=service.endpoint.ip, protocol=TransportLayerProtocol.UDP, port=service.endpoint.port, ) ) if service.has_tcp: options.add( IpV4EndpointOption( address=service.endpoint.ip, protocol=TransportLayerProtocol.TCP, port=service.endpoint.port, ) ) options = list(options) sd_message = SdMessage() sd_message.session_id = session_id sd_message.reboot_flag = reboot_flag for service in services_to_stop: endpoints = [] if service.has_udp: endpoints.extend( [ option for option in options if option.protocol == TransportLayerProtocol.UDP and option.address == service.endpoint.ip and option.port == service.endpoint.port ] ) if service.has_tcp: endpoints.extend( [ option for option in options if option.protocol == TransportLayerProtocol.TCP and option.address == service.endpoint.ip and option.port == service.endpoint.port ] ) new_entry = StopOfferServiceEntry( service_id=service.service_id, instance_id=service.instance_id, major_version=service.major_version, minor_version=service.minor_version, ip_v4_endpoints=endpoints, ip_v6_endpoints=[], ) sd_message.entries.append(new_entry) return sd_message someipy-2.1.2/src/someipy/_internal/_sd/service_instance.py000066400000000000000000000033451513043235100240750ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from someipy._internal._common.endpoint import Endpoint from someipy._internal.transport_layer_protocol import TransportLayerProtocol @dataclass class ServiceInstance: """This class aggregates data from entries and options and provides a compact interface instead of loose SD entries and options""" service_id: int instance_id: int major_version: int minor_version: int ttl: int endpoint: Endpoint protocols: frozenset[TransportLayerProtocol] timestamp: float def __eq__(self, other: object) -> bool: if not isinstance(other, ServiceInstance): return False # Ignore the timestamp in equality comparison return ( self.service_id == other.service_id and self.instance_id == other.instance_id and self.major_version == other.major_version and self.minor_version == other.minor_version and self.ttl == other.ttl and self.endpoint == other.endpoint and self.protocols == other.protocols ) someipy-2.1.2/src/someipy/_internal/daemon_client_abcs.py000066400000000000000000000033361513043235100235750ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from abc import ABC, abstractmethod from typing import Tuple from someipy._internal._daemon.uds_messages import ( InboundCallMethodResponse, ReceivedEvent, ) from someipy.service import Service class ClientInstanceInterface(ABC): @abstractmethod def _method_call_data_received(self, message: InboundCallMethodResponse) -> None: pass @abstractmethod def _event_data_received(self, message: ReceivedEvent) -> None: pass @property @abstractmethod def service(self) -> Service: pass @property @abstractmethod def instance_id(self) -> int: pass @property @abstractmethod def endpoint(self) -> Tuple[str, int]: pass class ServerInstanceInterface(ABC): @property @abstractmethod def service(self) -> Service: pass @property @abstractmethod def instance_id(self) -> int: pass @property @abstractmethod def endpoint_ip(self) -> str: pass @property @abstractmethod def endpoint_port(self) -> int: pass someipy-2.1.2/src/someipy/_internal/logging.py000066400000000000000000000031441513043235100214270ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import sys from someipy.someipy_logging import get_someipy_log_level def setup_console_handler( formatter: logging.Formatter, level: int ) -> logging.StreamHandler: console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(level) console_handler.setFormatter(formatter) return console_handler def get_logger(name: str) -> logging.Logger: logger = logging.getLogger(f"someipy.{name}") log_level = get_someipy_log_level() formatter = logging.Formatter( "%(asctime)s.%(msecs)03d %(name)s [%(levelname)s]: %(message)s", datefmt="%Y-%m-%d,%H:%M:%S", ) # Check if the logger already has a console handler if not any( isinstance(handler, logging.StreamHandler) for handler in logger.handlers ): console_handler = setup_console_handler(formatter, log_level) logger.addHandler(console_handler) logger.setLevel(log_level) return logger someipy-2.1.2/src/someipy/_internal/message_types.py000066400000000000000000000016721513043235100226550ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from enum import Enum class MessageType(Enum): REQUEST = 0x00 REQUEST_NO_RETURN = 0x01 NOTIFICATION = 0x02 RESPONSE = 0x80 ERROR = 0x81 TP_REQUEST = 0x20 TP_REQUEST_NO_RETURN = 0x21 TP_NOTIFICATION = 0x22 TP_RESPONSE = 0xA0 TP_ERROR = 0xA1 someipy-2.1.2/src/someipy/_internal/method_result.py000066400000000000000000000020321513043235100226520ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from .message_types import MessageType from .return_codes import ReturnCode class MethodResult: """Class representing the result of a method call.""" message_type: MessageType return_code: ReturnCode payload: bytes def __init__(self): self.message_type = MessageType.RESPONSE self.return_code = ReturnCode.E_OK self.payload = b"" someipy-2.1.2/src/someipy/_internal/return_codes.py000066400000000000000000000031441513043235100224750ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from enum import Enum # PRS_SOMEIP_00191 class ReturnCode(Enum): E_OK = 0x00 # No error occurred E_NOT_OK = 0x01 # An unspecified error occurred E_UNKNOWN_SERVICE = 0x02 # The requested Service ID is unknown. E_UNKNOWN_METHOD = 0x03 # The requested Method ID is unknown. E_NOT_READY = 0x04 # Service ID and Method ID are known. Application not running. E_NOT_REACHABLE = ( 0x05 # System running the service is not reachable (internal error code only). ) E_TIMEOUT = 0x06 # A timeout occurred (internal error code only). E_WRONG_PROTOCOL_VERSION = 0x07 # Version of SOME/IP protocol not supported E_WRONG_INTERFACE_VERSION = 0x08 # Interface version mismatch E_MALFORMED_MESSAGE = ( 0x09 # Deserialization error, so that payload cannot be de-serialized. ) E_WRONG_MESSAGE_TYPE = 0x0A # An unexpected message type was received (e.g. REQUEST_NO_RETURN for a method defined as REQUEST). someipy-2.1.2/src/someipy/_internal/session_handler.py000066400000000000000000000021321513043235100231550ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import Tuple class SessionHandler: session_id: int reboot_flag: bool def __init__(self, initial_value=0): self.session_id = initial_value self.reboot_flag = True def update_session(self) -> Tuple[int, bool]: self.session_id += 1 if self.session_id > 0xFFFF: self.session_id = 1 self.reboot_flag = False return self.session_id, self.reboot_flagsomeipy-2.1.2/src/someipy/_internal/simple_timer.py000066400000000000000000000032451513043235100224740ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio import time class SimplePeriodicTimer: def __init__(self, period, callback): self._period = period self._callback = callback self._task = None self._running = False async def _job(self): try: while True: start = time.time() self._callback() elapsed = time.time() - start to_sleep = self._period - elapsed if elapsed > self._period: to_sleep = 0 await asyncio.sleep(to_sleep) except asyncio.CancelledError: self._running = False def start(self): if not self._running: self._running = True loop = asyncio.get_running_loop() self._task = loop.create_task(self._job()) def stop(self): if self._running and self._task is not None: self._task.cancel() self._running = False @property def task(self): return self._task someipy-2.1.2/src/someipy/_internal/someip_data_processor.py000066400000000000000000000057601513043235100243730ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from enum import Enum import struct from someipy._internal.someip_header import SomeIpHeader from someipy._internal.someip_message import SomeIpMessage class SomeipDataProcessor: class State(Enum): HEADER = 1 PAYLOAD = 2 PENDING = 3 def __init__(self): self._reset() self._someip_message = None def _reset(self): self._state = SomeipDataProcessor.State.HEADER self._buffer = bytes() self._expected_bytes = 8 # 2x 32-bit for header self._total_length = 0 def process_data(self, new_data: bytes) -> bool: self._buffer += new_data current_length = len(self._buffer) if self._state == SomeipDataProcessor.State.HEADER: if current_length < self._expected_bytes: # The header was not fully received yet return False else: _, _, length = struct.unpack(">HHI", self._buffer[0:8]) self._total_length = length + 8 self._expected_bytes = self._total_length - current_length self._state = SomeipDataProcessor.State.PAYLOAD if self._state == SomeipDataProcessor.State.PAYLOAD: if current_length < self._total_length: # The payload was not fully received yet self._expected_bytes = self._total_length - current_length return False else: payload_length = self._total_length - 16 header = SomeIpHeader.from_buffer(self._buffer) self._someip_message = SomeIpMessage( header=header, payload=self._buffer[16 : (16 + payload_length)] ) self._state = SomeipDataProcessor.State.HEADER # If more data was received over the current message boundary, keep the data self._buffer = self._buffer[self._total_length :] self._expected_bytes = 8 self._total_length = 0 return True @property def someip_message(self): """Returns the SomeIpMessage that was received and interpreted""" return self._someip_message @property def expected_bytes(self): """Returns the number of bytes that are expected to complete the current message""" return self._expected_bytes someipy-2.1.2/src/someipy/_internal/someip_endpoint.py000066400000000000000000000240421513043235100231750ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio from abc import ABC, abstractmethod, abstractproperty from logging import Logger from typing import Callable, Tuple, Any, Union from someipy._internal.logging import get_logger from someipy._internal.someip_message import SomeIpMessage from someipy._internal.tcp_client_manager import ( TcpClientManagerInterface, TcpClientProtocolInterface, ) from someipy._internal.tcp_connection import TcpConnection from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy._internal.utils import EndpointType from someipy._internal.someip_data_processor import SomeipDataProcessor class SomeipEndpoint(ABC): """ A class representing an endpoint (UDP or TCP) which fires a callback when a SomeIpMessage is received. It can also send messages to a specific endpoint or broadcast to all connected endpoints (for UDP multicast or to all connected TCP clients). """ @abstractmethod def set_someip_callback( self, callback_func: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ], ) -> None: pass @abstractmethod def sendto(self, data: bytes, addr: EndpointType) -> None: pass @abstractmethod def sendtoall(self, data: bytes) -> None: pass @abstractmethod def shutdown(self) -> None: pass @abstractmethod def protocol(self) -> TransportLayerProtocol: pass @abstractmethod def src_ip(self) -> str: pass @abstractmethod def src_port(self) -> int: pass @abstractmethod def dst_ip(self) -> str: pass @abstractmethod def dst_port(self) -> int: pass class UDPSomeipEndpoint(SomeipEndpoint, asyncio.DatagramProtocol): def __init__(self, ip: str, port: int): self._callback: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ] = None self._transport = None self._processor = SomeipDataProcessor() self._protocol = TransportLayerProtocol.UDP self._ip = ip self._port = port def set_someip_callback( self, callback_func: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ], ) -> None: self._callback = callback_func def connection_made(self, transport: asyncio.DatagramTransport) -> None: self._transport = transport def connection_lost(self, exc: Exception) -> None: pass def datagram_received(self, data: bytes, addr: Tuple[Union[str, Any, int]]) -> None: result = self._processor.process_data(data) if result and self._callback is not None: self._callback( self._processor.someip_message, addr, (self._ip, self._port), self._protocol, ) def sendto(self, data: bytes, addr: EndpointType) -> None: if self._transport is not None: self._transport.sendto(data, (str(addr[0]), addr[1])) def sendtoall(self, data: bytes) -> None: # TODO: Implement for multicast support raise NotImplementedError("No implementation for UDP yet") def shutdown(self) -> None: if self._transport is not None: self._transport.close() def protocol(self) -> TransportLayerProtocol: return self._protocol def src_ip(self) -> str: return self._ip def src_port(self) -> int: return self._port def dst_ip(self) -> str: return 0 def dst_port(self) -> int: return 0 class TCPSomeipEndpoint(SomeipEndpoint): def __init__(self, server, manager, ip: str, port: int): self._server: asyncio.Server = server self._manager: TcpClientManagerInterface = manager self._protocol: TransportLayerProtocol = TransportLayerProtocol.TCP self._ip = ip self._port = port def set_someip_callback( self, callback_func: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ], ) -> None: self._manager.register_callback(callback_func) def sendto(self, data: bytes, addr: EndpointType) -> None: if self._manager is None: return client: TcpClientProtocolInterface = self._manager.get_client(addr[0], addr[1]) if client is not None: client.write(data) def sendtoall(self, data: bytes) -> None: if self._manager is None: return for c in self._manager.get_all_clients(): c.write(data) def shutdown(self) -> None: if self._manager is None: return self._server.close() def protocol(self) -> TransportLayerProtocol: return self._protocol def src_ip(self) -> str: return self._ip def src_port(self) -> int: return self._port def dst_ip(self) -> str: return 0 def dst_port(self) -> int: return 0 class TCPClientSomeipEndpoint(SomeipEndpoint): def __init__( self, dst_ip: str, dst_port: str, src_ip: str, src_port: str, logger: Logger = None, ): self._tcp_connection: TcpConnection = None self._protocol: TransportLayerProtocol = TransportLayerProtocol.TCP self._dst_ip = dst_ip self._dst_port = dst_port self._src_ip = src_ip self._src_port = src_port self._logger = logger self._callback: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ] = None self._connect_and_receive_task: asyncio.Task = asyncio.create_task( self._connect_and_receive() ) def _log(self, message: str) -> None: if self._logger: self._logger.debug(message) def is_connected(self) -> bool: return self._tcp_connection is not None and self._tcp_connection.is_open() async def _connect_and_receive(self) -> None: try: while True: self._log(f"Trying to connect to ({self._dst_ip}, {self._dst_port})") self._tcp_connection = TcpConnection(self._dst_ip, self._dst_port) try: await self._tcp_connection.connect(self._src_ip, self._src_port) except OSError: self._log( f"Connection refused while connecting to ({self._dst_ip}, {self._dst_port}). Try to reconnect in 1 second" ) # Wait a second before trying to connect again await asyncio.sleep(1.0) continue self._log(f"Start reading on port {self._src_port}") someip_processor = SomeipDataProcessor() while self._tcp_connection.is_open(): try: new_data = await asyncio.wait_for( self._tcp_connection.reader.read( someip_processor.expected_bytes ), 3.0, ) if someip_processor.process_data(new_data): self._callback( someip_processor.someip_message, (self._dst_ip, self._dst_port), (self._src_ip, self._src_port), self._protocol, ) except asyncio.TimeoutError: self._log( f"Timeout reading from TCP connection ({self._src_ip}, {self._src_port})" ) except Exception as e: self._log( f"Error while reading from TCP connection ({self._src_ip}, {self._src_port}): {e}" ) await self._tcp_connection.close() except asyncio.CancelledError: if self._tcp_connection.is_open(): await self._tcp_connection.close() self._log("TCP task is cancelled. Raise again.") raise def set_someip_callback( self, callback_func: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ], ) -> None: self._callback = callback_func def sendto(self, data: bytes, addr: EndpointType) -> None: if self._tcp_connection is not None and self._tcp_connection.is_open(): self._tcp_connection.writer.write(data) def sendtoall(self, data: bytes) -> None: raise NotImplementedError("No implementation for TCP client endpoint.") def shutdown(self) -> None: try: if self._connect_and_receive_task: self._connect_and_receive_task.cancel() except asyncio.CancelledError: self._log("Shutdown task was cancelled.") def protocol(self) -> TransportLayerProtocol: return self._protocol def src_ip(self) -> str: return self._src_ip def src_port(self) -> int: return self._src_port def dst_ip(self) -> str: return self._dst_ip def dst_port(self) -> int: return self._dst_port someipy-2.1.2/src/someipy/_internal/someip_endpoint_factory.py000066400000000000000000000071231513043235100247250ustar00rootroot00000000000000# Copyright (C) 2025 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio from collections.abc import Callable import logging from typing import Tuple from someipy._internal._common.endpoint import Endpoint from someipy._internal.someip_endpoint import ( SomeipEndpoint, TCPClientSomeipEndpoint, TCPSomeipEndpoint, UDPSomeipEndpoint, ) from someipy._internal.someip_message import SomeIpMessage from someipy._internal.tcp_client_manager import TcpClientManager, TcpClientProtocol from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy._internal.utils import create_udp_socket class SomeipEndpointFactory: @staticmethod async def create_server_endpoint( endpoint: Endpoint, protocol: TransportLayerProtocol, someip_callback: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ], ) -> SomeipEndpoint: if protocol == TransportLayerProtocol.UDP: loop = asyncio.get_running_loop() rcv_socket = create_udp_socket(str(endpoint.ip), endpoint.port) _, udp_endpoint = await loop.create_datagram_endpoint( lambda: UDPSomeipEndpoint(str(endpoint.ip), endpoint.port), sock=rcv_socket, ) udp_endpoint.set_someip_callback(someip_callback) return udp_endpoint else: tcp_client_manager = TcpClientManager(str(endpoint.ip), endpoint.port) loop = asyncio.get_running_loop() server = await loop.create_server( lambda: TcpClientProtocol(client_manager=tcp_client_manager), str(endpoint.ip), endpoint.port, ) tcp_someip_endpoint = TCPSomeipEndpoint( server, tcp_client_manager, str(endpoint.ip), endpoint.port ) tcp_someip_endpoint.set_someip_callback(someip_callback) return tcp_someip_endpoint @staticmethod async def create_udp_client_endpoint( dst_endpoint: Endpoint, src_endpoint: Endpoint, someip_message_callback: Callable[[SomeIpMessage], None], logger: logging.Logger = None, ) -> SomeipEndpoint: udp_endpoint = await SomeipEndpointFactory.create_server_endpoint( src_endpoint, TransportLayerProtocol.UDP, someip_message_callback, ) return udp_endpoint @staticmethod def create_tcp_client_endpoint( dst_endpoint: Endpoint, src_endpoint: Endpoint, someip_message_callback: Callable[[SomeIpMessage], None], logger: logging.Logger = None, ) -> TCPClientSomeipEndpoint: tcp_endpoint = TCPClientSomeipEndpoint( str(dst_endpoint.ip), dst_endpoint.port, str(src_endpoint.ip), src_endpoint.port, logger, ) tcp_endpoint.set_someip_callback(someip_message_callback) return tcp_endpoint someipy-2.1.2/src/someipy/_internal/someip_endpoint_storage.py000066400000000000000000000136451513043235100247300ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import Dict, List, Optional from someipy._internal.someip_endpoint import SomeipEndpoint from someipy._internal.transport_layer_protocol import TransportLayerProtocol class SomeipEndpointStorage: def __init__(self): self._storage: Dict[int, List[SomeipEndpoint]] = {} def add_endpoint(self, client_id: int, endpoint: SomeipEndpoint) -> bool: """ Add an endpoint for a client ID. Returns True if added successfully, False if client already has 2 endpoints. """ if client_id not in self._storage: self._storage[client_id] = [endpoint] return True if len(self._storage[client_id]) >= 2: return False self._storage[client_id].append(endpoint) return True def remove_endpoint(self, client_id: int, endpoint: SomeipEndpoint) -> bool: if client_id not in self._storage: return False try: self._storage[client_id].remove(endpoint) # Remove client entry if no endpoints left if not self._storage[client_id]: del self._storage[client_id] return True except ValueError: return False def remove_client(self, client_id: int) -> bool: if client_id in self._storage: del self._storage[client_id] return True return False def get_endpoints(self, client_id: int) -> Optional[List[SomeipEndpoint]]: return self._storage.get(client_id, None) def get_endpoint( self, client_id: int, protocol: TransportLayerProtocol ) -> Optional[SomeipEndpoint]: endpoints = self._storage.get(client_id, None) if endpoints is None: return None if any(endpoint.protocol() == protocol for endpoint in endpoints): # If the client has an endpoint with the same protocol, return all endpoints return [ endpoint for endpoint in endpoints if endpoint.protocol() == protocol ][0] else: return None def get_endpoint_by_ip_port( self, src_ip: str, src_port: int, protocol: TransportLayerProtocol ) -> Optional[SomeipEndpoint]: """ Get an endpoint by source IP, source port, and protocol. Returns the first matching endpoint or None if not found. """ for endpoints in self._storage.values(): for endpoint in endpoints: if ( endpoint.src_ip() == src_ip and endpoint.src_port() == src_port and endpoint.protocol() == protocol ): return endpoint return None def get_end_point_by_src_and_dst_ip_port( self, src_ip: str, src_port: int, dst_ip: str, dst_port: int, protocol: TransportLayerProtocol, ) -> Optional[SomeipEndpoint]: """ Get an endpoint by source IP, source port, destination IP, and destination port. Returns the first matching endpoint or None if not found. """ for endpoints in self._storage.values(): for endpoint in endpoints: if ( endpoint.src_ip() == src_ip and endpoint.src_port() == src_port and endpoint.dst_ip() == dst_ip and endpoint.dst_port() == dst_port and endpoint.protocol() == protocol ): return endpoint return None def get_all_endpoints(self) -> List[SomeipEndpoint]: """Get all endpoints in the storage""" return [ endpoint for endpoints in self._storage.values() for endpoint in endpoints ] def has_endpoint( self, src_ip: str, src_port: int, protocol: TransportLayerProtocol ) -> bool: """ Check if an endpoint with the given IP, port, and protocol exists in the storage. """ for endpoints in self._storage.values(): for endpoint in endpoints: if ( endpoint.src_ip() == src_ip and endpoint.src_port() == src_port and endpoint.protocol() == protocol ): return True return False def has_tcp_endpoint( self, src_ip: str, src_port: int, dst_ip: str, dst_port: int ) -> bool: """ Check if a TCP endpoint with the given source IP, source port, destination IP, and destination port exists in the storage. """ for endpoints in self._storage.values(): for endpoint in endpoints: if ( endpoint.protocol() == TransportLayerProtocol.TCP and endpoint.src_ip() == src_ip and endpoint.src_port() == src_port and endpoint.dst_ip() == dst_ip and endpoint.dst_port() == dst_port ): return True return False def __contains__(self, client_id: int) -> bool: """Check if a client ID exists in the storage""" return client_id in self._storage def __len__(self) -> int: """Get the number of clients in the storage""" return len(self._storage) someipy-2.1.2/src/someipy/_internal/someip_header.py000066400000000000000000000071261513043235100226110ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct from dataclasses import dataclass SERVICE_ID_SD = 0xFFFF METHOD_ID_SD = 0x8100 CLIENT_ID_SD = 0x0000 PROTOCOL_VERSION_SD = 0x01 INTERFACE_VERSION_SD = 0x01 MESSAGE_TYPE_SD = 0x02 RETURN_CODE_SD = 0x00 @dataclass class SomeIpHeader: service_id: int method_id: int length: int client_id: int session_id: int protocol_version: int interface_version: int message_type: int return_code: int MINIMAL_SIZE = 16 def is_sd_header(self) -> bool: return ( self.service_id == SERVICE_ID_SD and self.method_id == METHOD_ID_SD and self.client_id == CLIENT_ID_SD and self.protocol_version == PROTOCOL_VERSION_SD and self.interface_version == INTERFACE_VERSION_SD and self.message_type == MESSAGE_TYPE_SD and self.return_code == RETURN_CODE_SD and self.session_id != 0 ) @classmethod def generate_sd_header(cls, length: int, session_id: int): return cls( service_id=SERVICE_ID_SD, method_id=METHOD_ID_SD, length=length, client_id=CLIENT_ID_SD, session_id=session_id, protocol_version=PROTOCOL_VERSION_SD, interface_version=INTERFACE_VERSION_SD, message_type=MESSAGE_TYPE_SD, return_code=RETURN_CODE_SD, ) @classmethod def from_buffer(cls, buf: bytes): service_id, method_id, length = struct.unpack(">HHI", buf[0:8]) if length <= 0: raise ValueError(f"Length in SOME/IP header is <=0 ({length})") if length < 8: raise ValueError(f"Length in SOME/IP header is <8 ({length})") client_id, session_id, protocol_version, interface_version, message_type, return_code = struct.unpack(">HHBBBB", buf[8:16]) return cls( service_id, method_id, length, client_id, session_id, protocol_version, interface_version, message_type, return_code, ) def to_buffer(self) -> bytes: return struct.pack(">HHIHHBBBB", self.service_id, self.method_id, self.length, self.client_id, self.session_id, self.protocol_version, self.interface_version, self.message_type, self.return_code) def __str__(self) -> str: return f"Service ID: 0x{self.service_id:04X}, Method ID: 0x{self.method_id:04X}, Length: {self.length}, Client ID: 0x{self.client_id:04X}, Session ID: 0x{self.session_id:04X}, Protocol Version: 0x{self.protocol_version:02X}, Interface Version: 0x{self.interface_version:02X}, Message Type: 0x{self.message_type:02X}, Return Code: 0x{self.return_code:02X}" def get_payload_from_message_buffer(someip_header: SomeIpHeader, buffer: bytes) -> bytes: length = someip_header.length payload_length = length - 8 # 8 bytes for request ID, protocol version, etc. return buffer[16:(16+payload_length)] someipy-2.1.2/src/someipy/_internal/someip_message.py000066400000000000000000000016441513043235100230040ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from someipy._internal.someip_header import SomeIpHeader @dataclass class SomeIpMessage: header: SomeIpHeader payload: bytes def serialize(self) -> bytes: return self.header.to_buffer() + self.payload someipy-2.1.2/src/someipy/_internal/someip_sd_builder.py000066400000000000000000000067741513043235100235050ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from someipy._internal.someip_header import SomeIpHeader from .someip_sd_header import ( SD_BYTE_LENGTH_IP4ENDPOINT_OPTION, SD_SINGLE_ENTRY_LENGTH_BYTES, SomeIpSdHeader, SdEntry, SdEntryType, SdServiceEntry, SdEventGroupEntry, ) def build_subscribe_eventgroup_ack_entry( service_id: int, instance_id: int, major_version: int, ttl: int, event_group_id: int ) -> SdEventGroupEntry: sd_entry: SdEntry = SdEntry( SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK, 0, # index_first_option 0, # index_second_option 0, # num_options_1 0, # num_options_2 service_id, instance_id, major_version, ttl, ) entry = SdEventGroupEntry( sd_entry=sd_entry, initial_data_requested_flag=False, counter=0, eventgroup_id=event_group_id, ) return entry def build_subscribe_eventgroup_ack_sd_header( entry: SdEventGroupEntry, session_id: int, reboot_flag: bool ) -> SomeIpSdHeader: # 20 bytes for header and length values of entries and options # + length of entries array (1 entry) total_length = 20 + (1 * SD_SINGLE_ENTRY_LENGTH_BYTES) someip_header = SomeIpHeader.generate_sd_header( length=total_length, session_id=session_id ) return SomeIpSdHeader( someip_header=someip_header, reboot_flag=reboot_flag, unicast_flag=True, length_entries=(1 * SD_SINGLE_ENTRY_LENGTH_BYTES), length_options=0, service_entries=[entry], options=[], ) def build_find_service_sd_header( service_id: int, instance_id: int = 0xFFFF, major_version: int = 0xFF, minor_version: int = 0xFFFFFFFF, session_id: int = 0, reboot_flag: bool = False, ) -> SomeIpSdHeader: sd_entry: SdEntry = SdEntry( SdEntryType.FIND_SERVICE, 0, # index_first_option 0, # index_second_option 0, # num_options_1 0, # num_options_2 service_id, instance_id, major_version, 0, # TTL can be set to an arbitrary value ) sd_service_entry = SdServiceEntry(sd_entry=sd_entry, minor_version=minor_version) # 20 bytes for header and length values of entries and options # + length of entries array (1 entry) # + length of options array (1 option) total_length = ( 20 + (1 * SD_SINGLE_ENTRY_LENGTH_BYTES) + (1 * SD_BYTE_LENGTH_IP4ENDPOINT_OPTION) ) someip_header = SomeIpHeader.generate_sd_header( length=total_length, session_id=session_id ) return SomeIpSdHeader( someip_header=someip_header, reboot_flag=reboot_flag, unicast_flag=True, length_entries=(1 * SD_SINGLE_ENTRY_LENGTH_BYTES), length_options=(1 * SD_BYTE_LENGTH_IP4ENDPOINT_OPTION), service_entries=[sd_service_entry], options=[], ) someipy-2.1.2/src/someipy/_internal/someip_sd_extractors.py000066400000000000000000000127761513043235100242540ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from typing import List, Set, Tuple, Iterable, Union from someipy._internal.transport_layer_protocol import TransportLayerProtocol from .someip_sd_header import ( SdService2, SdSubscription, SomeIpSdHeader, SdService, SdEntryType, SdEventGroupEntry, SdServiceEntry, ) from .someip_sd_option import SdIPV4EndpointOption, SdOptionCommon, SdOptionType def option_runs( entry: Union[SdServiceEntry, SdEventGroupEntry], sd_message: SomeIpSdHeader ) -> Iterable[Union[SdIPV4EndpointOption, SdOptionCommon]]: """This function performs the option runs for SD entries. It uses the start index and the number of options to iterate over the options in two runs""" # First option run start_index = entry.sd_entry.index_first_option for i in range(entry.sd_entry.num_options_1): yield sd_message.options[start_index + i] # Second option run start_index = entry.sd_entry.index_second_option for i in range(entry.sd_entry.num_options_2): yield sd_message.options[start_index + i] def extract_offered_services(someip_sd_header: SomeIpSdHeader) -> List[SdService2]: result: List[SdService2] = [] service_offers = [ o for o in someip_sd_header.service_entries if o.sd_entry.type == SdEntryType.OFFER_SERVICE and o.sd_entry.ttl != 0x00 ] for e in service_offers: options = option_runs(e, someip_sd_header) supported_protocols: Set[TransportLayerProtocol] = set() for option in options: if option.sd_option_common.type == SdOptionType.IPV4_ENDPOINT: endpoint = ( option.ipv4_address, option.port, ) protocol = option.protocol supported_protocols.add(protocol) if len(supported_protocols) > 0: sd_offered_service = SdService2( service_id=e.sd_entry.service_id, instance_id=e.sd_entry.instance_id, major_version=e.sd_entry.major_version, minor_version=e.minor_version, ttl=e.sd_entry.ttl, endpoint=endpoint, protocols=supported_protocols, ) result.append(sd_offered_service) return result def extract_subscribe_entries(someip_sd_header: SomeIpSdHeader) -> List[SdSubscription]: result = [] for entry in someip_sd_header.service_entries: if entry.sd_entry.type == SdEntryType.SUBSCRIBE_EVENT_GROUP: # Check TTL in order to distinguish between subscribe and stop subscribe # SUBSCRIBE_EVENT_GROUP = 0x06 # STOP_SUBSCRIBE_EVENT_GROUP = 0x06 but with TTL set to 0x00 if entry.sd_entry.ttl != 0x00: options = option_runs(entry, someip_sd_header) for current_option in options: if ( current_option.sd_option_common.type == SdOptionType.IPV4_ENDPOINT ): sd_subscription = SdSubscription( service_id=entry.sd_entry.service_id, instance_id=entry.sd_entry.instance_id, major_version=entry.sd_entry.major_version, ttl=entry.sd_entry.ttl, initial_data_requested_flag=entry.initial_data_requested_flag, counter=entry.counter, eventgroup_id=entry.eventgroup_id, ipv4_address=current_option.ipv4_address, port=current_option.port, protocol=current_option.protocol, ) result.append(sd_subscription) return result def extract_subscribe_ack_eventgroup_entries( someip_sd_header: SomeIpSdHeader, ) -> List[SdEventGroupEntry]: result = [] for entry in someip_sd_header.service_entries: if entry.sd_entry.type == SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK: # Check TTL in order to distinguish between subscribe ack and nack # SUBSCRIBE_EVENT_GROUP_ACK = 0x07 # SUBSCRIBE_EVENT_GROUP_NACK = 0x07 # with TTL set to 0x00 if entry.sd_entry.ttl != 0x00: result.append(entry) return result def extract_subscribe_nack_eventgroup_entries( someip_sd_header: SomeIpSdHeader, ) -> List[SdEventGroupEntry]: result = [] for entry in someip_sd_header.service_entries: if entry.sd_entry.type == SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK: # Check TTL in order to distinguish between subscribe ack and nack # SUBSCRIBE_EVENT_GROUP_ACK = 0x07 # SUBSCRIBE_EVENT_GROUP_NACK = 0x07 # with TTL set to 0x00 if entry.sd_entry.ttl == 0x00: result.append(entry) return result someipy-2.1.2/src/someipy/_internal/someip_sd_header.py000066400000000000000000000324721513043235100233010ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import ipaddress import json import struct from enum import Enum from dataclasses import asdict, dataclass from typing import List, Tuple, TypeVar, Union from someipy._internal.someip_sd_option import ( SdIPV4EndpointOption, SdOptionCommon, SdOptionType, ) from someipy._internal.utils import set_bit_at_position, is_bit_set from someipy._internal.someip_header import SomeIpHeader from someipy._internal.transport_layer_protocol import TransportLayerProtocol # Constants for byte positions inside the SD header SD_POSITION_ENTRY_LENGTH = 20 SD_START_POSITION_ENTRIES = 24 # Constants for length of sections in the SD header SD_SINGLE_ENTRY_LENGTH_BYTES = 16 SD_IPV4ENDPOINT_OPTION_LENGTH_VALUE = 9 SD_BYTE_LENGTH_IP4ENDPOINT_OPTION = 12 _T = TypeVar("_T") class SdEntryType(Enum): FIND_SERVICE = 0x00 OFFER_SERVICE = 0x01 STOP_OFFER_SERVICE = 0x01 # with TTL to 0x000000 SUBSCRIBE_EVENT_GROUP = 0x06 STOP_SUBSCRIBE_EVENT_GROUP = 0x06 # with TTL to 0x000000 SUBSCRIBE_EVENT_GROUP_ACK = 0x07 SUBSCRIBE_EVENT_GROUP_NACK = 0x07 # with TTL to 0x000000 @dataclass class SdSubscription: service_id: int instance_id: int major_version: int ttl: int initial_data_requested_flag: int counter: int eventgroup_id: int ipv4_address: ipaddress.IPv4Address port: int protocol: TransportLayerProtocol @dataclass class SdEntry: type: SdEntryType index_first_option: int index_second_option: int num_options_1: int num_options_2: int service_id: int instance_id: int major_version: int ttl: int @classmethod def from_buffer(cls: _T, buf: bytes) -> _T: type_field_value, index_first_option, index_second_option = struct.unpack( ">BBB", buf[0:3] ) num_options_1 = struct.unpack(">B", buf[3:4])[0] # higher 4 bits num_options_1 = (num_options_1 >> 4) & 0x0F num_options_2 = struct.unpack(">B", buf[3:4])[0] # lower 4 bits num_options_2 = num_options_2 & 0x0F service_id, instance_id, major_version = struct.unpack(">HHB", buf[4:9]) (ttl,) = struct.unpack(">I", buf[8:12]) ttl = ttl & 0xFFFFFF if ( type_field_value == SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP.value and ttl == 0 ): type_field = SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP elif ( type_field_value == SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP.value and ttl != 0 ): type_field = SdEntryType.SUBSCRIBE_EVENT_GROUP elif ( type_field_value == SdEntryType.SUBSCRIBE_EVENT_GROUP_NACK.value and ttl == 0 ): type_field = SdEntryType.SUBSCRIBE_EVENT_GROUP_NACK elif ( type_field_value == SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK.value and ttl != 0 ): type_field = SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK else: type_field = SdEntryType(type_field_value) return cls( type_field, index_first_option, index_second_option, num_options_1, num_options_2, service_id, instance_id, major_version, ttl, ) def to_buffer(self) -> bytes: num_options = (self.num_options_1 << 4) | self.num_options_2 ttl_high = (self.ttl & 0xFF0000) >> 16 ttl_low = self.ttl & 0xFFFF return struct.pack( ">BBBBHHBBH", self.type.value, self.index_first_option, self.index_second_option, num_options, self.service_id, self.instance_id, self.major_version, ttl_high, ttl_low, ) @dataclass class SdEventGroupEntry: sd_entry: SdEntry initial_data_requested_flag: int counter: int eventgroup_id: int @classmethod def from_buffer(cls: _T, buf: bytes) -> _T: sd_entry = SdEntry.from_buffer(buf) initial_data_requested_flag_counter_value, eventgroup_id = struct.unpack( ">BH", buf[13:16] ) initial_data_requested_flag = is_bit_set( initial_data_requested_flag_counter_value, 7 ) counter = initial_data_requested_flag_counter_value & 0xF return cls(sd_entry, initial_data_requested_flag, counter, eventgroup_id) def to_buffer(self) -> bytes: initial_data_requested_flag_counter_value = set_bit_at_position(0, 7, True) initial_data_requested_flag_counter_value = ( initial_data_requested_flag_counter_value | (self.counter & 0xF) ) return self.sd_entry.to_buffer() + struct.pack( ">BBH", 0, initial_data_requested_flag_counter_value, self.eventgroup_id ) @dataclass class SdServiceEntry: sd_entry: SdEntry minor_version: int @classmethod def from_buffer(cls: _T, buf: bytes) -> _T: sd_entry = SdEntry.from_buffer(buf) (minor_version,) = struct.unpack(">I", buf[12:16]) return cls(sd_entry, minor_version) def to_buffer(self) -> bytes: return self.sd_entry.to_buffer() + struct.pack(">I", self.minor_version) @dataclass class SdService: """This class aggregates data from entries and options and provides a compact interface instead of loose SD entries and options""" service_id: int instance_id: int major_version: int minor_version: int ttl: int endpoint: Tuple[ipaddress.IPv4Address, int] protocol: TransportLayerProtocol def __hash__(self) -> int: return hash( ( self.service_id, self.instance_id, self.major_version, self.minor_version, self.ttl, self.endpoint, self.protocol, ) ) def to_json(self): output_dict = { "service_id": self.service_id, "instance_id": self.instance_id, "major_version": self.major_version, "minor_version": self.minor_version, "ttl": self.ttl, "endpoint_ip": str(self.endpoint[0]), "endpoint_port": self.endpoint[1], "protocol": self.protocol.value, } return json.dumps(output_dict) @classmethod def from_json(cls: _T, json_str: str) -> _T: json_dict = json.loads(json_str) o = cls( int(json_dict["service_id"]), int(json_dict["instance_id"]), int(json_dict["major_version"]), int(json_dict["minor_version"]), int(json_dict["ttl"]), ( ipaddress.IPv4Address(json_dict["endpoint_ip"]), json_dict["endpoint_port"], ), TransportLayerProtocol(json_dict["protocol"]), ) return o @dataclass class SdService2: """This class aggregates data from entries and options and provides a compact interface instead of loose SD entries and options""" service_id: int instance_id: int major_version: int minor_version: int ttl: int endpoint: Tuple[ipaddress.IPv4Address, int] protocols: frozenset[TransportLayerProtocol] def to_json(self): output_dict = { "service_id": self.service_id, "instance_id": self.instance_id, "major_version": self.major_version, "minor_version": self.minor_version, "ttl": self.ttl, "endpoint_ip": str(self.endpoint[0]), "endpoint_port": self.endpoint[1], "protocols": list(self.protocols), } return json.dumps(output_dict) @classmethod def from_json(cls: _T, json_str: str) -> _T: json_dict = json.loads(json_str) o = cls( int(json_dict["service_id"]), int(json_dict["instance_id"]), int(json_dict["major_version"]), int(json_dict["minor_version"]), int(json_dict["ttl"]), ( ipaddress.IPv4Address(json_dict["endpoint_ip"]), json_dict["endpoint_port"], ), frozenset(TransportLayerProtocol(p) for p in json_dict["protocols"]), ) return o @dataclass class SdServiceWithTimestamp: service: SdService2 timestamp: float def __eq__(self, value): if isinstance(value, SdServiceWithTimestamp): return self.service == value.service return False def __hash__(self) -> int: return hash( ( self.service.service_id, self.service.instance_id, self.service.major_version, self.service.minor_version, self.service.ttl, self.service.endpoint, self.service.protocols, ) ) @dataclass class SomeIpSdHeader: someip_header: SomeIpHeader reboot_flag: bool unicast_flag: bool length_entries: int length_options: int service_entries: List[Union[SdServiceEntry, SdEventGroupEntry]] options: List[Union[SdOptionCommon, SdIPV4EndpointOption]] @classmethod def from_buffer(cls: _T, buf: bytes) -> _T: someip_header = SomeIpHeader.from_buffer(buf) (flags,) = struct.unpack(">B", buf[16:17]) reboot_flag = is_bit_set(flags, 7) unicast_flag = is_bit_set(flags, 6) (length_entries,) = struct.unpack( ">I", buf[SD_POSITION_ENTRY_LENGTH : SD_POSITION_ENTRY_LENGTH + 4] ) number_of_entries = int(length_entries / SD_SINGLE_ENTRY_LENGTH_BYTES) # Read in all Service and Event Group entries entries = [] for i in range(number_of_entries): start_entry = SD_START_POSITION_ENTRIES + (i * SD_SINGLE_ENTRY_LENGTH_BYTES) end_entry = start_entry + SD_SINGLE_ENTRY_LENGTH_BYTES sd_entry = SdEntry.from_buffer(buf[start_entry:end_entry]) if sd_entry.type in [ SdEntryType.FIND_SERVICE, SdEntryType.OFFER_SERVICE, SdEntryType.STOP_OFFER_SERVICE, ]: entries.append(SdServiceEntry.from_buffer(buf[start_entry:end_entry])) elif sd_entry.type in [ SdEntryType.SUBSCRIBE_EVENT_GROUP, SdEntryType.SUBSCRIBE_EVENT_GROUP_ACK, SdEntryType.SUBSCRIBE_EVENT_GROUP_NACK, SdEntryType.STOP_SUBSCRIBE_EVENT_GROUP, ]: entries.append( SdEventGroupEntry.from_buffer(buf[start_entry:end_entry]) ) # Read in all options # The length of the positions is stored after all entries. Therefore the length entry (4 bytes) # and the total length of the entries is added to the position of the entries length pos_length_options = SD_POSITION_ENTRY_LENGTH + 4 + length_entries (length_options,) = struct.unpack( ">I", buf[pos_length_options : pos_length_options + 4] ) pos_start_options = pos_length_options + 4 current_pos_option = pos_start_options bytes_options_left = length_options options = [] while bytes_options_left > 0: sd_option_common = SdOptionCommon.from_buffer( buf[current_pos_option : current_pos_option + 4] ) if sd_option_common.type == SdOptionType.IPV4_ENDPOINT: sd_option = SdIPV4EndpointOption.from_buffer( buf[ current_pos_option : ( current_pos_option + SD_BYTE_LENGTH_IP4ENDPOINT_OPTION ) ] ) options.append(sd_option) else: options.append(sd_option_common) # Subtract 3 bytes first for length and type bytes_options_left -= sd_option_common.length + 3 current_pos_option += sd_option_common.length + 3 return cls( someip_header, reboot_flag, unicast_flag, length_entries, length_options, service_entries=entries, options=options, ) def to_buffer(self) -> bytes: out = self.someip_header.to_buffer() flags = 0 flags = set_bit_at_position(flags, 31, self.reboot_flag) flags = set_bit_at_position(flags, 30, self.unicast_flag) out += struct.pack(">I", flags) # 8 bit flags + 24 reserved bits out += struct.pack(">I", self.length_entries) for entry in self.service_entries: out += entry.to_buffer() out += struct.pack(">I", self.length_options) for option in self.options: out += option.to_buffer() return out someipy-2.1.2/src/someipy/_internal/someip_sd_option.py000066400000000000000000000057251513043235100233620ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass from enum import Enum from typing import TypeVar import ipaddress import struct from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy._internal.utils import is_bit_set, set_bit_at_position _T = TypeVar("_T") class SdOptionType(Enum): CONFIGURATION = 0x01 # TODO: not implemented LOAD_BALANCING = 0x02 # TODO: not implemented IPV4_ENDPOINT = 0x04 IPV6_ENDPOINT = 0x06 # TODO: not implemented IPV4_MULTICAST = 0x14 # TODO: not implemented IPV6_MULTICAST = 0x16 # TODO: not implemented IPV4_SD_ENDPOINT = 0x24 # TODO: not implemented IPV6_SD_ENDPOINT = 0x26 # TODO: not implemented @dataclass class SdOptionCommon: """This class represents the common part of all SD options including the length of the option in bytes, the type of the option (uint8) and a discardable flag (bool)""" length: int type: SdOptionType discardable_flag: bool @classmethod def from_buffer(cls: _T, buf: bytes) -> _T: option_length, option_type, discardable_flag_value = struct.unpack( ">HBB", buf[0:4] ) option_type = SdOptionType(option_type) discardable_flag = is_bit_set(discardable_flag_value, 7) return cls(option_length, option_type, discardable_flag) def to_buffer(self) -> bytes: discardable_flag_value = set_bit_at_position(0, 7, self.discardable_flag) return struct.pack(">HBB", self.length, self.type.value, discardable_flag_value) @dataclass class SdIPV4EndpointOption: sd_option_common: SdOptionCommon ipv4_address: ipaddress.IPv4Address protocol: TransportLayerProtocol port: int @classmethod def from_buffer(cls: _T, buf: bytes) -> _T: sd_option_common = SdOptionCommon.from_buffer(buf) ip1, ip2, ip3, ip4, _, protocol_value, port = struct.unpack( ">BBBBBBH", buf[4:12] ) protocol = TransportLayerProtocol(protocol_value) return cls( sd_option_common, ipaddress.IPv4Address(f"{ip1}.{ip2}.{ip3}.{ip4}"), protocol, port, ) def to_buffer(self) -> bytes: return self.sd_option_common.to_buffer() + struct.pack( ">IBBH", int(self.ipv4_address), 0, self.protocol.value, self.port ) someipy-2.1.2/src/someipy/_internal/subscribers.py000066400000000000000000000052251513043235100223310ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time from typing import List from someipy._internal.utils import EndpointType class EventGroupSubscriber: eventgroup_id: int endpoint: EndpointType ttl: int last_ts_ms: int def __init__(self, eventgroup_id: int, endpoint: EndpointType, ttl: int): self.eventgroup_id = eventgroup_id self.endpoint = endpoint self.ttl = ttl self.last_ts_ms = int(time.time() * 1000) def __eq__(self, __value: object) -> bool: return ( self.eventgroup_id == __value.eventgroup_id and self.endpoint[0] == __value.endpoint[0] and self.endpoint[1] == __value.endpoint[1] ) class Subscribers: def __init__(self): self._subscribers: List[EventGroupSubscriber] = [] def update(self): # From SOME/IP specification: # TTL shall be set to the lifetime of the subscription. # If set to 0xFFFFFF, the Subscribe Eventgroup entry shall be considered valid # until the next reboot. time_now_ms = int(time.time() * 1000) self._subscribers = [ s for s in self._subscribers if (s.ttl == 0xFFFFFF) or (time_now_ms < (s.last_ts_ms + (s.ttl * 1000.0))) ] def add_subscriber(self, new_subscriber: EventGroupSubscriber) -> None: time_now_ms = int(time.time() * 1000.0) for s in self._subscribers: if new_subscriber == s: s.last_ts_ms = time_now_ms return new_subscriber.last_ts_ms = time_now_ms self._subscribers.append(new_subscriber) def remove_subscriber(self, subscriber: EventGroupSubscriber) -> None: if subscriber in self._subscribers: self._subscribers.remove(subscriber) def clear(self) -> None: self._subscribers = [] @property def subscribers(self) -> List[EventGroupSubscriber]: return self._subscribers @property def has_subscribers(self) -> bool: return len(self._subscribers) > 0 someipy-2.1.2/src/someipy/_internal/tcp_client_manager.py000066400000000000000000000123071513043235100236200ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio from abc import ABC, abstractmethod from typing import Callable, Dict, Iterable, Tuple from someipy._internal.someip_message import SomeIpMessage from someipy._internal.someip_data_processor import SomeipDataProcessor from someipy._internal.transport_layer_protocol import TransportLayerProtocol class TcpClientProtocolInterface(ABC): @abstractmethod def write(self, data: bytes) -> None: pass @property @abstractmethod def ip_addr(self) -> str: pass @property @abstractmethod def port(self) -> int: pass class TcpClientManagerInterface(ABC): @abstractmethod def register_client(self, client: TcpClientProtocolInterface) -> None: pass @abstractmethod def unregister_client(self, client: TcpClientProtocolInterface) -> None: pass @abstractmethod def get_client(self, ip_addr: str, port: int) -> TcpClientProtocolInterface: pass @abstractmethod def get_all_clients(self) -> Iterable[TcpClientProtocolInterface]: pass @abstractmethod def someip_callback( self, client: TcpClientProtocolInterface, someip_message: SomeIpMessage ) -> None: pass @abstractmethod def register_callback( self, callback: Callable[[SomeIpMessage, Tuple[str, int]], None] ) -> None: pass class TcpClientManager(TcpClientManagerInterface): def __init__(self, ip: str, port: int): self._ip = ip self._port = port self._clients: Dict[str, TcpClientProtocolInterface] = {} self._someip_callback: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ] = None def _build_key(self, ip_addr: str, port: int) -> str: return f"{ip_addr}-{port}" def register_client(self, client: TcpClientProtocolInterface) -> None: self._clients[self._build_key(client.ip_addr, client.port)] = client def unregister_client(self, client: TcpClientProtocolInterface) -> None: if self._build_key(client.ip_addr, client.port) in self._clients.keys(): del self._clients[self._build_key(client.ip_addr, client.port)] def get_client(self, ip_addr: str, port: int) -> TcpClientProtocolInterface: if self._build_key(ip_addr, port) in self._clients.keys(): return self._clients[self._build_key(ip_addr, port)] else: return None def get_all_clients(self) -> Iterable[TcpClientProtocolInterface]: return self._clients.values() def someip_callback( self, client: TcpClientProtocolInterface, someip_message: SomeIpMessage ) -> None: """ This function is called by a TCP client when a SOME/IP message was received. """ if self._someip_callback is not None: self._someip_callback( someip_message, (client.ip_addr, client.port), (self._ip, self._port), TransportLayerProtocol.TCP, ) def register_callback( self, callback: Callable[ [SomeIpMessage, Tuple[str, int], Tuple[str, int], TransportLayerProtocol], None, ], ) -> None: self._someip_callback = callback class TcpClientProtocol(asyncio.Protocol, TcpClientProtocolInterface): def __init__(self, client_manager: TcpClientManager): self._client_manager: TcpClientManager = client_manager self._transport = None self._ip_addr_client = None self._port_client = None self._data_processor = SomeipDataProcessor() def connection_made(self, transport: asyncio.BaseTransport): peername: Tuple = transport.get_extra_info("peername") self._transport = transport self._ip_addr_client = peername[0] self._port_client = peername[1] self._client_manager.register_client(self) def data_received(self, data: bytes): # Push data to processor result = self._data_processor.process_data(data) if result and self._client_manager is not None: self._client_manager.someip_callback( self, self._data_processor.someip_message ) def connection_lost(self, _) -> None: self._client_manager.unregister_client(self) def write(self, data: bytes) -> None: if self._transport is not None: self._transport.write(data) @property def ip_addr(self) -> str: return self._ip_addr_client @property def port(self) -> int: return self._port_client someipy-2.1.2/src/someipy/_internal/tcp_connection.py000066400000000000000000000033601513043235100230060ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio from someipy._internal.logging import get_logger _logger_name = "tcp_connection" class TcpConnection: def __init__(self, remote_ip: str, remote_port: int): self.remote_ip = remote_ip self.remote_port = remote_port self.reader = None self.writer = None async def connect(self, src_ip: str, src_port: int): local_addr = (src_ip, src_port) self.reader, self.writer = await asyncio.open_connection( self.remote_ip, self.remote_port, local_addr=local_addr ) get_logger(_logger_name).debug( f"Connected to {self.remote_ip}:{self.remote_port}" ) def is_open(self): if self.writer is None or self.writer.is_closing(): return False return not self.reader.at_eof() async def close(self): if self.writer: self.writer.close() await self.writer.wait_closed() self.writer = None get_logger(_logger_name).debug( f"Connection to {self.remote_ip}:{self.remote_port} closed" ) someipy-2.1.2/src/someipy/_internal/transport_layer_protocol.py000066400000000000000000000013721513043235100251530ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from enum import Enum class TransportLayerProtocol(Enum): TCP = 0x06 UDP = 0x11 someipy-2.1.2/src/someipy/_internal/utils.py000066400000000000000000000132571513043235100211470ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio import ipaddress import socket import struct import platform from typing import Tuple, Union, Any def create_udp_socket(ip_address: str, port: int) -> socket.socket: """ Create a datagram protocol based socket and bind the socket to an address. The option "SO_REUSEADDR" will be set on the socket. Parameters ---------- ip_address : str The IP address to which the socket is bound port : int The port to which the socket is bound Returns ------- socket.socket The newly created socket """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) if platform.system() == "Linux": sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.bind((ip_address, port)) return sock def create_rcv_multicast_socket( ip_address: str, port: int, interface_address ) -> socket.socket: """ Create a datagram protocol based socket for multicast and bind the socket to the passed multicast address. The options "SO_REUSEADDR" and "IP_ADD_MEMBERSHIP" will be set on the socket. Parameters ---------- ip_address : str The multicast IP address to which the socket is bound port : int The port to which the socket is bound interface_address : str The address of the local interface Returns ------- socket.socket The newly created socket """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) os_type = platform.system() if os_type == "Windows": sock.bind(("", port)) else: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind((ip_address, port)) # Specify the interface for multicast group membership instead of INADDR_ANY mreq = struct.pack( "4s4s", socket.inet_aton(ip_address), socket.inet_aton(interface_address) ) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) return sock def create_rcv_broadcast_socket( ip_address: str, port: int, interface_address ) -> socket.socket: """ Create a datagram protocol based socket for multicast and bind the socket to the passed multicast address. The options "SO_REUSEADDR" and "SO_BROADCAST" will be set on the socket. Parameters ---------- ip_address : str The multicast IP address to which the socket is bound port : int The port to which the socket is bound interface_address : str The address of the local interface Returns ------- socket.socket The newly created socket """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) os_type = platform.system() if os_type == "Windows": sock.bind(("", port)) else: sock.bind((ip_address, port)) return sock EndpointType = Tuple[ipaddress.IPv4Address, int] def endpoint_to_str_int_tuple(endpoint: EndpointType) -> Tuple[str, int]: """A helper function for converting the format of a tuple for an endpoint""" return (str(endpoint[0]), endpoint[1]) class DatagramAdapter(asyncio.DatagramProtocol): """An adapter class which allows to forward the calls of of asyncio.DatagramProtocol to an injected target class""" def __init__( self, target=None, datagram_received_callback=None, connection_lost_callback=None, ): self.target = target self.datagram_received_callback = datagram_received_callback self.connection_lost_callback = connection_lost_callback def datagram_received(self, data: bytes, addr: Tuple[Union[str, Any], int]) -> None: if self.target != None: self.target.datagram_received(data, addr) elif self.datagram_received_callback != None: self.datagram_received_callback(data, addr) def connection_lost(self, exc: Exception) -> None: if self.target != None: self.target.connection_lost(exc) elif self.connection_lost_callback != None: self.connection_lost_callback(exc) def set_bit_at_position(number: int, position: int, value: bool) -> int: """Set the bit at the specified position (0 is the least significant bit) to the given boolean value.""" if value: # Set the bit to 1 return number | (1 << position) else: # Set the bit to 0 return number & ~(1 << position) def is_bit_set(number: int, bit_position: int) -> bool: """ Checks if the bit at the specified position is set in the given number. Parameters: - number: The integer to check. - bit_position: The position of the bit to check (0-based index). Returns: - True if the bit is set, False otherwise. """ # Left shift 1 to the bit position and perform bitwise AND with the number # If the result is non-zero, the bit is set; otherwise, it's not set. return (number & (1 << bit_position)) != 0 someipy-2.1.2/src/someipy/client_service_instance.py000066400000000000000000000275751513043235100227260ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import asyncio import base64 from dataclasses import dataclass from typing import Dict, Tuple, Callable from someipy import Service from someipy._internal.daemon_client_abcs import ClientInstanceInterface from someipy._internal.method_result import MethodResult from someipy._internal.someip_sd_header import SdService from someipy._internal._daemon.someipy_daemon_client import SomeIpDaemonClient from someipy._internal._daemon.uds_messages import ( OutboundCallMethodRequest, OutboundCallMethodResponse, ReceivedEvent, StopSubscribeEventGroupRequest, SubscribeEventGroupRequest, create_uds_message, ) from someipy._internal.logging import get_logger from someipy._internal.message_types import MessageType from someipy._internal.return_codes import ReturnCode from someipy._internal.someip_endpoint import ( SomeIpMessage, ) from someipy.service import EventGroup _logger_name = "client_service_instance" @dataclass class MethodCall: service_id: int method_id: int client_id: int session_id: int def __hash__(self): return hash( ( self.service_id, self.method_id, self.client_id, self.session_id, ) ) class ClientServiceInstance(ClientInstanceInterface): """Client-side representation of a SOME/IP service instance. This class provides methods to call SOME/IP methods and to subscribe to SOME/IP events. """ def __init__( self, daemon: SomeIpDaemonClient, service: Service, instance_id: int, endpoint_ip: str, endpoint_port: int, client_id: int = 0, ): """Initialize a ClientServiceInstance. Parameters ---------- daemon : SomeIpDaemonClient Daemon client used to communicate with the someipy daemon. service : Service Service configuration for this instance. instance_id : int Instance ID for this service instance. endpoint_ip : str IP address of the endpoint on which the service instance is reachable (method responses or reception of events). endpoint_port : int Port of the endpoint on which the service instance is reachable. client_id : int, optional Client ID used for this client service instance. Default: 0. """ self._daemon: SomeIpDaemonClient = daemon self._service: Service = service self._instance_id: int = instance_id self._endpoint_ip: str = endpoint_ip self._endpoint_port: int = endpoint_port self._client_id: int = client_id self._eventgroups_to_subscribe = set() self._event_callback: Callable[[int, bytes], None] = None self._method_call_futures: Dict[MethodCall, asyncio.Future] = {} self._session_id: int = 0 # Starts from 1 to 0xFFFF self._daemon._client_service_instances.append(self) @property def service(self) -> Service: """Return the associated Service object for this client instance.""" return self._service @property def instance_id(self) -> int: """Return the instance ID for this client service instance.""" return self._instance_id @property def endpoint(self) -> Tuple[str, int]: """Return the (IP, port) endpoint for this client instance.""" return (self._endpoint_ip, self._endpoint_port) def register_callback(self, callback: Callable[[int, bytes], None]) -> None: """Register a callback for received SOME/IP events. The registered callback will be invoked with (event_id, payload) when an event is received. Parameters ---------- callback : Callable[[int, bytes], None] Callback function invoked when an event is received. """ self._event_callback = callback def _event_data_received(self, message: ReceivedEvent) -> None: if message["service_id"] != self._service.id: return all_events = [ e for group in self._service.eventgroups.values() for e in group.events ] all_event_ids = [e.id for e in all_events] if message["event_id"] not in all_event_ids: return if self._event_callback is not None: decoded_payload = base64.b64decode(message["payload"]) self._event_callback(message["event_id"], decoded_payload) def _method_call_data_received(self, message: OutboundCallMethodResponse) -> None: method_call_key = MethodCall( service_id=message["service_id"], method_id=message["method_id"], client_id=message["client_id"], session_id=message["session_id"], ) if method_call_key not in self._method_call_futures.keys(): return if message["client_id"] != self._client_id: return call_future = self._method_call_futures[method_call_key] if call_future is not None: decoded_payload = base64.b64decode(message["payload"]) result = MethodResult() result.message_type = MessageType.RESPONSE result.return_code = ReturnCode(message["return_code"]) result.payload = decoded_payload call_future.set_result(result) async def call_method(self, method_id: int, payload: bytes) -> MethodResult: get_logger(_logger_name).debug(f"Trying to call method 0x{method_id:04X}") service: SdService = await self._daemon._find_service( self._service.id, self._instance_id, self._service.major_version, self._service.minor_version, ) if service is None: error_msg = f"Method 0x{method_id:04x} called, but service 0x{self._service.id:04X} with instance 0x{self._instance_id:04X} not found yet." get_logger(_logger_name).warning(error_msg) raise RuntimeError(error_msg) # Session ID is a 16-bit value and should be incremented for each method call starting from 1 self._session_id = (self._session_id + 1) % 0xFFFF session_id = self._session_id # Find method in self._service method = self._service.methods.get(method_id, None) protocol_to_use = method.protocol.value # base64 encoded payload payload_encoded = base64.b64encode(payload).decode("utf-8") method_request = create_uds_message( OutboundCallMethodRequest, service_id=service.service_id, instance_id=service.instance_id, method_id=method_id, client_id=self._client_id, session_id=session_id, protocol_version=0x01, major_version=service.major_version, minor_version=service.minor_version, dst_endpoint_ip=str(service.endpoint[0]), dst_endpoint_port=service.endpoint[1], src_endpoint_ip=self._endpoint_ip, src_endpoint_port=self._endpoint_port, protocol=protocol_to_use, payload=payload_encoded, ) method_call_key = MethodCall( service_id=service.service_id, method_id=method_id, client_id=self._client_id, session_id=session_id, ) future = asyncio.Future() self._method_call_futures[method_call_key] = future self._daemon.transmit_message_to_daemon(method_request) # After sending the method call wait for maximum 10 seconds try: await asyncio.wait_for(future, 10.0) except asyncio.TimeoutError: # Remove the call_future from self._method_call_futures del self._method_call_futures[method_call_key] get_logger(_logger_name).error( f"Waiting on response for method call 0x{method_id:04X} timed out." ) raise method_result = future.result() del self._method_call_futures[method_call_key] return method_result def someip_message_received( self, someip_message: SomeIpMessage, addr: Tuple[str, int] ) -> None: if ( someip_message.header.client_id == 0x00 and someip_message.header.message_type == MessageType.NOTIFICATION.value and someip_message.header.return_code == ReturnCode.E_OK.value ): if self._event_callback is not None: self._event_callback(someip_message) return # Handling a response message if ( someip_message.header.message_type == MessageType.RESPONSE.value or someip_message.header.message_type == MessageType.ERROR.value ): method_call_key = MethodCall( service_id=someip_message.header.service_id, method_id=someip_message.header.method_id, client_id=someip_message.header.client_id, session_id=someip_message.header.session_id, ) if method_call_key not in self._method_call_futures.keys(): return if someip_message.header.client_id != self._client_id: return call_future = self._method_call_futures[method_call_key] if call_future is not None: result = MethodResult() result.message_type = MessageType(someip_message.header.message_type) result.return_code = ReturnCode(someip_message.header.return_code) result.payload = someip_message.payload call_future.set_result(result) def subscribe_eventgroup( self, eventgroup: EventGroup, ttl_subscription_seconds: int ): if not isinstance(ttl_subscription_seconds, int): raise ValueError("ttl_subscription_seconds must be an integer value.") method_request = create_uds_message( SubscribeEventGroupRequest, service_id=self._service.id, instance_id=self.instance_id, major_version=self._service.major_version, eventgroup=eventgroup.to_json(), ttl_subscription=ttl_subscription_seconds, client_endpoint_ip=self._endpoint_ip, client_endpoint_port=self._endpoint_port, udp=eventgroup.has_udp, tcp=eventgroup.has_tcp, ) self._daemon.transmit_message_to_daemon(method_request) def unsubscribe_eventgroup(self, eventgroup: EventGroup): method_request = create_uds_message( StopSubscribeEventGroupRequest, service_id=self._service.id, instance_id=self.instance_id, major_version=self._service.major_version, eventgroup=eventgroup.to_json(), client_endpoint_ip=self._endpoint_ip, client_endpoint_port=self._endpoint_port, udp=eventgroup.has_udp, tcp=eventgroup.has_tcp, ) self._daemon.transmit_message_to_daemon(method_request) async def is_available(self) -> bool: service = await self._daemon._find_service( self._service.id, self._instance_id, self._service.major_version, self._service.minor_version, ) if service is None: return False return True someipy-2.1.2/src/someipy/serialization.py000066400000000000000000001117731513043235100207130ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import codecs import struct from dataclasses import dataclass from typing import Generic, List, Type, TypeVar """ PRS_SOMEIP_00065 This table about basic datatypes is taken from https://www.autosar.org/fileadmin/standards/R22-11/FO/AUTOSAR_PRS_SOMEIPProtocol.pdf Type Description Size [bit] Remark boolean TRUE/FALSE value 8 FALSE (0), TRUE (1) uint8 unsigned Integer 8 uint16 unsigned Integer 16 uint32 unsigned Integer 32 uint64 unsigned Integer 64 sint8 signed Integer 8 sint16 signed Integer 16 sint32 signed Integer 32 sint64 signed Integer 64 float32 floating point number 32 IEEE 754 binary32 (Single Precision) float64 floating point number 64 IEEE 754 binary64 (Double Precision) """ @dataclass class Uint8: """ someipy datatype representing an unsigned 8 bit integer on the wire. """ value: int = 0 def __len__(self): """ Return the length of the object. :return: An integer representing the length of the object. :rtype: int """ return 1 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. """ return struct.pack(">B", self.value) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: None """ (self.value,) = struct.unpack(">B", payload) return self @dataclass class Sint8: """ someipy datatype representing a signed 8 bit integer on the wire. """ value: int = 0 def __len__(self): """ Return the length of the object. :return: An integer representing the length of the object. :rtype: int """ return 1 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. """ return struct.pack(">b", self.value) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. """ (self.value,) = struct.unpack(">b", payload) return self @dataclass class Uint16: """ someipy datatype representing an unsigned 16 bit integer on the wire. """ value: int = 0 def __len__(self): """ Return the length of the object. Returns: int: The length of the object, which is always 2. """ return 2 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. """ return struct.pack(">H", self.value) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. """ (self.value,) = struct.unpack(">H", payload) return self @dataclass class Sint16: """ someipy datatype representing a signed 16 bit integer on the wire. """ value: int = 0 def __len__(self): """ Return the length of the object. Returns: int: The length of the object, which is always 2. """ return 2 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. """ return struct.pack(">h", self.value) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. """ (self.value,) = struct.unpack(">h", payload) return self @dataclass class Uint32: """ someipy datatype representing an unsigned 32 bit integer on the wire. """ value: int = 0 def __len__(self): return 4 def serialize(self) -> bytes: return struct.pack(">L", self.value) def deserialize(self, payload): (self.value,) = struct.unpack(">L", payload) return self @dataclass class Sint32: """ someipy datatype representing a signed 32 bit integer on the wire. """ value: int = 0 def __len__(self): return 4 def serialize(self) -> bytes: return struct.pack(">l", self.value) def deserialize(self, payload): (self.value,) = struct.unpack(">l", payload) return self @dataclass class Uint64: """ someipy datatype representing an unsigned 64 bit integer on the wire. """ value: int = 0 def __len__(self): return 8 def serialize(self) -> bytes: return struct.pack(">Q", self.value) def deserialize(self, payload): (self.value,) = struct.unpack(">Q", payload) return self @dataclass class Sint64: """ someipy datatype representing a signed 64 bit integer on the wire. """ value: int = 0 def __len__(self): return 8 def serialize(self) -> bytes: return struct.pack(">q", self.value) def deserialize(self, payload): (self.value,) = struct.unpack(">q", payload) return self @dataclass class Bool: """ someipy datatype representing a boolean type transported as a single byte on the wire. """ value: bool = False def __len__(self): """ Return the length of the object. Returns: int: The length of the object, which is always 1. """ return 1 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. """ return struct.pack(">B", int(self.value)) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the value of the object. It expects the payload to be a single byte representing a boolean value. If the payload is 0, the value of the object is set to False. If the payload is 1, the value of the object is set to True. The deserialized object is then returned. """ (int_value,) = struct.unpack(">B", payload) if int_value == 0: self.value = False elif int_value == 1: self.value = True return self @dataclass class Float32: """ someipy datatype representing a 32 bit floating type. """ value: float = 0.0 def __len__(self): """ Return the length of the object. Returns: int: The length of the object, which is always 4. """ return 4 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. This method serializes the value of the object into bytes using the big-endian byte order. It expects the value to be a float. The serialized value is returned as a bytes object. """ return struct.pack(">f", self.value) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the value of the object. It expects the payload to be a 4-byte float in big-endian byte order. The deserialized value is assigned to the `value` attribute of the object. The deserialized object is then returned. """ (self.value,) = struct.unpack(">f", payload) return self def __eq__(self, other) -> Bool: """ Compare two objects for equality. This method compares the serialized representation of the current object and the other object to determine if they are equal. It returns a Bool object indicating whether the objects are equal or not. Parameters: other (Any): The object to compare with the current object. Returns: Bool: A Bool object indicating whether the objects are equal or not. """ return self.serialize() == other.serialize() @dataclass class Float64: """ someipy datatype representing a 64 bit floating type. """ value: float = 0.0 def __len__(self): """ Return the length of the object. Returns: int: The length of the object, which is always 8. """ return 8 def serialize(self) -> bytes: """ Serialize the value of the object into bytes using the big-endian byte order. Returns: bytes: The serialized value of the object. This method serializes the value of the object into bytes using the big-endian byte order. It expects the value to be a float. The serialized value is returned as a bytes object. """ return struct.pack(">d", self.value) def deserialize(self, payload): """ Deserialize the payload into the value of the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the value of the object. It expects the payload to be an 8-byte float in big-endian byte order. The deserialized value is assigned to the `value` attribute of the object. The deserialized object is then returned. """ (self.value,) = struct.unpack(">d", payload) return self def __eq__(self, other) -> Bool: """ Compare two objects for equality. This method compares the serialized representation of the current object and the other object to determine if they are equal. It returns a Bool object indicating whether the objects are equal or not. Parameters: other (Any): The object to compare with the current object. Returns: Bool: A Bool object indicating whether the objects are equal or not. """ return self.serialize() == other.serialize() def serialize(obj) -> bytes: """ Serializes an object into bytes by iterating over its attributes, excluding those starting with double underscores or underscores. For each attribute, it calls the `serialize` method of the attribute and appends the returned bytes to the output. Parameters: obj (object): The object to be serialized. Returns: bytes: The serialized representation of the object as bytes. """ ordered_items = [ (name, value) for name, value in obj.__dict__.items() if not (name.startswith("__") or name.startswith("_")) ] output = bytes() for _, value in ordered_items: output += value.serialize() return output class SomeIpPayload: """ A base class for defining a custom SOME/IP payload ("structs"). It can be recursively nested, i.e. a SomeIpPayload object may contain other SomeIpPayload objects. """ def __len__(self) -> int: """ Return the length of the object. Returns: int: The length of the object. """ payload_length = 0 ordered_items = [ (name, value) for name, value in self.__dict__.items() if not name.startswith("__") ] for _, value in ordered_items: payload_length += len(value) return payload_length def serialize(self) -> bytes: """ Serialize the object into bytes to be transported on the wire. Returns: bytes: The serialized representation of the object. """ return serialize(self) def deserialize(self, payload: bytes): """ Deserialize the payload (on wire representation) into the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the object. It iterates over the attributes of the object, excluding those starting with "__". For each attribute, it calculates the length of the corresponding value and deserializes it using the `deserialize` method of the value object. The deserialized values are assigned back to the corresponding attributes of the object. Finally, the deserialized object is returned. """ ordered_items = [ (name, value) for name, value in self.__dict__.items() if not name.startswith("__") ] pos = 0 for key, value in ordered_items: if hasattr(value, "_has_dynamic_size") and value._has_dynamic_size == True: # If the length is not known before deserialization, first deserialize using the # remaining payload and then calculate the length self.__dict__[key].deserialize(payload[pos:]) type_length = len(self.__dict__[key]) else: # If the length is known beforehand, only deserialize the part of the payload needed type_length = len(value) self.__dict__[key].deserialize(payload[pos : (pos + type_length)]) pos += type_length return self T = TypeVar("T") class SomeIpFixedSizeArray(Generic[T]): """ A datatype for a SOME/IP fixed size array. This type shall be used with someipy datatypes that support serialization and deserialization. """ def __init__(self, class_reference: Type[T], size: int): """ Initializes a new instance of the SomeIpFixedSizeArray class. Parameters: class_reference (Type[T]): The type of elements to be stored in the array. size (int): The number of elements in the array. Returns: None """ self.data: List[T] = [class_reference() for i in range(size)] def __eq__(self, other): """ Compare two SomeIpFixedSizeArray objects for equality. This method compares the length (number of elements) of the current array and the other array to determine if they are equal. It also compares the length of the bytes representation of the arrays. Finally, it compares the content of all elements in the arrays to check if they are equal. Parameters: other (SomeIpFixedSizeArray): The object to compare with the current object. Returns: bool: True if the arrays are equal, False otherwise. """ if isinstance(other, SomeIpFixedSizeArray): # Compare if the length (number of elements) of other array is the same if len(self.data) != len(other.data): return False # Compare if bytes length of other is the same if len(self) != len(other): return False # Compare if the content of all elements is the same for i in range(len(self.data)): if self.data[i] != other.data[i]: return False return True return False def __len__(self) -> int: """ Return the length of the object. This method calculates the length of the object based on the number of elements in the `data` list and the length of each element. If the `data` list is empty, it returns 0. Otherwise, it returns the product of the length of the `data` list and the length of the first element in the `data` list. Returns: int: The length of the object. """ if len(self.data) == 0: return 0 else: return len(self.data) * len(self.data[0]) def serialize(self) -> bytes: """ Serialize the object into bytes by iterating over its attributes, excluding those starting with double underscores or underscores. For each attribute, it calls the `serialize` method of the attribute and appends the returned bytes to the output. Returns: bytes: The serialized representation of the object as bytes. """ result = bytes() for element in self.data: result += element.serialize() return result def deserialize(self, payload: bytes): """ Deserialize the payload into the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the object. It iterates over the `data` list and for each element, it calls the `deserialize` method of that element, passing a slice of the payload corresponding to the element's length. The deserialized values are assigned back to the corresponding elements of the `data` list. If the `data` list is empty, the method returns immediately. Finally, the deserialized object is returned. """ if len(self.data) == 0: return single_element_length = len(self.data[0]) for i in range(len(self.data)): self.data[i].deserialize( payload[(i * single_element_length) : ((i + 1) * single_element_length)] ) return self class SomeIpDynamicSizeArray(Generic[T]): """ A datatype for a SOME/IP dynamically sized array. This type shall be used in someipy datatypes that support serialization and deserialization. """ _has_dynamic_size = True def __init__(self, class_reference: Type[T]): """ Initializes a new instance of the SomeIpDynamicSizeArray class. Parameters: class_reference (Type[T]): The type of elements to be stored in the array. Returns: None """ self._data: List[T] = [] self._length_field_length = 4 # The length of the length field in bytes. It can be either 0 (no length field), 1, 2 or 4 bytes. self._single_element_length = len(class_reference()) self._class_reference = class_reference @property def data(self) -> List[T]: return self._data @data.setter def data(self, value: List[T]): self._data = value @property def length_field_length(self): return self._length_field_length @length_field_length.setter def length_field_length(self, value): if value in [0, 1, 2, 4]: self._length_field_length = value else: raise ValueError("Length field length must be 0, 1, 2 or 4 bytes") def __eq__(self, other) -> bool: """ Compare two SomeIpDynamicSizeArray objects for equality. This method compares the length (number of elements) of the current array and the other array to determine if they are equal. It also compares the length of the bytes representation of the arrays. Finally, it compares the content of all elements in the arrays to check if they are equal. Parameters: other (SomeIpDynamicSizeArray): The object to compare with the current object. Returns: bool: True if the arrays are equal, False otherwise. """ if isinstance(other, SomeIpDynamicSizeArray): # Compare if the length (number of elements) of other array is the same if len(self.data) != len(other.data): return False # Compare if bytes length of other is the same if len(self) != len(other): return False if self.length_field_length != other.length_field_length: return False # Compare if the content of all elements is the same for i in range(len(self.data)): if self.data[i] != other.data[i]: return False return True return False def __len__(self) -> int: """ Return the length of the object in bytes. This method calculates the length of the object based on the number of elements in the `data` list and the length of each element. If the `data` list is empty, it returns 0. Otherwise, it returns the product of the length of the `data` list and the length of the first element in the `data` list. Returns: int: The length of the object. """ return self.length_field_length + len(self.data) * self._single_element_length def serialize(self) -> bytes: """ Serialize the object into bytes by iterating over its attributes, excluding those starting with double underscores or underscores. For each attribute, it calls the `serialize` method of the attribute and appends the returned bytes to the output. Returns: bytes: The serialized representation of the object as bytes. """ result = bytes() length_data_in_bytes = len(self.data) * self._single_element_length if self._length_field_length == 1: result += struct.pack(">B", length_data_in_bytes) elif self._length_field_length == 2: result += struct.pack(">H", length_data_in_bytes) elif self._length_field_length == 4: result += struct.pack(">L", length_data_in_bytes) for element in self.data: result += element.serialize() return result def deserialize(self, payload: bytes): """ Deserialize the payload into the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the object. It iterates over the `data` list and for each element, it calls the `deserialize` method of that element, passing a slice of the payload corresponding to the element's length. The deserialized values are assigned back to the corresponding elements of the `data` list. If the `data` list is empty, the method returns immediately. Finally, the deserialized object is returned. """ self.data = [] length = 0 if self._length_field_length == 1: (length,) = struct.unpack(">B", payload[:1]) elif self._length_field_length == 2: (length,) = struct.unpack(">H", payload[:2]) elif self._length_field_length == 4: (length,) = struct.unpack(">L", payload[:4]) else: return number_of_elements = length / self._single_element_length for i in range(int(number_of_elements)): start_idx = (i * self._single_element_length) + self._length_field_length end_idx = start_idx + self._single_element_length next_element = self._class_reference().deserialize( payload[start_idx:end_idx] ) self.data.append(next_element) return self class SomeIpFixedSizeString(Generic[T]): """ A datatype for a SOME/IP fixed size string. """ def __init__(self, size: int, value: str = ""): """ Initializes a new instance of the SomeIpFixedSizeString class. Parameters: size (int): The size of the string including the terminating '\0' character. Returns: None """ self._size = size self._data = value self._encoding = "utf-8" @property def size(self) -> int: return self._size @property def data(self) -> str: return self._data @data.setter def data(self, value: str): if ( len(value) ) > self._size - 1: # -1 since the terminating '\0' character is included in the size raise ValueError( f"String length exceeds maximum size of {self._size} including the terminating character" ) self._data = value @property def encoding(self) -> str: return self._encoding @encoding.setter def encoding(self, value: str): if value not in ["utf-8", "utf-16le", "utf-16be"]: raise ValueError( f"Encoding {value} is not supported. Supported encodings are 'utf-8', 'utf-16le' and 'utf-16be'" ) self._encoding = value def __eq__(self, other): """ Compare two SomeIpFixedSizeString objects for equality. Parameters: other (SomeIpFixedSizeArray): The object to compare with the current object. Returns: bool: True if the strings are equal, False otherwise. """ if isinstance(other, SomeIpFixedSizeString): # Compare if the length (number of elements) of other array is the same if self._size != other._size: return False return self._data == other._data return False def __len__(self) -> int: """ Return the length of the object on the wire in bytes. Includes the BOM and terminating '\0' character. Returns: int: The length of the object on the wire in bytes. """ if self.encoding == "utf-8": return self.size + len(codecs.BOM_UTF8) elif self.encoding == "utf-16le" or self.encoding == "utf-16be": return (self.size * 2) + len(codecs.BOM_UTF16_LE) raise ValueError("Unknown encoding") def serialize(self) -> bytes: """ Serialize the object into bytes by iterating over its attributes, excluding those starting with double underscores or underscores. For each attribute, it calls the `serialize` method of the attribute and appends the returned bytes to the output. Returns: bytes: The serialized representation of the object as bytes. """ result = bytes() if self._encoding == "utf-8": result += codecs.BOM_UTF8 result += self.data.encode("utf-8") filler_chars = self.size - len(self._data) result += "\0".encode("utf-8") * filler_chars assert len(result) == self.size + len(codecs.BOM_UTF8) elif self._encoding == "utf-16le": result += codecs.BOM_UTF16_LE result += self.data.encode("utf-16le") filler_chars = self.size - len(self._data) result += "\0".encode("utf-16le") * filler_chars assert len(result) == (self.size * 2) + len(codecs.BOM_UTF16_LE) elif self._encoding == "utf-16be": result += codecs.BOM_UTF16_BE result += self.data.encode("utf-16be") filler_chars = self.size - len(self._data) result += "\0".encode("utf-16be") * filler_chars assert len(result) == (self.size * 2) + len(codecs.BOM_UTF16_BE) return result def deserialize(self, payload: bytes): """ Deserialize the payload into the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the string. It automatically detects the encoding from the BOM at the beginning of the payload. """ # Get the byte order mark, either 3 bytes for utf-8 or 2 bytes for utf-16 bom = payload[:3] if payload.startswith(codecs.BOM_UTF8) else payload[:2] if bom == codecs.BOM_UTF8: self.encoding = "utf-8" start_idx = 3 end_idx = start_idx + self.size decoded_string = payload[start_idx:end_idx].decode("utf-8") self.data = decoded_string.rstrip("\0") elif bom == codecs.BOM_UTF16_LE: self.encoding = "utf-16le" start_idx = 2 end_idx = start_idx + self.size * 2 decoded_string = payload[start_idx:end_idx].decode("utf-16le") self.data = decoded_string.rstrip("\0") elif bom == codecs.BOM_UTF16_BE: self.encoding = "utf-16be" start_idx = 2 end_idx = start_idx + self.size * 2 decoded_string = payload[start_idx:end_idx].decode("utf-16be") self.data = decoded_string.rstrip("\0") else: raise ValueError("Unknown encoding") return self class SomeIpDynamicSizeString(Generic[T]): """ A datatype for a SOME/IP dynamically sized string. """ _has_dynamic_size = True def __init__(self, value: str = ""): """ Initializes a new instance of the SomeIpDynamicSizeString class. Parameters: value (str): The initial string data of the object. Returns: None """ self._data = value self._length_field_length = 4 # The length of the length field in bytes. It can be either 1, 2 or 4 bytes. # BOM + string + terminating '\0' character self._length_field_value = 3 + len(value) + 1 self._encoding = "utf-8" self._length = self._length_field_length + self._length_field_value @property def data(self) -> str: return self._data @data.setter def data(self, value: str): self._data = value if self.encoding == "utf-8": self._length_field_value = 3 + len(value) + 1 elif self.encoding == "utf-16le" or self.encoding == "utf-16be": self._length_field_value = 2 + len(value) * 2 + 2 self._length = self._length_field_length + self._length_field_value @property def length_field_length(self): return self._length_field_length @length_field_length.setter def length_field_length(self, value): if value in [1, 2, 4]: self._length_field_length = value self._length = self._length_field_length + self._length_field_value else: raise ValueError("Length field length must be 1, 2 or 4 bytes") @property def encoding(self) -> str: return self._encoding @encoding.setter def encoding(self, value: str): if value not in ["utf-8", "utf-16le", "utf-16be"]: raise ValueError( f"Encoding {value} is not supported. Supported encodings are 'utf-8', 'utf-16le' and 'utf-16be'" ) self._encoding = value if self.encoding == "utf-8": self._length_field_value = 3 + len(self.data) + 1 elif self.encoding == "utf-16le" or self.encoding == "utf-16be": self._length_field_value = 2 + len(self.data) * 2 + 2 self._length = self._length_field_length + self._length_field_value def __eq__(self, other): """ Compare two SomeIpDynamicSizeString objects for equality. Parameters: other (SomeIpDynamicSizeString): The object to compare with the current object. Returns: bool: True if the strings are equal, False otherwise. """ if isinstance(other, SomeIpDynamicSizeString): if len(self) != len(other): return False if self.encoding != other.encoding: return False if self.length_field_length != other.length_field_length: return False return self._data == other._data return False def __len__(self) -> int: """ Return the length of the serialized string in bytes. Returns: int: The length of the string. """ return self._length def serialize(self) -> bytes: """ Serialize the object into bytes by iterating over its attributes, excluding those starting with double underscores or underscores. For each attribute, it calls the `serialize` method of the attribute and appends the returned bytes to the output. Returns: bytes: The serialized representation of the object as bytes. """ # The length field is placed first # The length is measured in bytes and includes the BOM length. The length of the length field is not included result = bytes() bom = None encoded_str = None if self.encoding == "utf-8": bom = codecs.BOM_UTF8 encoded_str = self.data.encode("utf-8") elif self.encoding == "utf-16le": bom = codecs.BOM_UTF16_LE encoded_str = self.data.encode("utf-16le") elif self.encoding == "utf-16be": bom = codecs.BOM_UTF16_BE encoded_str = self.data.encode("utf-16be") length = ( len(bom) + len(encoded_str) + 1 ) # +1 for the terminating '\0' character if self.encoding == "utf-16le" or self.encoding == "utf-16be": length += 1 # The terminating '\0' character is 2 bytes in utf-16 if self.length_field_length == 1: if length > 255: raise ValueError( "Length of the string exceeds maximum value of 255 for 1 byte length field." ) result += struct.pack(">B", length) elif self.length_field_length == 2: if length > 65535: raise ValueError( "Length of the string exceeds maximum value of 65535 for 2 byte length field." ) result += struct.pack(">H", length) elif self.length_field_length == 4: if length > 4294967295: raise ValueError( "Length of the string exceeds maximum value of 4294967295 for 4 byte length field." ) result += struct.pack(">L", length) result += bom result += encoded_str result += "\0".encode(self.encoding) assert len(result) == self._length return result def deserialize(self, payload: bytes): """ Deserialize the payload into the object. Args: payload (bytes): The payload to be deserialized. Returns: self: The deserialized object. This method deserializes the payload into the string. It automatically detects the encoding from the BOM at the beginning of the payload. """ if len(payload) < self.length_field_length: raise ValueError( f"Deserialization failed: Payload is too short. Payload length: {len(payload)}" ) length_field = payload[: self.length_field_length] if self.length_field_length == 1: (length,) = struct.unpack(">B", length_field) elif self.length_field_length == 2: (length,) = struct.unpack(">H", length_field) elif self.length_field_length == 4: (length,) = struct.unpack(">L", length_field) if len(payload) < length: raise ValueError( f"Deserialization failed: Payload is too short. Payload length: {len(payload)}. Expected length: {length}" ) bom_start = self.length_field_length # Get the byte order mark, either 3 bytes for utf-8 or 2 bytes for utf-16 bom = ( payload[bom_start : bom_start + 3] if payload[bom_start:].startswith(codecs.BOM_UTF8) else payload[bom_start : bom_start + 2] ) if bom == codecs.BOM_UTF8: self.encoding = "utf-8" start_idx = self.length_field_length + 3 end_idx = start_idx + length - 3 decoded_string = payload[start_idx:end_idx].decode("utf-8") self.data = decoded_string.rstrip("\0") elif bom == codecs.BOM_UTF16_LE: self.encoding = "utf-16le" start_idx = self.length_field_length + 2 end_idx = start_idx + length - 2 decoded_string = payload[start_idx:end_idx].decode("utf-16le") self.data = decoded_string.rstrip("\0") elif bom == codecs.BOM_UTF16_BE: self.encoding = "utf-16be" start_idx = self.length_field_length + 2 end_idx = start_idx + length - 2 decoded_string = payload[start_idx:end_idx].decode("utf-16be") self.data = decoded_string.rstrip("\0") else: raise ValueError("Unknown encoding") self._length = self._length_field_length + length return self someipy-2.1.2/src/someipy/server_service_instance.py000066400000000000000000000205611513043235100227420ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import base64 from typing import List from someipy._internal.daemon_client_abcs import ServerInstanceInterface from someipy._internal._daemon.someipy_daemon_client import SomeIpDaemonClient from someipy._internal._daemon.uds_messages import create_uds_message, SendEventRequest from someipy.service import EventGroup, Method, Service from someipy._internal.logging import get_logger _logger_name = "server_service_instance" class ServerServiceInstance(ServerInstanceInterface): """Server-side representation of a service instance used for offering SOME/IP services. This class manages the lifecycle of offering a service instance via the Some/IP-SD mechanism and enables sending events to subscribed clients. Parameters ---------- daemon : SomeIpDaemonClient Daemon client used to communicate with the someipy daemon. service : Service Service configuration for this instance. instance_id : int Instance ID for this service instance. endpoint_ip : str IP address of the endpoint on which the service instance is reachable. endpoint_port : int Port of the endpoint on which the service instance is reachable. ttl : int, optional TTL used for Service Discovery offers. Default: 0. cyclic_offer_delay_ms : int, optional Delay between cyclic offers in milliseconds. Default: 2000. """ def __init__( self, daemon: SomeIpDaemonClient, service: Service, instance_id: int, endpoint_ip: str, endpoint_port: int, ttl: int = 0, # TTL used for SD Offer entries cyclic_offer_delay_ms=2000, ): """Initialize a ServerServiceInstance. Parameters ---------- daemon : SomeIpDaemonClient Daemon client used to communicate with the someipy daemon. service : Service Service configuration for this instance. instance_id : int Instance ID for this service instance. endpoint_ip : str IP address of the endpoint on which the service instance is reachable. endpoint_port : int Port of the endpoint on which the service instance is reachable. ttl : int, optional TTL used for Service Discovery offers. Default: 0. cyclic_offer_delay_ms : int, optional Delay between cyclic offers in milliseconds. Default: 2000. """ self._daemon = daemon self._service = service self._instance_id = instance_id self._endpoint_ip = endpoint_ip self._endpoint_port = endpoint_port self._ttl = ttl self._cyclic_offer_delay_ms = cyclic_offer_delay_ms self._daemon._server_service_instances.append(self) async def start_offer(self): """Start offering the service instance via the service discovery offer entries. This method gathers the current service methods and event groups and invokes the daemon to advertise the service with the configured endpoint and version information. Returns ------- None """ methods: List[Method] = self._service.methods.values() eventgroups: List[EventGroup] = self._service.eventgroups.values() await self._daemon.offer_service( service_id=self._service.id, instance_id=self._instance_id, major_version=self._service.major_version, minor_version=self._service.minor_version, ttl=self._ttl, endpoint_ip=self._endpoint_ip, endpoint_port=self._endpoint_port, eventgroups=eventgroups, methods=methods, cyclic_offer_delay_ms=self._cyclic_offer_delay_ms, ) async def stop_offer(self): """Stop offering the service instance and send out a stop offer entry. This stops advertising the service instance to clients via the daemon. Returns ------- None """ methods: List[Method] = self._service.methods.values() eventgroups: List[EventGroup] = self._service.eventgroups.values() await self._daemon.stop_offer_service( service_id=self._service.id, instance_id=self._instance_id, major_version=self._service.major_version, minor_version=self._service.minor_version, ttl=self._ttl, endpoint_ip=self._endpoint_ip, endpoint_port=self._endpoint_port, eventgroups=eventgroups, methods=methods, cyclic_offer_delay_ms=self._cyclic_offer_delay_ms, ) def send_event(self, eventgroup_id: int, event_id: int, payload: bytes): """Send an event to clients subscribed to the event. This method validates the specified event group and event within the service definition, encodes the payload in Base64, constructs a UDS message and dispatches it through the daemon. Parameters ---------- eventgroup_id : int ID of the event group the event belongs to. event_id : int ID of the event to send. payload : bytes Payload of the event to transmit to clients. Returns ------- None Raises ------ ValueError If event group ID or event ID is not found within the service. """ if not eventgroup_id in self._service.eventgroupids: raise ValueError( f"Event group ID {eventgroup_id} not found in service 0x{self._service.id:04X}" ) eventgroup = self._service.eventgroups[eventgroup_id] events = [event for event in eventgroup.events if event.id == event_id] if not events: raise ValueError( f"Event ID {event_id} not found in event group 0x{eventgroup_id:04X} of service 0x{self._service.id:04X}" ) if len(events) > 1: raise ValueError( f"Multiple events with ID {event_id} found in event group 0x{eventgroup_id:04X} of service 0x{self._service.id:04X}" ) event = events[0] base64_encoded_payload = base64.b64encode(payload).decode("utf-8") message = create_uds_message( SendEventRequest, service_id=self._service.id, instance_id=self._instance_id, major_version=self._service.major_version, client_id=0, session_id=1, # TODO: Session ID eventgroup_id=eventgroup_id, event=event.to_json(), src_endpoint_ip=self._endpoint_ip, src_endpoint_port=self._endpoint_port, payload=base64_encoded_payload, ) self._daemon.transmit_message_to_daemon(message) @property def service(self) -> Service: """Service associated with this server service instance. Returns ------- Service The service configuration that this instance exposes. """ return self._service @property def instance_id(self) -> int: """Instance ID of this server service instance. Returns ------- int The unique identifier for this service instance. """ return self._instance_id @property def endpoint_ip(self) -> str: """IP address of the endpoint this instance offers services on. Returns ------- str Endpoint IP address. """ return self._endpoint_ip @property def endpoint_port(self) -> int: """Port of the endpoint this instance offers services on. Returns ------- int Endpoint port number. """ return self._endpoint_port someipy-2.1.2/src/someipy/service.py000066400000000000000000000251231513043235100174670ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from dataclasses import dataclass import json from typing import List, Callable, Tuple, Dict, TypeVar from someipy._internal.method_result import MethodResult from someipy._internal.transport_layer_protocol import TransportLayerProtocol MethodHandler = Callable[[bytes, Tuple[str, int]], MethodResult] _T = TypeVar("_T") @dataclass class Method: """ Class representing a SOME/IP method with a method id and a method handler. Parameters ---------- id : int Method identifier. protocol : TransportLayerProtocol Transport protocol for the method. method_handler : MethodHandler, optional Optional method which is called on server side when an offered service is invoked. The handler shall return a MethodResult. """ id: int protocol: TransportLayerProtocol method_handler: MethodHandler def __init__( self, id: int, protocol: TransportLayerProtocol, method_handler: MethodHandler = None, ): """Initialize a Method. Parameters ---------- id : int Method identifier. protocol : TransportLayerProtocol Transport protocol for the method. method_handler : MethodHandler, optional Optional method which is called on server side when an offered service is invoked. The handler shall return a MethodResult. """ self.id = id self.protocol = protocol self.method_handler = method_handler def __eq__(self, __value: object) -> bool: """Check equality with another Method based on id and protocol. Parameters ---------- __value : object Another Method instance. Returns ------- bool True if ids and protocols match, False otherwise. """ return self.id == __value.id and self.protocol == __value.protocol def to_json(self) -> str: """Serialize this Method to a JSON string. Returns ------- str JSON representation of the method. """ as_dict = { "id": self.id, "protocol": self.protocol.value, } return json.dumps(as_dict) @classmethod def from_json(cls: _T, json_str: str) -> _T: """Create a Method from a JSON string. Parameters ---------- json_str : str JSON representation of a Method. Returns ------- Method The constructed Method instance. """ json_dict = json.loads(json_str) id = int(json_dict["id"]) protocol = TransportLayerProtocol(json_dict["protocol"]) method_handler = None o = cls(id, protocol, method_handler) return o @dataclass class Event: """ Class representing a SOME/IP event with an event id and a transport layer protocol. """ id: int protocol: TransportLayerProtocol def to_json(self) -> str: """Serialize this Event to JSON. Returns ------- str JSON representation of the event. """ as_dict = { "id": self.id, "protocol": self.protocol.value, } return json.dumps(as_dict) @classmethod def from_json(cls: _T, json_str: str) -> _T: """Create an Event from a JSON string. Parameters ---------- json_str : str JSON representation of an Event. Returns ------- Event """ json_dict = json.loads(json_str) o = cls(int(json_dict["id"]), TransportLayerProtocol(json_dict["protocol"])) return o @dataclass class EventGroup: """ Class representing a SOME/IP eventgroup with an eventgroup id and a list of event ids. """ id: int events: List[Event] def to_json(self) -> str: """Serialize this EventGroup to JSON. Returns ------- str JSON representation of the event group. """ as_dict = { "id": self.id, "events": [event.to_json() for event in self.events], } return json.dumps(as_dict) @classmethod def from_json(cls: _T, json_str: str) -> _T: """Create an EventGroup from a JSON string. Parameters ---------- json_str : str JSON representation of an EventGroup. Returns ------- EventGroup """ json_dict = json.loads( json_str ) # Contains a dictionary with "id" (int) and "events" (serialized Event) events = [Event.from_json(event_json) for event_json in json_dict["events"]] o: EventGroup = cls(int(json_dict["id"]), events) return o def __hash__(self): """Return a hash based on the group id and contained event ids.""" return hash((self.id, tuple(event.id for event in self.events))) @property def has_udp(self) -> bool: """ Checks if the event group contains any events with UDP protocol. Returns ------- bool True if at least one event uses UDP, False otherwise. """ return any( event.protocol == TransportLayerProtocol.UDP for event in self.events ) @property def has_tcp(self) -> bool: """ Checks if the event group contains any events with TCP protocol. Returns ------- bool True if at least one event uses TCP, False otherwise. """ return any( event.protocol == TransportLayerProtocol.TCP for event in self.events ) @dataclass class Service: """ Class representing a SOME/IP service. A service has an id, major and minor version and 0 or more methods and/or eventgroups. Attributes ---------- id : int Service identifier. major_version : int Major version of the service. minor_version : int Minor version of the service. methods : Dict[int, Method] Mapping of method IDs to Method instances. eventgroups : Dict[int, EventGroup] Mapping of event group IDs to EventGroup instances. """ id: int major_version: int minor_version: int methods: Dict[int, Method] eventgroups: Dict[int, EventGroup] def __init__(self): """Initialize a new Service instance with defaults.""" self.id = 0 self.major_version = 1 self.minor_version = 0 self.methods = dict() self.eventgroups = dict() @property def eventgroupids(self) -> List[int]: """ Returns a list of event group IDs associated with the service. Returns ------- List[int] List of event group IDs. """ return list(self.eventgroups.keys()) @property def events(self) -> List[Event]: """ Returns a list of events associated with the service. Returns ------- List[Event] All events across event groups for this service. """ return [ event for eventgroup in self.eventgroups.values() for event in eventgroup.events ] @property def methodids(self) -> List[int]: """ Returns a list of method IDs associated with the object. Returns ------- List[int] List of method IDs. """ return list(self.methods.keys()) class ServiceBuilder: """ Class used to build a Service using a fluent API. Call the 'with' methods to add methods and event groups to the service. Call the build method to create the service. """ def __init__(self): """Initializes a new ServiceBuilder instance.""" self._service = Service() def with_service_id(self, id: int) -> "ServiceBuilder": """ Sets the service id for the service to be built. Parameters ---------- id : int The ID of the service. Returns ------- ServiceBuilder """ self._service.id = id return self def with_major_version(self, major_version: int) -> "ServiceBuilder": """ Sets the major version for the service to be built. Parameters ---------- major_version : int The major version of the service. Returns ------- ServiceBuilder """ self._service.major_version = major_version return self def with_minor_version(self, minor_version: int) -> "ServiceBuilder": """ Sets the minor version for the service to be built. Parameters ---------- minor_version : int The minor version of the service. Returns ------- ServiceBuilder """ self._service.minor_version = minor_version return self def with_method(self, method: Method) -> "ServiceBuilder": """ Adds a method to the service to be built. Parameters ---------- method : Method The method to be added. Returns ------- ServiceBuilder """ if self._service.methods.get(method.id) is None: self._service.methods[method.id] = method return self def with_eventgroup(self, eventgroup: EventGroup) -> "ServiceBuilder": """ Adds an event group to the service to be built. Parameters ---------- eventgroup : EventGroup The event group to be added. Returns ------- ServiceBuilder """ if self._service.eventgroups.get(eventgroup.id) is None: self._service.eventgroups[eventgroup.id] = eventgroup return self def build(self) -> Service: """Builds and returns a Service. Returns ------- Service The built Service. """ return self._service someipy-2.1.2/src/someipy/someipy_logging.py000066400000000000000000000026361513043235100212260ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging _log_level = logging.DEBUG def set_someipy_log_level(logging_level: int): """ Set the log level for the someipy module. Parameters ---------- logging_level (int): The log level to set. Must be one of the constants defined in the logging module, such as logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, or logging.CRITICAL. Returns ------- None """ global _log_level _log_level = logging_level def get_someipy_log_level() -> int: """ Get the current log level for the someipy library. Parameters ---------- int: The current log level. Returns ------- int: The current log level. """ global _log_level return _log_level someipy-2.1.2/src/someipy/someipyd.json000066400000000000000000000002771513043235100202040ustar00rootroot00000000000000{ "sd_address": "224.224.224.245", "sd_port": 30490, "log_level": "DEBUG", "interface": "127.0.0.1", "use_tcp": false, "tcp_host": "127.0.0.1", "tcp_port": 30500 }someipy-2.1.2/src/someipy/someipyd.py000066400000000000000000002174351513043235100176710ustar00rootroot00000000000000# Copyright (C) 2024 Christian H. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import argparse import asyncio import base64 from dataclasses import dataclass import functools import json import logging import os import struct import sys import ipaddress import time from typing import Any, Dict, List, Set, Tuple, Union import someipy from someipy._internal._common.endpoint import Endpoint from someipy._internal._daemon.daemon_server_client import ( ClientMessageEventArgs, DaemonServerClient, ) from someipy._internal._daemon.subscription import Subscription from someipy._internal._daemon.subscription_storage import SubscriptionStorage from someipy._internal._sd.deserialization.sd_deserialization import ( deserialize_sd_message, is_sd_message, ) from someipy._internal._sd.deserialization.sd_serialization import serialize_sd_message from someipy._internal._sd.entries.offer_service_entry import OfferServiceEntry from someipy._internal._sd.entries.stop_subscribe_eventgroup_entry import ( StopSubscribeEventGroupEntry, ) from someipy._internal._sd.entries.subscribe_eventgroup_entry import ( SubscribeEventGroupEntry, ) from someipy._internal._sd.options.endpoint import IpV4EndpointOption from someipy._internal._sd.sd_message import SdMessage from someipy._internal._sd.sd_message_creator import ( create_offer_service_message, create_stop_offer_service_message, ) from someipy._internal._sd.service_instance import ServiceInstance from someipy._internal.message_types import MessageType from someipy._internal.someip_endpoint import ( TCPClientSomeipEndpoint, TCPSomeipEndpoint, ) from someipy._internal.someip_endpoint_factory import SomeipEndpointFactory from someipy._internal.someip_endpoint_storage import SomeipEndpointStorage from someipy._internal.someip_message import SomeIpMessage from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy._internal.session_handler import SessionHandler from someipy._internal.simple_timer import SimplePeriodicTimer from someipy._internal.someip_header import SomeIpHeader from someipy._internal.someip_sd_builder import ( build_subscribe_eventgroup_ack_entry, build_subscribe_eventgroup_ack_sd_header, ) from someipy._internal.someip_sd_extractors import ( extract_subscribe_ack_eventgroup_entries, extract_subscribe_entries, extract_subscribe_nack_eventgroup_entries, ) from someipy._internal.someip_sd_header import ( SdEntryType, SdEventGroupEntry, SdService, SdService2, SdServiceWithTimestamp, SdSubscription, SomeIpSdHeader, ) from someipy._internal.subscribers import EventGroupSubscriber, Subscribers from someipy._internal._daemon.uds_messages import ( InboundCallMethodRequest, InboundCallMethodResponse, FindServiceRequest, FindServiceResponse, OfferServiceRequest, OutboundCallMethodRequest, OutboundCallMethodResponse, ReceivedEvent, SendEventRequest, StopOfferServiceRequest, StopSubscribeEventGroupRequest, SubscribeEventGroupRequest, create_uds_message, ) from someipy._internal.utils import ( DatagramAdapter, create_rcv_multicast_socket, create_rcv_broadcast_socket, create_udp_socket, ) from someipy._internal._daemon.offer_service_storage import ( OfferServiceStorage, ServiceToOffer, ) from someipy.service import Event, Method, EventGroup from someipy._internal._daemon.daemon_server import ( ClientConnectedEventArgs, DaemonServer, ) DEFAULT_SOCKET_PATH = "/tmp/someipyd.sock" DEFAULT_CONFIG_FILE = "someipyd.json" DEFAULT_SD_ADDRESS = "224.224.224.245" DEFAULT_INTERFACE_IP = "127.0.0.1" DEFAULT_SD_PORT = 30490 DEFAULT_TCP_PORT = 30500 @dataclass class MethodCall: service_id: int method_id: int client_id: int session_id: int src_ip: str src_port: int def __hash__(self): return hash( ( self.service_id, self.method_id, self.client_id, self.session_id, self.src_ip, self.src_port, ) ) class SomeipDaemon: def __init__( self, server: DaemonServer, endpoint_factory: SomeipEndpointFactory, config: dict = None, logger: logging.Logger = None, ): self.config = config self.logger = logger self._endpoint_factory = endpoint_factory self.sd_address = self.config.get("sd_address", DEFAULT_SD_ADDRESS) self.sd_port = self.config.get("sd_port", DEFAULT_SD_PORT) self.interface = self.config.get("interface", DEFAULT_INTERFACE_IP) self._server = server self._sd_socket_mcast = None self._sd_socket_ucast = None self._mcast_transport = None self._ucast_transport = None # Services offered by other ECUs self._found_services: List[ServiceInstance] = [] # Services offered by this daemon self._services_to_offer = OfferServiceStorage() self._offer_timers: Dict[int, SimplePeriodicTimer] = {} # Active subscriptions to services offered by this daemon self._service_subscribers: Dict[ServiceToOffer, Subscribers] = {} # Subscriptions requested by local clients self._requested_subscriptions = SubscriptionStorage() self._pending_subscriptions: Set[Subscription] = set() self._active_subscriptions: Set[Subscription] = set() self._mcast_session_handler = SessionHandler() self._unicast_session_handler = SessionHandler() # Qeueues and tasks stored by id of asyncio.StreamWriter self._tx_queues: Dict[int, asyncio.Queue] = {} self._tx_tasks: Dict[int, asyncio.Task] = {} self._someip_server_endpoints = SomeipEndpointStorage() self._someip_client_endpoints = SomeipEndpointStorage() self._ttl_task: asyncio.Task = None self._issued_method_calls: Dict[MethodCall, int] = {} async def new_client_connected( self, sender: object, event_args: ClientConnectedEventArgs ): self.logger.info(f"New client connected: {event_args.client.id}") # Create the tx_queue and tx_task for the client using the writers id self._tx_queues[event_args.client.id] = asyncio.Queue() self._tx_tasks[event_args.client.id] = asyncio.create_task( self.tx_task(event_args.client) ) event_args.client.message_received += self.handle_client_message async def client_disconnected( self, sender: object, event_args: ClientConnectedEventArgs ): self.logger.info(f"Client disconnected: {event_args.client.id}") client_id = event_args.client.id event_args.client.message_received -= self.handle_client_message # Remove all subscriptions for the client self._requested_subscriptions.remove_client(client_id) # Clean up the transmission task for the client. This will also clean up the transmission queue tx_task = self._tx_tasks.pop(client_id, None) if tx_task and not tx_task.cancelled(): tx_task.cancel() try: await tx_task except asyncio.CancelledError: pass self._services_to_offer.remove_client(client_id) self._cleanup_unused_timers() client_endpoints = self._someip_server_endpoints.get_endpoints(client_id) if client_endpoints is not None: for endpoint in client_endpoints: self.logger.debug( f"Closing endpoint {endpoint.dst_ip()}:{endpoint.dst_port()} for client {client_id}" ) endpoint.shutdown() self._someip_server_endpoints.remove_endpoint(client_id, endpoint) self.logger.debug(f"Client disconnected") async def _check_services_ttl_task(self): try: while True: await asyncio.sleep(0.1) self._check_service_ttl_task_impl() except asyncio.CancelledError: # Task was cancelled - exit cleanly self.logger.debug("Service TTL checker task cancelled") except Exception as e: self.logger.error(f"Error in service TTL checker task: {e}") pass def _check_service_ttl_task_impl(self): self._cleanup_obsolete_pending_subscriptions() self._cleanup_active_subscriptions() count_before = len(self._found_services) current_time = time.time() # Process timeouts and filter services in one operation self._found_services = [ service for service in self._found_services if not (current_time - service.timestamp > service.ttl) ] count_after = len(self._found_services) if count_before != count_after: self.logger.info( f"Removed {count_before - count_after} timed out services. Remaining: {count_after}" ) def _someip_message_callback( self, message: SomeIpMessage, src_addr: Tuple[str, int], dst_addr: Tuple[str, int], protocol: TransportLayerProtocol, ) -> None: self.logger.debug( f"Received SOME/IP message from {src_addr} to {dst_addr} with protocol {protocol}" ) header = message.header if MessageType(header.message_type) == MessageType.REQUEST: service_id = header.service_id method_id = header.method_id for service in self._services_to_offer.get_all_services(): if ( service.service_id == service_id and str(service.endpoint.ip) == dst_addr[0] and service.endpoint.port == dst_addr[1] ): self.logger.debug(f"Found matching service {service.service_id}") for method in service.methods: if method.id == method_id: self.logger.debug( f"Found matching method id {method.id} for service {service_id}" ) payload_encoded = base64.b64encode(message.payload).decode( "utf-8" ) call_method_request = create_uds_message( InboundCallMethodRequest, service_id=service_id, instance_id=service.instance_id, method_id=method_id, client_id=header.client_id, session_id=header.session_id, protocol_version=header.protocol_version, interface_version=header.interface_version, major_version=service.major_version, minor_version=service.minor_version, message_type=header.message_type, src_endpoint_ip=src_addr[0], src_endpoint_port=src_addr[1], protocol=protocol.value, payload=payload_encoded, ) tx_queue = self._tx_queues.get(service.client_writer_id) if tx_queue: tx_queue.put_nowait( self.prepare_message(call_method_request) ) elif MessageType(header.message_type) == MessageType.RESPONSE: issued_call = MethodCall( service_id=header.service_id, method_id=header.method_id, client_id=header.client_id, session_id=header.session_id, src_ip=dst_addr[0], src_port=dst_addr[1], ) if not issued_call in self._issued_method_calls: self.logger.debug(f"Received response for unknown method call.") return writer_id = self._issued_method_calls[issued_call] del self._issued_method_calls[issued_call] payload_encoded = base64.b64encode(message.payload).decode("utf-8") message = create_uds_message( OutboundCallMethodResponse, service_id=header.service_id, method_id=header.method_id, client_id=header.client_id, session_id=header.session_id, return_code=header.return_code, dst_endpoint_ip=dst_addr[0], dst_endpoint_port=dst_addr[1], payload=payload_encoded, ) self._tx_queues[writer_id].put_nowait(self.prepare_message(message)) elif MessageType(header.message_type) == MessageType.NOTIFICATION: if header.return_code == 0x00 and header.client_id == 0x00: self.logger.debug( f"Received notification for service {header.service_id}, event {header.method_id}" ) event_id = header.method_id event_msg = create_uds_message( ReceivedEvent, service_id=header.service_id, event_id=event_id, src_endpoint_ip=src_addr[0], src_endpoint_port=src_addr[1], payload=base64.b64encode(message.payload).decode("utf-8"), ) for active_subscription in self._active_subscriptions: event_ids = [i.id for i in active_subscription.eventgroup.events] self.logger.debug("check event ids: %s", event_ids) if ( event_id in event_ids and str(active_subscription.server_endpoint.ip) == src_addr[0] and active_subscription.server_endpoint.port == src_addr[1] and active_subscription.service_id == header.service_id ): self.logger.debug( f"Found active subscription for service {header.service_id}, " f"instance {active_subscription.instance_id}, " f"eventgroup {active_subscription.eventgroup.id}, " ) for ( requested_subscription ) in self._requested_subscriptions.subscriptions: if ( requested_subscription.service_id == active_subscription.service_id and requested_subscription.instance_id == active_subscription.instance_id and requested_subscription.major_version == active_subscription.major_version and requested_subscription.eventgroup == active_subscription.eventgroup and requested_subscription.client_endpoint.ip == active_subscription.client_endpoint.ip and requested_subscription.client_endpoint.port == active_subscription.client_endpoint.port ): client_ids = ( self._requested_subscriptions.get_client_ids( requested_subscription ) ) for client_id in client_ids: tx_queue = self._tx_queues.get(client_id) if tx_queue: tx_queue.put_nowait( self.prepare_message(event_msg) ) def _cleanup_active_subscriptions(self): current_time = time.time() subscriptions_to_remove = [] for subscription in self._active_subscriptions: if ( current_time - subscription.timestamp_last_update > subscription.ttl_seconds ): subscriptions_to_remove.append(subscription) for subscription in subscriptions_to_remove: self._active_subscriptions.remove(subscription) self.logger.debug( f"Removed active subscription for service {subscription.service_id}, " f"instance {subscription.instance_id}, eventgroup {subscription.eventgroup_id}" ) def _cleanup_obsolete_pending_subscriptions(self): current_time = time.time() subscriptions_to_remove = [] for subscription in self._pending_subscriptions: if current_time - subscription.timestamp_last_update > 10.0: subscriptions_to_remove.append(subscription) for subscription in subscriptions_to_remove: self._pending_subscriptions.remove(subscription) def _cleanup_unused_timers(self): timers_to_stop = [] for interval in self._offer_timers.keys(): if ( len(self._services_to_offer.services_by_cyclic_offer_delay(interval)) == 0 ): timers_to_stop.append(interval) for interval in timers_to_stop: self.logger.debug(f"Stopping offer timer for {interval}ms") self._offer_timers[interval].stop() del self._offer_timers[interval] def _close_unused_endpoints(self): endpoints_to_close = [] # Loop through all endpoints. For each endpoint loop through offered services and check if the endpoint is used by any service for endpoint in self._someip_server_endpoints: endpoint_used = False for service in self._services_to_offer.services: if ( service.endpoint.ip == endpoint.ip() and service.endpoint_port == endpoint.port() ): endpoint_used = True break if not endpoint_used: endpoints_to_close.append(endpoint) async def tx_task(self, client: DaemonServerClient): tx_queue = self._tx_queues[client.id] try: while True: try: # Wait on queue with timeout data = await asyncio.wait_for(tx_queue.get(), timeout=0.2) try: # Send the data await client.send(data) tx_queue.task_done() except ConnectionError as e: self.logger.error(f"Error sending data in tx task: {e}") break except asyncio.TimeoutError: # Periodic timeout for cancellation check continue except asyncio.CancelledError: self.logger.debug(f"TX task for writer {client.id} cancelled") # Perform cleanup here try: await client.close() except Exception as e: self.logger.error(f"Error closing writer: {e}") finally: # Always clean up the queue self._tx_queues.pop(client.id, None) self.logger.debug(f"TX task for writer {client.id} finished") async def handle_client_message( self, sender: object, event_args: ClientMessageEventArgs ): client_id = event_args.client.id message = event_args.message message_type = event_args.message.get("type") self.logger.debug(f"Received message type: {message_type}") message_handlers = { OfferServiceRequest.__name__: self._handle_offer_service_request, StopOfferServiceRequest.__name__: self._handle_stop_offer_service_request, InboundCallMethodResponse.__name__: self._handle_inbound_call_method_response, FindServiceRequest.__name__: self._handle_find_service_request, OutboundCallMethodRequest.__name__: self._handle_outbound_call_method_request, SendEventRequest.__name__: self._handle_send_event_request, SubscribeEventGroupRequest.__name__: self._handle_subscribe_eventgroup_request, StopSubscribeEventGroupRequest.__name__: self._handle_stop_subscribe_eventgroup_request, } if message_type in message_handlers: handler = message_handlers[message_type] if asyncio.iscoroutinefunction(handler): await handler(message, client_id) return else: handler(message, client_id) return else: self.logger.warning( f"Received unknown message type: {message_type}. Message: {message}" ) async def _handle_subscribe_eventgroup_request( self, message: SubscribeEventGroupRequest, client_id: int ): protocols = [] if message["udp"]: protocols.append(TransportLayerProtocol.UDP) if not self._someip_client_endpoints.has_endpoint( message["client_endpoint_ip"], message["client_endpoint_port"], TransportLayerProtocol.UDP, ): self.logger.debug( f"Creating new UDP endpoint for {message['client_endpoint_ip']}:{message['client_endpoint_port']}" ) udp_endpoint = await self._endpoint_factory.create_server_endpoint( Endpoint( ip=ipaddress.IPv4Address(message["client_endpoint_ip"]), port=message["client_endpoint_port"], ), TransportLayerProtocol.UDP, self._someip_message_callback, ) self._someip_client_endpoints.add_endpoint(client_id, udp_endpoint) if message["tcp"]: protocols.append(TransportLayerProtocol.TCP) event_group = EventGroup.from_json(message["eventgroup"]) client_address = ipaddress.IPv4Address(message["client_endpoint_ip"]) client_endpoint = Endpoint( ip=client_address, port=message["client_endpoint_port"] ) new_subscription = Subscription( service_id=message["service_id"], instance_id=message["instance_id"], major_version=message["major_version"], client_endpoint=client_endpoint, server_endpoint=None, protocols=frozenset(protocols), eventgroup=event_group, ttl_seconds=message["ttl_subscription"], ) if new_subscription in self._requested_subscriptions.subscriptions: self.logger.warning( f"The requested subscription received by client {client_id} is already requested." ) self.logger.debug(f"Add subscription to storage with id {client_id}") self._requested_subscriptions.add_subscription(client_id, new_subscription) def _handle_stop_subscribe_eventgroup_request( self, message: StopSubscribeEventGroupRequest, client_id: int ): client_endpoint = Endpoint( ip=ipaddress.IPv4Address(message["client_endpoint_ip"]), port=message["client_endpoint_port"], ) event_group = EventGroup.from_json(message["eventgroup"]) protocols = [ protocol for flag, protocol in ( (message["udp"], TransportLayerProtocol.UDP), (message["tcp"], TransportLayerProtocol.TCP), ) if flag ] subscription_to_remove = Subscription( service_id=message["service_id"], instance_id=message["instance_id"], major_version=message["major_version"], client_endpoint=client_endpoint, server_endpoint=None, protocols=frozenset(protocols), eventgroup=event_group, ttl_seconds=0, # TTL is not relevant for removal ) self._requested_subscriptions.remove_subscription( client_id, subscription_to_remove ) if ( len(self._requested_subscriptions.get_client_ids(subscription_to_remove)) == 0 ): for pending_subscription in list(self._pending_subscriptions): if ( pending_subscription.service_id == subscription_to_remove.service_id and pending_subscription.instance_id == subscription_to_remove.instance_id and pending_subscription.major_version == subscription_to_remove.major_version and pending_subscription.eventgroup.id == subscription_to_remove.eventgroup.id and pending_subscription.client_endpoint == subscription_to_remove.client_endpoint ): self._pending_subscriptions.remove(pending_subscription) for active_subscription in list(self._active_subscriptions): if ( active_subscription.service_id == subscription_to_remove.service_id and active_subscription.instance_id == subscription_to_remove.instance_id and active_subscription.major_version == subscription_to_remove.major_version and active_subscription.eventgroup.id == subscription_to_remove.eventgroup.id and active_subscription.client_endpoint == subscription_to_remove.client_endpoint ): self._active_subscriptions.remove(active_subscription) ( session_id, reboot_flag, ) = self._unicast_session_handler.update_session() # Build subscribe message sd_message = SdMessage() sd_message.session_id = session_id sd_message.reboot_flag = reboot_flag options = [] for protocol in active_subscription.protocols: options.append( IpV4EndpointOption( address=active_subscription.client_endpoint.ip, protocol=protocol, port=active_subscription.client_endpoint.port, ) ) entry = StopSubscribeEventGroupEntry( service_id=active_subscription.service_id, instance_id=active_subscription.instance_id, major_version=active_subscription.major_version, eventgroup_id=active_subscription.eventgroup.id, counter=0, ip_v4_endpoints=options, ip_v6_endpoints=[], ) sd_message.entries.append(entry) # Send to server if self._ucast_transport: self._ucast_transport.sendto( serialize_sd_message(sd_message), ( str(active_subscription.server_endpoint.ip), self.sd_port, ), ) async def _handle_offer_service_request( self, message: OfferServiceRequest, client_id: int ): method_strs = message.get("method_list", []) methods = [Method.from_json(m) for m in method_strs] eventgroup_strs = message.get("eventgroup_list", []) eventgroups = [EventGroup.from_json(e) for e in eventgroup_strs] """ - Store offered service including events - Subscribe received with service id, instance id, major version, ttl, eventgroup id. References an endpoint with ip and port option - If service is offered and found, send back an acknowledge and store the subscription with: - endpoint ip and port of the client where the events shall be sent to - service id, instance id, major version, eventgroup id, """ service_to_add = ServiceToOffer( client_writer_id=client_id, instance_id=message["instance_id"], service_id=message["service_id"], major_version=message["major_version"], minor_version=message["minor_version"], offer_ttl_seconds=message["ttl"], cyclic_offer_delay_ms=message["cyclic_offer_delay_ms"], endpoint=Endpoint( ipaddress.IPv4Address(message["endpoint_ip"]), message["endpoint_port"] ), methods=methods, eventgroups=eventgroups, ) self._services_to_offer.add_service(service_to_add) # Check if there is already an endpoint for the ip and port, if not, open a new endpoint if service_to_add.has_udp: if not self._someip_server_endpoints.has_endpoint( str(service_to_add.endpoint.ip), service_to_add.endpoint.port, TransportLayerProtocol.UDP, ): self.logger.debug( f"Creating new UDP endpoint for {service_to_add.endpoint}" ) udp_endpoint = await self._endpoint_factory.create_server_endpoint( service_to_add.endpoint, TransportLayerProtocol.UDP, self._someip_message_callback, ) self._someip_server_endpoints.add_endpoint(client_id, udp_endpoint) if service_to_add.has_tcp: if not self._someip_server_endpoints.has_endpoint( str(service_to_add.endpoint.ip), service_to_add.endpoint.port, TransportLayerProtocol.TCP, ): self.logger.debug( f"Creating new TCP endpoint for {service_to_add.endpoint}" ) tcp_endpoint = await self._endpoint_factory.create_server_endpoint( service_to_add.endpoint, TransportLayerProtocol.TCP, self._someip_message_callback, ) self._someip_server_endpoints.add_endpoint(client_id, tcp_endpoint) cyclic_offer_delay_ms = message["cyclic_offer_delay_ms"] # If there is no timer running for the interval yet, create a new timer task if cyclic_offer_delay_ms not in self._offer_timers: self.logger.debug(f"Starting new offer timer for {cyclic_offer_delay_ms}ms") self._offer_timers[cyclic_offer_delay_ms] = SimplePeriodicTimer( cyclic_offer_delay_ms / 1000.0, functools.partial(self.offer_timer_callback, cyclic_offer_delay_ms), ) self._offer_timers[cyclic_offer_delay_ms].start() def _handle_stop_offer_service_request( self, message: StopOfferServiceRequest, writer_id: int ): method_strs = message.get("method_list", []) methods = [Method.from_json(m) for m in method_strs] eventgroup_strs = message.get("eventgroup_list", []) eventgroups = [EventGroup.from_json(e) for e in eventgroup_strs] service_to_stop = ServiceToOffer( client_writer_id=writer_id, instance_id=message["instance_id"], service_id=message["service_id"], major_version=message["major_version"], minor_version=message["minor_version"], offer_ttl_seconds=message["ttl"], cyclic_offer_delay_ms=message["cyclic_offer_delay_ms"], endpoint=Endpoint( ipaddress.IPv4Address(message["endpoint_ip"]), message["endpoint_port"] ), methods=methods, eventgroups=eventgroups, ) # Remove the service from the storage self._services_to_offer.remove_service(service_to_stop) self._cleanup_unused_timers() ( session_id, reboot_flag, ) = self._mcast_session_handler.update_session() sd_message = create_stop_offer_service_message( services_to_stop=[service_to_stop], session_id=session_id, reboot_flag=reboot_flag, ) if self._ucast_transport: self.logger.debug( f"Send stop offer message for service 0x{service_to_stop.service_id:04x}, instance 0x{service_to_stop.instance_id:04x} to {self.sd_address}:{self.sd_port}" ) self._ucast_transport.sendto( serialize_sd_message(sd_message), (self.sd_address, self.sd_port) ) if service_to_stop.has_udp: try: udp_endpoint = self._someip_server_endpoints.get_endpoint( writer_id, TransportLayerProtocol.UDP ) if udp_endpoint: self.logger.debug( f"Closing UDP endpoint for {service_to_stop.endpoint}" ) udp_endpoint.shutdown() self._someip_server_endpoints.remove_endpoint( writer_id, udp_endpoint ) except Exception as e: self.logger.error( f"Error closing UDP endpoint for {service_to_stop.endpoint}: {e}" ) if service_to_stop.has_tcp: try: tcp_endpoint = self._someip_server_endpoints.get_endpoint( writer_id, TransportLayerProtocol.TCP ) if tcp_endpoint: self.logger.debug( f"Closing TCP endpoint for {service_to_stop.endpoint}" ) tcp_endpoint.shutdown() self._someip_server_endpoints.remove_endpoint( writer_id, tcp_endpoint ) except Exception as e: self.logger.error( f"Error closing TCP endpoint for {service_to_stop.endpoint}: {e}" ) def _handle_inbound_call_method_response( self, message: InboundCallMethodResponse, writer_id: int ): self.logger.debug(f"Received CallMethodResponse: {message}") header = SomeIpHeader( service_id=message["service_id"], method_id=message["method_id"], length=0, client_id=message["client_id"], session_id=message["session_id"], protocol_version=message["protocol_version"], interface_version=message["interface_version"], message_type=message["message_type"], return_code=message["return_code"], ) payload_decoded = base64.b64decode(message["payload"]) header.length = 8 + len(payload_decoded) endpoint = self._someip_server_endpoints.get_endpoint( writer_id, TransportLayerProtocol(message["protocol"]) ) self.logger.debug( f"Sending CallMethodResponse to {message['src_endpoint_ip']}:{message['src_endpoint_port']}" ) if endpoint: endpoint.sendto( header.to_buffer() + payload_decoded, (message["src_endpoint_ip"], message["src_endpoint_port"]), ) async def _handle_outbound_call_method_request( self, message: OutboundCallMethodRequest, client_id: int ): endpoint = None if TransportLayerProtocol(message["protocol"]) == TransportLayerProtocol.UDP: if not self._someip_client_endpoints.has_endpoint( message["src_endpoint_ip"], message["src_endpoint_port"], TransportLayerProtocol.UDP, ): self.logger.debug( f"Creating new UDP endpoint for {message['src_endpoint_ip']}:{message['src_endpoint_port']}" ) dst_endpoint = Endpoint( ip=ipaddress.IPv4Address(message["dst_endpoint_ip"]), port=message["dst_endpoint_port"], ) src_endpoint = Endpoint( ip=ipaddress.IPv4Address(message["src_endpoint_ip"]), port=message["src_endpoint_port"], ) udp_endpoint = await self._endpoint_factory.create_udp_client_endpoint( dst_endpoint, src_endpoint, self._someip_message_callback, self.logger, ) self._someip_client_endpoints.add_endpoint(client_id, udp_endpoint) endpoint = udp_endpoint else: endpoint = self._someip_client_endpoints.get_endpoint_by_ip_port( message["src_endpoint_ip"], message["src_endpoint_port"], TransportLayerProtocol.UDP, ) elif TransportLayerProtocol(message["protocol"]) == TransportLayerProtocol.TCP: if not self._someip_client_endpoints.has_tcp_endpoint( message["src_endpoint_ip"], message["src_endpoint_port"], message["dst_endpoint_ip"], message["dst_endpoint_port"], ): self.logger.debug( f"Creating new TCP endpoint for {message['src_endpoint_ip']}:{message['src_endpoint_port']}" ) tcp_endpoint = self._endpoint_factory.create_tcp_client_endpoint( Endpoint( ip=ipaddress.IPv4Address(message["dst_endpoint_ip"]), port=message["dst_endpoint_port"], ), Endpoint( ip=ipaddress.IPv4Address(message["src_endpoint_ip"]), port=message["src_endpoint_port"], ), self._someip_message_callback, self.logger, ) self._someip_client_endpoints.add_endpoint(client_id, tcp_endpoint) endpoint: TCPClientSomeipEndpoint = tcp_endpoint else: endpoint: TCPClientSomeipEndpoint = ( self._someip_client_endpoints.get_end_point_by_src_and_dst_ip_port( message["src_endpoint_ip"], message["src_endpoint_port"], message["dst_endpoint_ip"], message["dst_endpoint_port"], TransportLayerProtocol.TCP, ) ) # TODO: This shall not block the handle_client function. A new task shall be created # For TCP wait for the connection to be established while not endpoint.is_connected(): # self.logger.debug( # f"Waiting for TCP connection to {message['dst_endpoint_ip']}:{message['dst_endpoint_port']}" # ) await asyncio.sleep(0.2) # Build the request message self.logger.debug( f"Sending OutboundCallMethodRequest to {message['dst_endpoint_ip']}:{message['dst_endpoint_port']}" ) decoded_payload = base64.b64decode(message["payload"]) header = SomeIpHeader( service_id=message["service_id"], method_id=message["method_id"], client_id=message["client_id"], session_id=message["session_id"], protocol_version=0x01, interface_version=message["major_version"], message_type=MessageType.REQUEST.value, return_code=0x00, length=len(decoded_payload) + 8, ) someip_message = SomeIpMessage(header, decoded_payload) new_call = MethodCall( service_id=message["service_id"], method_id=message["method_id"], client_id=message["client_id"], session_id=message["session_id"], src_ip=message["src_endpoint_ip"], src_port=message["src_endpoint_port"], ) if new_call in self._issued_method_calls: self.logger.warning( f"Method call {new_call} already issued. Overwriting writer_id." ) self._issued_method_calls[new_call] = client_id endpoint.sendto( someip_message.serialize(), (message["dst_endpoint_ip"], message["dst_endpoint_port"]), ) def _handle_find_service_request(self, message: FindServiceRequest, writer_id: int): service_found = False all_services = [s for s in self._found_services] for service in self._services_to_offer.get_all_services(): protocols_to_add = set() if service.has_udp: protocols_to_add.add(TransportLayerProtocol.UDP) if service.has_tcp: protocols_to_add.add(TransportLayerProtocol.TCP) service_to_add = ServiceInstance( service_id=service.service_id, instance_id=service.instance_id, major_version=service.major_version, minor_version=service.minor_version, ttl=service.offer_ttl_seconds, endpoint=service.endpoint, protocols=frozenset(protocols_to_add), timestamp=0.0, ) all_services.append(service_to_add) for found_service in all_services: """ • Instance ID shall be set to 0xFFFF, if all service instances shall be returned. It shall be set to the Instance ID of a specific service instance, if just a single service instance shall be returned. • Major Version shall be set to 0xFF, that means that services with any version shall be returned. If set to value different than 0xFF, services with this specific major version shall be returned only. • Minor Version shall be set to 0xFFFF FFFF, that means that services with any version shall be returned. If set to a value different to 0xFFFF FFFF, services with this specific minor version shall be returned only """ if ( (message["service_id"] == found_service.service_id) and ( message["instance_id"] == found_service.instance_id or message["instance_id"] == 0xFFFF ) and ( message["major_version"] == found_service.major_version or message["major_version"] == 0xFF ) and ( message["minor_version"] == found_service.minor_version or message["minor_version"] == 0xFFFFFFFF ) ): service_found = True response = create_uds_message( FindServiceResponse, success=True, service_id=found_service.service_id, instance_id=found_service.instance_id, major_version=found_service.major_version, minor_version=found_service.minor_version, endpoint_ip=str(found_service.endpoint.ip), endpoint_port=found_service.endpoint.port, ) tx_queue = self._tx_queues.get(writer_id) if tx_queue: tx_queue.put_nowait(self.prepare_message(response)) break if not service_found: response = create_uds_message( FindServiceResponse, success=False, service_id=message["service_id"], instance_id=message["instance_id"], major_version=message["major_version"], minor_version=message["minor_version"], endpoint_ip="empty", endpoint_port=0, ) tx_queue = self._tx_queues.get(writer_id) if tx_queue: tx_queue.put_nowait(self.prepare_message(response)) def _handle_send_event_request(self, message: SendEventRequest, writer_id: int): for sub in self._service_subscribers.values(): sub.update() deserialized_event = Event.from_json(message["event"]) payload_decoded = base64.b64decode(message["payload"]) for offered_service in self._service_subscribers.keys(): if ( offered_service.service_id == message["service_id"] and offered_service.instance_id == message["instance_id"] and message["eventgroup_id"] in offered_service.eventgroup_ids ): if self._service_subscribers[offered_service].has_subscribers: for subscriber in self._service_subscribers[ offered_service ].subscribers: self.logger.debug( f"Sending event to subscriber {subscriber.endpoint[0]}:{subscriber.endpoint[1]}" ) if deserialized_event.protocol == TransportLayerProtocol.UDP: endpoint = ( self._someip_server_endpoints.get_endpoint_by_ip_port( message["src_endpoint_ip"], message["src_endpoint_port"], TransportLayerProtocol.UDP, ) ) if endpoint: someip_header = SomeIpHeader( service_id=offered_service.service_id, method_id=deserialized_event.id, length=len(payload_decoded) + 8, client_id=message["client_id"], session_id=message["session_id"], protocol_version=1, interface_version=offered_service.major_version, message_type=MessageType.NOTIFICATION.value, return_code=0x00, ) someip_message = SomeIpMessage( someip_header, payload_decoded ) endpoint.sendto( someip_message.serialize(), subscriber.endpoint ) elif deserialized_event.protocol == TransportLayerProtocol.TCP: endpoint: TCPSomeipEndpoint = ( self._someip_server_endpoints.get_endpoint_by_ip_port( message["src_endpoint_ip"], message["src_endpoint_port"], TransportLayerProtocol.TCP, ) ) if endpoint: someip_header = SomeIpHeader( service_id=offered_service.service_id, method_id=deserialized_event.id, length=len(payload_decoded) + 8, client_id=message["client_id"], session_id=message["session_id"], protocol_version=1, interface_version=offered_service.major_version, message_type=MessageType.NOTIFICATION.value, return_code=0x00, ) someip_message = SomeIpMessage( someip_header, payload_decoded ) endpoint.sendto( someip_message.serialize(), subscriber.endpoint ) # Handle internal subscriptions (UDS clients) for requested_subscription in self._requested_subscriptions.subscriptions: if ( requested_subscription.service_id == message["service_id"] and requested_subscription.instance_id == message["instance_id"] and requested_subscription.eventgroup.id == message["eventgroup_id"] and requested_subscription.major_version == message["major_version"] ): self.logger.debug( f"Internal subscription for service {message['service_id']:04x}, " f"instance {message['instance_id']:04x}, eventgroup {message['eventgroup_id']:04x}" ) event_msg = create_uds_message( ReceivedEvent, service_id=message["service_id"], event_id=deserialized_event.id, src_endpoint_ip=message["src_endpoint_ip"], src_endpoint_port=message["src_endpoint_port"], payload=message["payload"], ) writer_ids = self._requested_subscriptions.get_client_ids( requested_subscription ) for writer_id in writer_ids: tx_queue = self._tx_queues.get(writer_id) if tx_queue: tx_queue.put_nowait(self.prepare_message(event_msg)) def offer_timer_callback(self, cyclic_offer_delay_ms: int): self.logger.debug(f"Offer timer callback for {cyclic_offer_delay_ms}ms") services_to_offer: List[ServiceToOffer] = ( self._services_to_offer.services_by_cyclic_offer_delay( cyclic_offer_delay_ms ) ) for service in services_to_offer: service.last_offer_time = time.time() if len(services_to_offer) > 0: ( session_id, reboot_flag, ) = self._mcast_session_handler.update_session() sd_message = create_offer_service_message( services_to_offer=services_to_offer, session_id=session_id, reboot_flag=reboot_flag, ) if self._ucast_transport: self._ucast_transport.sendto( serialize_sd_message(sd_message), (self.sd_address, self.sd_port) ) def prepare_message(self, message: dict): payload = json.dumps(message).encode("utf-8") return struct.pack(" dict: messages_to_keep = [] found_message = None message_found = False while not message_found: try: msg = await asyncio.wait_for(rx_queue.get(), timeout=timeout) if msg.get("type") == msg_type: found_message = msg message_found = True else: messages_to_keep.append(msg) except asyncio.TimeoutError: # Put all non-target messages back in the queue for msg in messages_to_keep: await rx_queue.put(msg) return None # Put all non-target messages back in the queue for msg in messages_to_keep: await rx_queue.put(msg) return found_message def _handle_offered_service(self, offered_service: ServiceInstance): self.logger.info(f"Received offered service: {offered_service}") if offered_service not in self._found_services: self._found_services.append(offered_service) else: # Update the timestamp if the service is already in the list index = self._found_services.index(offered_service) self._found_services[index].timestamp = offered_service.timestamp # Check if there is a requested subscription for this service for ( requested_subscription, client_id, ) in self._requested_subscriptions.has_subscriptions( offered_service.service_id, offered_service.instance_id, offered_service.major_version, ): requested_protocols: Set[TransportLayerProtocol] = ( offered_service.protocols & requested_subscription.protocols ) if TransportLayerProtocol.TCP in requested_protocols: if not self._someip_client_endpoints.has_tcp_endpoint( str(requested_subscription.client_endpoint.ip), requested_subscription.client_endpoint.port, str(offered_service.endpoint.ip), offered_service.endpoint.port, ): self.logger.debug( f"Creating new TCP endpoint for {requested_subscription.client_endpoint}" ) tcp_endpoint = self._endpoint_factory.create_tcp_client_endpoint( offered_service.endpoint, requested_subscription.client_endpoint, self._someip_message_callback, self.logger, ) self._someip_client_endpoints.add_endpoint(client_id, tcp_endpoint) # TODO: This shall not block the handle_client function. A new task shall be created # For TCP wait for the connection to be established # while not tcp_endpoint.is_connected(): # await asyncio.sleep(0.2) ( session_id, reboot_flag, ) = self._unicast_session_handler.update_session() # Build subscribe message sd_message = SdMessage() sd_message.session_id = session_id sd_message.reboot_flag = reboot_flag options = [] for protocol in requested_protocols: options.append( IpV4EndpointOption( address=requested_subscription.client_endpoint.ip, protocol=protocol, port=requested_subscription.client_endpoint.port, ) ) entry = SubscribeEventGroupEntry( service_id=offered_service.service_id, instance_id=offered_service.instance_id, major_version=offered_service.major_version, ttl=requested_subscription.ttl_seconds, eventgroup_id=requested_subscription.eventgroup.id, counter=0, ip_v4_endpoints=options, ip_v6_endpoints=[], ) sd_message.entries.append(entry) client_endpoint = requested_subscription.client_endpoint server_endpoint = offered_service.endpoint pending_subscription = Subscription( service_id=offered_service.service_id, instance_id=offered_service.instance_id, major_version=offered_service.major_version, eventgroup=requested_subscription.eventgroup, ttl_seconds=requested_subscription.ttl_seconds, client_endpoint=client_endpoint, server_endpoint=server_endpoint, protocols=frozenset(requested_protocols), timestamp_last_update=time.time(), ) self._pending_subscriptions.add(pending_subscription) if self._ucast_transport: self._ucast_transport.sendto( serialize_sd_message(sd_message), (str(offered_service.endpoint.ip), self.sd_port), ) def _handle_subscription( self, sd_subscription: SdSubscription, ): # TODO: Send back a nack message if no service is found self.logger.info(f"Received subscription: {sd_subscription}") for sub in self._service_subscribers.values(): sub.update() # From SD specification: # [PRS_SOMEIPSD_00829] When receiving a SubscribeEventgroupAck or Sub- # scribeEventgroupNack the Service ID, Instance ID, Eventgroup ID, and Major Ver- # sion shall match exactly to the corresponding SubscribeEventgroup Entry to identify # an Eventgroup of a Service Instance. # Check if the service id, the instance and the major version is in the list of offered services # If yes, check if the eventgroup id is in the list of eventgroup ids # If yes, subscribe to the eventgroup for offered_service in self._services_to_offer.get_all_services(): # [PRS_SOMEIPSD_00828] When receiving a SubscribeEventgroup or StopSubscribeEventgroup the Service ID, # Instance ID, Eventgroup ID, and Major Version shall # match exactly to the configured values to identify an Eventgroup of a Service Instance. if ( offered_service.service_id == sd_subscription.service_id and offered_service.instance_id == sd_subscription.instance_id and sd_subscription.eventgroup_id in offered_service.eventgroup_ids and offered_service.major_version == sd_subscription.major_version ): self.logger.info( f"Subscription to eventgroup 0x{sd_subscription.eventgroup_id:04X} of service 0x{offered_service.service_id:04X}, instance 0x{offered_service.instance_id:04X} requested." ) ( session_id, reboot_flag, ) = self._unicast_session_handler.update_session() ack_entry = build_subscribe_eventgroup_ack_entry( service_id=offered_service.service_id, instance_id=offered_service.instance_id, major_version=offered_service.major_version, ttl=sd_subscription.ttl, event_group_id=sd_subscription.eventgroup_id, ) header_output = build_subscribe_eventgroup_ack_sd_header( entry=ack_entry, session_id=session_id, reboot_flag=reboot_flag, ) self.logger.info( f"Sending subscribe ack for eventgroup 0x{sd_subscription.eventgroup_id:04X} of service 0x{offered_service.service_id:04X} instance 0x{offered_service.instance_id:04X} to {sd_subscription.ipv4_address}:{sd_subscription.port}" ) new_subscriber = EventGroupSubscriber( sd_subscription.eventgroup_id, (sd_subscription.ipv4_address, sd_subscription.port), sd_subscription.ttl, ) if offered_service not in self._service_subscribers: self._service_subscribers[offered_service] = Subscribers() self._service_subscribers[offered_service].add_subscriber( new_subscriber ) if self._ucast_transport: self._ucast_transport.sendto( data=header_output.to_buffer(), addr=( str(sd_subscription.ipv4_address), self.sd_port, ), ) def _handle_sd_subscribe_ack_eventgroup_entry( self, event_group_entry: SdEventGroupEntry ): self.logger.info( f"Received subscribe ack eventgroup entry: {event_group_entry}" ) pending_subscription = None for pending_subscription_tmp in self._pending_subscriptions: self.logger.debug( f"Checking pending subscription: {pending_subscription_tmp} with values \ service_id={pending_subscription_tmp.service_id}, \ instance_id={pending_subscription_tmp.instance_id}, \ major_version={pending_subscription_tmp.major_version}, \ eventgroup_id={pending_subscription_tmp.eventgroup.id}" ) self.logger.debug( f"Event group entry values: \ service_id={event_group_entry.sd_entry.service_id}, \ instance_id={event_group_entry.sd_entry.instance_id}, \ major_version={event_group_entry.sd_entry.major_version}, \ eventgroup_id={event_group_entry.eventgroup_id}" ) if ( pending_subscription_tmp.service_id == event_group_entry.sd_entry.service_id and pending_subscription_tmp.instance_id == event_group_entry.sd_entry.instance_id and pending_subscription_tmp.major_version == event_group_entry.sd_entry.major_version and pending_subscription_tmp.eventgroup.id == event_group_entry.eventgroup_id ): self.logger.debug( f"Found matching pending subscription: {pending_subscription_tmp}" ) pending_subscription = pending_subscription_tmp break if pending_subscription is not None: pending_subscription.timestamp_last_update = time.time() self._active_subscriptions.discard(pending_subscription) self._active_subscriptions.add(pending_subscription) self.logger.info(f"Subscription acknowledged: {pending_subscription}") self._pending_subscriptions.discard(pending_subscription) def _handle_sd_subscribe_nack_eventgroup_entry( self, event_group_entry: SdEventGroupEntry ): self.logger.info( f"Received subscribe nack eventgroup entry: {event_group_entry}" ) def datagram_received_mcast( self, data: bytes, addr: Tuple[Union[str, Any], int] ) -> None: # Ignore messages from the same interface and port if addr[0] == self.interface and addr[1] == self.sd_port: return if not is_sd_message(data): return sd_message = deserialize_sd_message(data, addr[0], addr[1], multicast=True) sd_message.timestamp = time.time() for offer_service_entry in [ o for o in sd_message.entries if o.type == someipy._internal._sd.entries.sd_entry.SdEntryType.OFFER_SERVICE ]: entry: OfferServiceEntry = offer_service_entry protocols = set() for ep in entry.ip_v4_endpoints: protocols.add(ep.protocol) for ep in entry.ip_v6_endpoints: protocols.add(ep.protocol) endpoint = Endpoint( ip=entry.ip_v4_endpoints[0].address, port=entry.ip_v4_endpoints[0].port, ) service_instance = ServiceInstance( service_id=entry.service_id, instance_id=entry.instance_id, major_version=entry.major_version, minor_version=entry.minor_version, ttl=entry.ttl, endpoint=endpoint, protocols=frozenset(protocols), timestamp=sd_message.timestamp, ) self._handle_offered_service(service_instance) someip_sd_header = SomeIpSdHeader.from_buffer(data) for subscription in extract_subscribe_entries(someip_sd_header): self._handle_subscription(subscription) for event_group_entry in extract_subscribe_ack_eventgroup_entries( someip_sd_header ): self._handle_sd_subscribe_ack_eventgroup_entry(event_group_entry) def connection_lost_mcast(self, exc: Exception) -> None: pass def datagram_received_ucast( self, data: bytes, addr: Tuple[Union[str, Any], int] ) -> None: self.logger.debug(f"Received SD message from {addr}: {data}") # Ignore messages from the same interface and port if addr[0] == self.interface and addr[1] == self.sd_port: return someip_header = SomeIpHeader.from_buffer(data) if not someip_header.is_sd_header(): return someip_sd_header = SomeIpSdHeader.from_buffer(data) for subscription in extract_subscribe_entries(someip_sd_header): self._handle_subscription(subscription) for event_group_entry in extract_subscribe_ack_eventgroup_entries( someip_sd_header ): self._handle_sd_subscribe_ack_eventgroup_entry(event_group_entry) for event_group_entry in extract_subscribe_nack_eventgroup_entries( someip_sd_header ): self._handle_sd_subscribe_nack_eventgroup_entry(event_group_entry) def connection_lost_ucast(self, exc: Exception) -> None: pass async def start_sd_listening(self): if self.sd_address.startswith("224"): self._sd_socket_mcast = create_rcv_multicast_socket( self.sd_address, self.sd_port, self.interface ) else: self._sd_socket_mcast = create_rcv_broadcast_socket( self.sd_address, self.sd_port, self.interface ) loop = asyncio.get_running_loop() self._mcast_transport, _ = await loop.create_datagram_endpoint( lambda: DatagramAdapter( target=None, datagram_received_callback=self.datagram_received_mcast, connection_lost_callback=self.connection_lost_mcast, ), sock=self._sd_socket_mcast, ) self._sd_socket_ucast = create_udp_socket(self.interface, self.sd_port) self._ucast_transport, _ = await loop.create_datagram_endpoint( lambda: DatagramAdapter( target=None, datagram_received_callback=self.datagram_received_ucast, connection_lost_callback=self.connection_lost_ucast, ), sock=self._sd_socket_ucast, ) def _configure_logging(log_level=logging.DEBUG, log_path=None) -> logging.Logger: logger = logging.getLogger(f"someipyd") logger.setLevel(log_level) # Remove any existing handlers to prevent duplicate logs if logger.hasHandlers(): logger.handlers.clear() formatter = logging.Formatter( "%(asctime)s.%(msecs)03d %(name)s [%(levelname)s]: %(message)s", datefmt="%Y-%m-%d,%H:%M:%S", ) if log_path: file_handler = logging.FileHandler(log_path) file_handler.setLevel(log_level) file_handler.setFormatter(formatter) logger.addHandler(file_handler) else: console_handler = logging.StreamHandler(sys.stdout) console_handler.setLevel(log_level) console_handler.setFormatter(formatter) logger.addHandler(console_handler) return logger def _load_config(config_file: str) -> dict: if config_file and os.path.exists(config_file): try: with open(config_file, "r") as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError) as e: print(f"Error loading config file: {e}. Using defaults.") return {} elif os.path.exists(DEFAULT_CONFIG_FILE): try: with open(DEFAULT_CONFIG_FILE, "r") as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError) as e: print(f"Error loading config file: {e}. Using defaults.") return {} else: return {} async def async_main(): parser = argparse.ArgumentParser(description="SOME/IP Daemon") parser.add_argument("--config", help="Path to configuration file") parser.add_argument("--log-path", help="Path to log file") args = parser.parse_args() # Load configuration config = _load_config(args.config) # Logging log_path = args.log_path if args.log_path else config.get("log_path", None) log_level = config.get("log_level", "INFO") log_level_mapping = { "DEBUG": logging.DEBUG, "ERROR": logging.ERROR, "INFO": logging.INFO, "FATAL": logging.FATAL, } if log_level in log_level_mapping: log_level = log_level_mapping[log_level] logger = _configure_logging(log_level=log_level, log_path=log_path) logger.info( f"Starting SOME/IP daemon with config:\n" f"Socket path: {config.get('socket_path', DEFAULT_SOCKET_PATH)}\n" f"SD address: {config.get('sd_address', DEFAULT_SD_ADDRESS)}\n" f"SD port: {config.get('sd_port', DEFAULT_SD_PORT)}\n" f"Interface: {config.get('interface', DEFAULT_INTERFACE_IP)}\n" f"Loglevel: {log_level}\n" f"Log path: {log_path if log_path else 'Console'}\n" f"Use tcp: {config.get('use_tcp', False)}\n" f"Tcp port: {config.get('tcp_port', None)}\n" f"Tcp host: {config.get('tcp_host', '127.0.0.1')}\n" ) daemon_server = DaemonServer(logger) daemon = SomeipDaemon(daemon_server, SomeipEndpointFactory(), config, logger) daemon_server.client_connected += daemon.new_client_connected daemon_server.client_disconnected += daemon.client_disconnected await daemon_server.start( use_tcp=config.get("use_tcp", False), socket_path=config.get("socket_path", DEFAULT_SOCKET_PATH), tcp_port=config.get("tcp_port", 30500), host=config.get("tcp_host", "127.0.0.1"), ) await daemon.start_server() def main(): try: asyncio.run(async_main()) except KeyboardInterrupt: pass if __name__ == "__main__": main() someipy-2.1.2/tests/000077500000000000000000000000001513043235100143405ustar00rootroot00000000000000someipy-2.1.2/tests/__init__.py000066400000000000000000000000001513043235100164370ustar00rootroot00000000000000someipy-2.1.2/tests/common/000077500000000000000000000000001513043235100156305ustar00rootroot00000000000000someipy-2.1.2/tests/common/__init__.py000066400000000000000000000000001513043235100177270ustar00rootroot00000000000000someipy-2.1.2/tests/common/test_endpoint.py000066400000000000000000000014421513043235100210620ustar00rootroot00000000000000import ipaddress from someipy._internal._common.endpoint import Endpoint def test_equality(): endpoint_1 = Endpoint(ipaddress.ip_address("192.168.0.1"), 3000) endpoint_2 = Endpoint(ipaddress.ip_address("192.168.0.1"), 3000) assert endpoint_1 == endpoint_2 def test_inequality(): endpoint_1 = Endpoint(ipaddress.ip_address("192.168.0.1"), 3000) endpoint_2 = Endpoint(ipaddress.ip_address("192.168.0.2"), 3000) assert endpoint_1 != endpoint_2 def test_endpoint_is_ipv4(): endpoint_ipv4 = Endpoint(ipaddress.ip_address("192.168.0.1"), 3000) assert endpoint_ipv4.is_ipv4 == True def test_endpoint_is_ipv6(): endpoint_ipv6 = Endpoint( ipaddress.ip_address("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), 3000 ) assert endpoint_ipv6.is_ipv4 == False someipy-2.1.2/tests/daemon/000077500000000000000000000000001513043235100156035ustar00rootroot00000000000000someipy-2.1.2/tests/daemon/__init__.py000066400000000000000000000000001513043235100177020ustar00rootroot00000000000000someipy-2.1.2/tests/daemon/test_someipyd.py000066400000000000000000000375311513043235100210560ustar00rootroot00000000000000from asyncio import DatagramTransport import asyncio import ipaddress import logging import time import pytest import pytest_asyncio from unittest.mock import MagicMock, Mock, patch import someipy from someipy._internal._common.endpoint import Endpoint from someipy._internal._daemon.daemon_server import ClientConnectedEventArgs from someipy._internal._daemon.daemon_server_client import DaemonServerClient from someipy._internal._daemon.subscription import Subscription from someipy._internal._daemon.uds_messages import ( OfferServiceRequest, StopOfferServiceRequest, StopSubscribeEventGroupRequest, SubscribeEventGroupRequest, create_uds_message, ) from someipy._internal._sd.deserialization.sd_serialization import serialize_sd_message from someipy._internal._sd.entries.offer_service_entry import OfferServiceEntry from someipy._internal._sd.options.endpoint import IpV4EndpointOption from someipy._internal._sd.service_instance import ServiceInstance from someipy._internal.someip_endpoint_factory import SomeipEndpointFactory from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy.service import Event, EventGroup, Method from someipy.someipyd import DaemonServer, SomeipDaemon @pytest.fixture def mock_logger() -> logging.Logger: mock_logger = Mock(spec=logging.Logger) return mock_logger @pytest.fixture def mock_daemon_server(mock_logger) -> DaemonServer: return DaemonServer(mock_logger) @pytest.fixture def mock_endpoint_factory() -> Mock: return Mock(spec=SomeipEndpointFactory) @pytest.fixture def daemon(mock_daemon_server, mock_endpoint_factory, mock_logger) -> SomeipDaemon: config = {} daemon = SomeipDaemon( mock_daemon_server, mock_endpoint_factory, config, mock_logger ) daemon._ucast_transport = Mock(spec=DatagramTransport) return daemon @pytest.fixture def service_instance() -> ServiceInstance: service_instance = ServiceInstance( service_id=1, instance_id=2, major_version=3, minor_version=0, ttl=10, endpoint=Endpoint(ipaddress.IPv4Address("192.168.1.1"), 1), protocols=frozenset([TransportLayerProtocol.UDP]), timestamp=1000, ) return service_instance @pytest.fixture def eventgroup() -> EventGroup: return EventGroup( id=1, events=[ Event(id=1, protocol=TransportLayerProtocol.UDP), Event(id=2, protocol=TransportLayerProtocol.TCP), ], ) @pytest.fixture def method() -> Method: return Method( id=1, protocol=TransportLayerProtocol.UDP, ) @pytest.fixture def subscribe_event_group_request_udp(eventgroup) -> SubscribeEventGroupRequest: return SubscribeEventGroupRequest( service_id=1, instance_id=2, major_version=3, ttl_subscription=10, eventgroup=eventgroup.to_json(), client_endpoint_ip="192.168.1.1", client_endpoint_port=1, udp=True, tcp=False, ) @pytest.fixture def subscribe_event_group_request_tcp(eventgroup) -> SubscribeEventGroupRequest: return SubscribeEventGroupRequest( service_id=1, instance_id=2, major_version=3, ttl_subscription=10, eventgroup=eventgroup.to_json(), client_endpoint_ip="192.168.1.1", client_endpoint_port=1, udp=False, tcp=True, ) @pytest.fixture def subscribe_event_group_request_udp_and_tcp(eventgroup) -> SubscribeEventGroupRequest: return create_uds_message( SubscribeEventGroupRequest, service_id=1, instance_id=2, major_version=3, ttl_subscription=10, eventgroup=eventgroup.to_json(), client_endpoint_ip="123", client_endpoint_port=1, udp=True, tcp=True, ) @pytest.fixture def stop_subscribe_eventgroup_request( eventgroup: EventGroup, ) -> StopSubscribeEventGroupRequest: return create_uds_message( StopSubscribeEventGroupRequest, service_id=1, instance_id=2, major_version=3, eventgroup=eventgroup.to_json(), client_endpoint_ip="192.168.1.1", client_endpoint_port=1, udp=eventgroup.has_udp, tcp=eventgroup.has_tcp, ) @pytest.fixture def offer_service_request(eventgroup, method) -> OfferServiceRequest: return create_uds_message( OfferServiceRequest, service_id=1, instance_id=2, major_version=3, minor_version=0, endpoint_ip="127.0.0.1", endpoint_port=1, ttl=5, eventgroup_list=[eventgroup.to_json()], method_list=[method.to_json()], cyclic_offer_delay_ms=1000, ) @pytest.fixture def stop_offer_service_request(eventgroup, method) -> StopOfferServiceRequest: return create_uds_message( StopOfferServiceRequest, service_id=1, instance_id=2, major_version=3, minor_version=0, endpoint_ip="127.0.0.1", endpoint_port=1, ttl=5, eventgroup_list=[eventgroup.to_json()], method_list=[method.to_json()], cyclic_offer_delay_ms=1000, ) def test_handle_offered_service_adds_service( daemon: SomeipDaemon, service_instance: ServiceInstance ): # Initially, the found services list should be empty assert len(daemon._found_services) == 0 # Handle the offered service daemon._handle_offered_service(service_instance) # Now, the found services list should contain the new service assert len(daemon._found_services) == 1 assert daemon._found_services[0] == service_instance def test_handle_offered_service_updates_timestamp( daemon: SomeipDaemon, service_instance: ServiceInstance ): # Initially, the found services list should be empty assert len(daemon._found_services) == 0 # Handle the offered service daemon._handle_offered_service(service_instance) service_instance_2 = ServiceInstance( service_id=service_instance.service_id, instance_id=service_instance.instance_id, major_version=service_instance.major_version, minor_version=service_instance.minor_version, ttl=service_instance.ttl, endpoint=service_instance.endpoint, protocols=service_instance.protocols, timestamp=2000, ) # Handle the offered service again with updated timestamp daemon._handle_offered_service(service_instance_2) # Now, the found services list should contain the updated timestamp assert len(daemon._found_services) == 1 assert daemon._found_services[0] == service_instance assert daemon._found_services[0].timestamp == 2000 @pytest.mark.asyncio async def test_handle_offered_service_opens_tcp_client_endpoint( daemon: SomeipDaemon, mock_endpoint_factory: Mock, service_instance: ServiceInstance, subscribe_event_group_request_tcp: SubscribeEventGroupRequest, ): service_instance.protocols = frozenset([TransportLayerProtocol.TCP]) # Add a subscription first await daemon._handle_subscribe_eventgroup_request( subscribe_event_group_request_tcp, 1 ) # Handle the offered service daemon._handle_offered_service(service_instance) # Verify that create_client_endpoint was called for TCP mock_endpoint_factory.create_tcp_client_endpoint.assert_called_once_with( service_instance.endpoint, service_instance.endpoint, daemon._someip_message_callback, daemon.logger, ) assert len(daemon._pending_subscriptions) == 1 assert len(daemon._someip_client_endpoints) == 1 daemon._ucast_transport.sendto.assert_called_once() @pytest.mark.asyncio async def test_handle_subscribe_eventgroup_request_adds_requested_subscription( daemon: SomeipDaemon, subscribe_event_group_request_udp: SubscribeEventGroupRequest, ): # Initially, the requested subscriptions list should be empty assert len(daemon._requested_subscriptions) == 0 # Handle the subscribe event group request await daemon._handle_subscribe_eventgroup_request( subscribe_event_group_request_udp, 1 ) # Now, the requested subscriptions list should contain the new subscription assert len(daemon._requested_subscriptions) == 1 @pytest.mark.asyncio async def test_handle_offer_service_request_opens_server_endpoint( daemon: SomeipDaemon, offer_service_request: OfferServiceRequest, ): assert len(daemon._someip_server_endpoints) == 0 await daemon._handle_offer_service_request(offer_service_request, 1) assert len(daemon._someip_server_endpoints) == 1 @pytest.mark.asyncio async def test_handle_offer_service_does_not_add_service_twice( daemon: SomeipDaemon, offer_service_request: OfferServiceRequest, ): assert len(daemon._services_to_offer) == 0 await daemon._handle_offer_service_request(offer_service_request, 1) await daemon._handle_offer_service_request(offer_service_request, 1) assert len(daemon._services_to_offer) == 1 @pytest.mark.asyncio async def test_handle_stop_offer_service_removes_service_to_offer( daemon: SomeipDaemon, offer_service_request: OfferServiceRequest, stop_offer_service_request: StopOfferServiceRequest, ): assert len(daemon._services_to_offer) == 0 await daemon._handle_offer_service_request(offer_service_request, 1) assert len(daemon._services_to_offer) == 1 daemon._handle_stop_offer_service_request(stop_offer_service_request, 1) assert len(daemon._services_to_offer) == 0 @pytest.mark.asyncio async def test_client_connected_disconnected( daemon: SomeipDaemon, ): initial_queue_count = len(daemon._tx_queues) # Simulate a new client connection client_id = 42 new_client = Mock(spec=DaemonServerClient) new_client.id = client_id new_client.message_received = someipy._internal._common.event.Event() new_client.message_received.add_handler = Mock() new_client.message_received.remove_handler = Mock() new_client_args = ClientConnectedEventArgs(new_client) await daemon.new_client_connected(new_client, new_client_args) # Verify that a new queue has been created for the client assert client_id in daemon._tx_queues.keys() assert daemon._tx_queues[client_id] is not None new_client.message_received.add_handler.assert_called_once() await asyncio.sleep(0.0) # Allow tx task to be scheduled await daemon.client_disconnected(daemon, new_client_args) # Verify that the client's queue and tx task was removed assert client_id not in daemon._tx_queues.keys() assert client_id not in daemon._tx_tasks.keys() # Message received event handler was removed new_client.message_received.remove_handler.assert_called_once() """ Cleanup of: - Offer timers - Services to be offered - Subscriptions (pending) - Subscriptions (active) - Method calls pending - Pending find calls - Close server or client endpoints that are only used by the disconnected client """ def test_datagram_received_mcast_calls_handle_offered_service( daemon: SomeipDaemon, ): # Create an SdMessage with an OfferService entry sd_message = someipy._internal._sd.sd_message.SdMessage() sd_message.session_id = 1 ip_endpoint_option_1 = IpV4EndpointOption( address=ipaddress.IPv4Address("192.168.1.1"), protocol=TransportLayerProtocol.TCP, port=8080, ) ip_endpoint_option_2 = IpV4EndpointOption( address=ipaddress.IPv4Address("192.168.1.2"), protocol=TransportLayerProtocol.UDP, port=8080, ) offer_service_entry = OfferServiceEntry( service_id=1, instance_id=1, major_version=1, minor_version=0, ttl=120, ip_v4_endpoints=[ip_endpoint_option_1], ip_v6_endpoints=[], ) sd_message.entries.append(offer_service_entry) data = serialize_sd_message(sd_message) # Patch the _handle_offered_service method to monitor its calls with patch.object( daemon, "_handle_offered_service", wraps=daemon._handle_offered_service ) as mock_handle_offered_service: # Simulate receiving a multicast datagram daemon.datagram_received_mcast(data, ("127.0.0.1", 5000)) mock_handle_offered_service.assert_called_once() def test_check_services_ttl_task_removes_expired_offered_services( daemon: SomeipDaemon, service_instance: ServiceInstance ): service_instance.timestamp = time.time() service_instance.ttl = 10 # seconds # Add a service instance with a short TTL daemon._found_services.append(service_instance) # Run the TTL check task once daemon._check_service_ttl_task_impl() # Service is still valid assert len(daemon._found_services) == 1 service_instance.timestamp -= service_instance.ttl + 1 # Simulate time passage daemon._check_service_ttl_task_impl() # Service should be removed due to TTL expiry assert len(daemon._found_services) == 0 def test_find_service_request_sends_negative_response(daemon: SomeipDaemon): pass def test_find_service_request_sends_positive_response(daemon: SomeipDaemon): pass def test_stop_subscribe_eventgroup_request_removes_requested_subscriptions( daemon: SomeipDaemon, eventgroup: EventGroup, stop_subscribe_eventgroup_request: StopSubscribeEventGroupRequest, ): protocols = [ protocol for flag, protocol in ( (stop_subscribe_eventgroup_request["udp"], TransportLayerProtocol.UDP), (stop_subscribe_eventgroup_request["tcp"], TransportLayerProtocol.TCP), ) if flag ] new_subscription = Subscription( service_id=stop_subscribe_eventgroup_request["service_id"], instance_id=stop_subscribe_eventgroup_request["instance_id"], major_version=stop_subscribe_eventgroup_request["major_version"], eventgroup=eventgroup, ttl_seconds=10, client_endpoint=Endpoint( ipaddress.IPv4Address( stop_subscribe_eventgroup_request["client_endpoint_ip"] ), stop_subscribe_eventgroup_request["client_endpoint_port"], ), server_endpoint=None, protocols=frozenset(protocols), ) daemon._requested_subscriptions.add_subscription( 1, new_subscription, ) assert len(daemon._requested_subscriptions) == 1 daemon._handle_stop_subscribe_eventgroup_request( stop_subscribe_eventgroup_request, 1 ) assert len(daemon._requested_subscriptions) == 0 def test_stop_subscribe_eventgroup_request_removes_pending_and_active_subscriptions( daemon: SomeipDaemon, eventgroup: EventGroup, stop_subscribe_eventgroup_request: StopSubscribeEventGroupRequest, ): protocols = [ protocol for flag, protocol in ( (stop_subscribe_eventgroup_request["udp"], TransportLayerProtocol.UDP), (stop_subscribe_eventgroup_request["tcp"], TransportLayerProtocol.TCP), ) if flag ] endpoint = Endpoint( ipaddress.IPv4Address(stop_subscribe_eventgroup_request["client_endpoint_ip"]), stop_subscribe_eventgroup_request["client_endpoint_port"], ) new_subscription = Subscription( service_id=stop_subscribe_eventgroup_request["service_id"], instance_id=stop_subscribe_eventgroup_request["instance_id"], major_version=stop_subscribe_eventgroup_request["major_version"], eventgroup=eventgroup, ttl_seconds=10, client_endpoint=endpoint, server_endpoint=endpoint, protocols=frozenset(protocols), ) daemon._pending_subscriptions.add(new_subscription) daemon._active_subscriptions.add(new_subscription) assert len(daemon._pending_subscriptions) == 1 assert len(daemon._active_subscriptions) == 1 daemon._handle_stop_subscribe_eventgroup_request( stop_subscribe_eventgroup_request, 1 ) assert len(daemon._pending_subscriptions) == 0 assert len(daemon._active_subscriptions) == 0 someipy-2.1.2/tests/daemon/test_subscription_storage.py000066400000000000000000000125361513043235100234730ustar00rootroot00000000000000import pytest from someipy._internal._daemon.subscription import Subscription from someipy._internal._daemon.subscription_storage import SubscriptionStorage from someipy._internal.transport_layer_protocol import TransportLayerProtocol from someipy.service import EventGroup @pytest.fixture def subscription_service_id_1() -> Subscription: return Subscription( service_id=1, instance_id=1, major_version=1, eventgroup=EventGroup(0, []), ttl_seconds=60, client_endpoint=None, server_endpoint=None, protocols=frozenset([TransportLayerProtocol.TCP]), timestamp_last_update=0, ) @pytest.fixture def subscription_service_id_2() -> Subscription: return Subscription( service_id=2, instance_id=1, major_version=1, eventgroup=EventGroup(0, []), ttl_seconds=60, client_endpoint=None, server_endpoint=None, protocols=frozenset([TransportLayerProtocol.TCP]), timestamp_last_update=0, ) def test_add_subscription_adds_subscription(subscription_service_id_1): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) assert subscription_service_id_1 in storage.subscriptions def test_add_subscription_adds_multiple_subscriptions_per_client( subscription_service_id_1, subscription_service_id_2 ): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) storage.add_subscription(100, subscription_service_id_2) assert subscription_service_id_1 in storage.subscriptions assert subscription_service_id_2 in storage.subscriptions assert storage.get_client_ids(subscription_service_id_1) == [100] assert storage.get_client_ids(subscription_service_id_2) == [100] def test_get_client_ids_returns_multiple_clients(subscription_service_id_1): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) storage.add_subscription(200, subscription_service_id_1) client_ids = storage.get_client_ids(subscription_service_id_1) assert 100 in client_ids assert 200 in client_ids def test_remove_subscription_removes_subscription(subscription_service_id_1): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) storage.remove_subscription(100, subscription_service_id_1) assert subscription_service_id_1 not in storage.subscriptions def test_remove_client_removes_all_subscriptions( subscription_service_id_1, subscription_service_id_2 ): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) storage.add_subscription(100, subscription_service_id_2) storage.remove_client(100) assert subscription_service_id_1 not in storage.subscriptions assert subscription_service_id_2 not in storage.subscriptions def test_has_subscriptions_returns_empty_list_when_no_subscriptions( subscription_service_id_1, subscription_service_id_2 ): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) result = storage.has_subscriptions( service_id=subscription_service_id_2.service_id, instance_id=subscription_service_id_1.instance_id, major_version=subscription_service_id_1.major_version, ) assert result == [] def test_has_subscriptions_returns_matching_subscriptions( subscription_service_id_1, subscription_service_id_2 ): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) storage.add_subscription(200, subscription_service_id_2) result = storage.has_subscriptions( service_id=subscription_service_id_1.service_id, instance_id=subscription_service_id_1.instance_id, major_version=subscription_service_id_1.major_version, ) assert len(result) == 1 subscription, client_id = result[0] assert subscription == subscription_service_id_1 assert client_id == 100 def test_has_subscriptions_returns_multiple_matching_subscriptions( subscription_service_id_1, subscription_service_id_2 ): storage = SubscriptionStorage() storage.add_subscription(100, subscription_service_id_1) storage.add_subscription(200, subscription_service_id_1) storage.add_subscription(300, subscription_service_id_2) result = storage.has_subscriptions( service_id=subscription_service_id_1.service_id, instance_id=subscription_service_id_1.instance_id, major_version=subscription_service_id_1.major_version, ) assert len(result) == 2 client_ids = [client_id for _, client_id in result] assert 100 in client_ids assert 200 in client_ids def test_len(subscription_service_id_1, subscription_service_id_2): storage = SubscriptionStorage() assert len(storage) == 0 storage.add_subscription(100, subscription_service_id_1) assert len(storage) == 1 storage.add_subscription(200, subscription_service_id_1) assert len(storage) == 2 storage.add_subscription(100, subscription_service_id_2) assert len(storage) == 3 storage.remove_subscription(100, subscription_service_id_1) assert len(storage) == 2 storage.remove_subscription(200, subscription_service_id_1) assert len(storage) == 1 storage.remove_subscription(100, subscription_service_id_2) assert len(storage) == 0 someipy-2.1.2/tests/sd/000077500000000000000000000000001513043235100147465ustar00rootroot00000000000000someipy-2.1.2/tests/sd/__init__.py000066400000000000000000000000001513043235100170450ustar00rootroot00000000000000someipy-2.1.2/tests/sd/test_offer_service_entry.py000066400000000000000000000023411513043235100224210ustar00rootroot00000000000000import pytest from someipy._internal._sd.entries.offer_service_entry import OfferServiceEntry from someipy._internal._sd.options.endpoint import IpV4EndpointOption def test_base_types_len(): ip_endpoint_option_1 = IpV4EndpointOption( address="192.168.1.1", protocol=1, port=8080 ) ip_endpoint_option_2 = IpV4EndpointOption( address="192.168.1.2", protocol=1, port=8080 ) offer_service_entry_1 = OfferServiceEntry( service_id=1, instance_id=1, major_version=1, minor_version=0, ttl=120, ip_v4_endpoints=[ip_endpoint_option_1], ip_v6_endpoints=[], ) offer_service_entry_2 = OfferServiceEntry( service_id=1, instance_id=1, major_version=1, minor_version=0, ttl=120, ip_v4_endpoints=[ip_endpoint_option_1], ip_v6_endpoints=[], ) offer_service_entry_3 = OfferServiceEntry( service_id=1, instance_id=1, major_version=1, minor_version=0, ttl=120, ip_v4_endpoints=[ip_endpoint_option_2], ip_v6_endpoints=[], ) assert offer_service_entry_1 == offer_service_entry_2 assert offer_service_entry_1 != offer_service_entry_3 someipy-2.1.2/tests/sd/test_sd_deserialization.py000066400000000000000000000167051513043235100222440ustar00rootroot00000000000000import pytest from someipy._internal._sd.deserialization.sd_deserialization import ( CommonEntryData, CommonOptionData, SdOptionOnWireType, deserialize_common_entry_data, deserialize_common_option_data, deserialize_ipv4_endpoint_option, deserialize_ipv4_multicast_option, deserialize_ipv4_sd_endpoint_option, deserialize_ipv6_endpoint_option, deserialize_ipv6_multicast_option, deserialize_ipv6_sd_endpoint_option, deserialize_load_balancing_option, deserialize_sd_message, ) from someipy._internal._sd.entries.sd_entry import SdEntryType from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) from someipy._internal._sd.options.load_balancing import LoadBalancingOption from someipy._internal._sd.options.multicast import ( IpV4MulticastOption, IpV6MulticastOption, ) from someipy._internal._sd.options.sd_endpoint import ( IpV4SdEndpointOption, IpV6SdEndpointOption, ) from someipy._internal.transport_layer_protocol import TransportLayerProtocol def test_deserialize_common_entry_data(): data = bytes( [0x01, 0x02, 0x03, 0x24, 0x00, 0x10, 0x00, 0x20, 0x01, 0x0B, 0x00, 0x0A] ) result = deserialize_common_entry_data(data) assert isinstance(result, CommonEntryData) assert result.type_field_value == 0x01 assert result.index_first_option == 0x02 assert result.index_second_option == 0x03 assert result.num_options_1 == 2 assert result.num_options_2 == 4 assert result.service_id == 0x0010 assert result.instance_id == 0x0020 assert result.major_version == 0x01 assert result.ttl == 0x0B000A def test_deserialize_common_option_data(): data = bytes([0x01, 0x05, 0x04, 0x80]) result = deserialize_common_option_data(data) assert isinstance(result, CommonOptionData) assert result.option_length == 5 + 256 assert result.option_type == SdOptionOnWireType.IPV4_ENDPOINT assert result.discardable_flag is True def test_deserialize_ipv4_endpoint_option(): data = bytes([192, 168, 1, 10, 0x01, 0x11, 0x10, 0x01]) result = deserialize_ipv4_endpoint_option(data) assert isinstance(result, IpV4EndpointOption) assert str(result.address) == "192.168.1.10" assert result.protocol == TransportLayerProtocol.UDP assert result.port == 0x1001 def test_deserialize_ipv6_endpoint_option(): data = bytes( [ 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x34, 0x01, 0x11, 0x10, 0x01, ] ) result = deserialize_ipv6_endpoint_option(data) assert isinstance(result, IpV6EndpointOption) assert str(result.address) == "2001:db8:85a3::8a2e:370:7334" assert result.protocol == TransportLayerProtocol.UDP assert result.port == 0x1001 def test_deserialize_ipv4_multicast_option(): data = bytes([192, 168, 1, 10, 0x01, 0x11, 0x10, 0x01]) result = deserialize_ipv4_multicast_option(data) assert isinstance(result, IpV4MulticastOption) assert str(result.address) == "192.168.1.10" assert result.protocol == TransportLayerProtocol.UDP assert result.port == 0x1001 def test_deserialize_ipv6_multicast_option(): data = bytes( [ 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x34, 0x01, 0x11, 0x10, 0x01, ] ) result = deserialize_ipv6_multicast_option(data) assert isinstance(result, IpV6MulticastOption) assert str(result.address) == "2001:db8:85a3::8a2e:370:7334" assert result.protocol == TransportLayerProtocol.UDP assert result.port == 0x1001 def test_deserialize_ipv4_sd_endpoint_option(): data = bytes([192, 168, 1, 10, 0x01, 0x11, 0x10, 0x01]) result = deserialize_ipv4_sd_endpoint_option(data) assert isinstance(result, IpV4SdEndpointOption) assert str(result.address) == "192.168.1.10" assert result.port == 0x1001 def test_deserialize_ipv6_sd_endpoint_option(): data = bytes( [ 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x34, 0x01, 0x11, 0x10, 0x01, ] ) result = deserialize_ipv6_sd_endpoint_option(data) assert isinstance(result, IpV6SdEndpointOption) assert str(result.address) == "2001:db8:85a3::8a2e:370:7334" assert result.port == pow(16, 3) + 1 def test_deserialize_load_balancing_option(): data = bytes([0x01, 0x02, 0x03, 0x04]) result = deserialize_load_balancing_option(data) assert isinstance(result, LoadBalancingOption) assert result.priority == 0x0102 assert result.weight == 0x0304 @pytest.fixture def sd_message_no_entries_no_options() -> bytes: # fmt: off data = bytes([ 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 20, # length 0x00, 0x00, 0x00, 0x01, # client id, session id 0x01, 0x01, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, # flags 8 bit, reserved 24 bit 0x00, 0x00, 0x00, 0x00, # entries length 0x00, 0x00, 0x00, 0x00, # options length ]) # fmt: on return data @pytest.fixture def sd_message_no_with_stop_offer_service_entry() -> bytes: # fmt: off data = bytes([ 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 20, # length 0x00, 0x00, 0x00, 0x01, # client id, session id 0x01, 0x01, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, # flags 8 bit, reserved 24 bit 0x00, 0x00, 0x00, 16, # entries length 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, # service id, instance id 0x03, 0x00, 0x00, 0x00, # major version, ttl 0x00, 0x00, 0x00, 0x05, # minor version 0x00, 0x00, 0x00, 12, # options length 0x00, 0x09, 0x04, 0x00, # common option data 192, 168, 1, 10, # ipv4 address 0x00, 0x11, 0x10, 0x01 # reserved, proto, port ]) # fmt: on return data def test_deserialize_sd_message_reboot_flag(sd_message_no_entries_no_options): sd_message = deserialize_sd_message(sd_message_no_entries_no_options, "", 0, True) assert sd_message.reboot_flag == True def test_deserialize_sd_message_with_stop_offer_service_entry( sd_message_no_with_stop_offer_service_entry, ): sd_message = deserialize_sd_message( sd_message_no_with_stop_offer_service_entry, "", 0, True ) assert len(sd_message.entries) == 1 entry = sd_message.entries[0] assert entry.type == SdEntryType.STOP_OFFER_SERVICE assert entry.service_id == 0x0001 assert entry.instance_id == 0x0002 assert entry.major_version == 0x03 assert entry.minor_version == 0x05 assert len(entry.ip_v4_endpoints) == 1 endpoint = entry.ip_v4_endpoints[0] assert len(entry.ip_v6_endpoints) == 0 assert str(endpoint.address) == "192.168.1.10" assert endpoint.protocol == TransportLayerProtocol.UDP assert endpoint.port == 0x1001 someipy-2.1.2/tests/sd/test_sd_serialization.py000066400000000000000000000120731513043235100217250ustar00rootroot00000000000000import ipaddress from someipy._internal._sd.deserialization.sd_serialization import ( serialize_ipv4_endpoint_option, serialize_ipv6_endpoint_option, serialize_sd_message, ) from someipy._internal._sd.entries.offer_service_entry import OfferServiceEntry from someipy._internal._sd.options.endpoint import ( IpV4EndpointOption, IpV6EndpointOption, ) from someipy._internal._sd.sd_message import SdMessage from someipy._internal.transport_layer_protocol import TransportLayerProtocol def test_serialize_ipv4_endpoint_option(): option = IpV4EndpointOption( address=ipaddress.IPv4Address("1.2.3.4"), protocol=TransportLayerProtocol.UDP, port=0x1F90, ) data = serialize_ipv4_endpoint_option(option) expected_data = bytes( [0x00, 0x09, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x11, 0x1F, 0x90] ) assert data == expected_data def test_serialize_ipv6_endpoint_option(): option = IpV6EndpointOption( address=ipaddress.IPv6Address("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), protocol=TransportLayerProtocol.TCP, port=0x2328, ) data = serialize_ipv6_endpoint_option(option) expected_data = bytes( [ 0x00, 0x15, 0x06, 0x00, 0x20, 0x01, 0x0D, 0xB8, 0x85, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x34, 0x00, 0x06, 0x23, 0x28, ] ) assert data == expected_data def test_serialize_empty_sd_message(): sd_message = SdMessage() sd_message.multicast = False sd_message.session_id = 0x2 data = serialize_sd_message(sd_message) # fmt: off expected_data = bytes( [ 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x14, # length: 20 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # length entries 0x00, 0x00, 0x00, 0x00]) # length of options # fmt: on assert len(data) == len(expected_data) assert data == expected_data def test_serialize_sd_message_with_one_offer_service_entry_without_options(): sd_message = SdMessage() sd_message.multicast = True sd_message.session_id = 0x1234 sd_message.entries.append( OfferServiceEntry( service_id=0x01, instance_id=0x02, major_version=0x03, minor_version=0x04, ttl=0x10, ip_v4_endpoints=[], ip_v6_endpoints=[], ) ) data = serialize_sd_message(sd_message) # fmt: off expected_data = bytes( [ 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x24, # length: 36 0x00, 0x00, 0x12, 0x34, 0x01, 0x01, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, # length entries: 16 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00]) # length of options: 0 # fmt: on assert len(data) == len(expected_data) assert data == expected_data def test_serialize_sd_message_with_one_offer_service_entry_with_two_options(): sd_message = SdMessage() sd_message.multicast = True sd_message.session_id = 0x1234 sd_message.entries.append( OfferServiceEntry( service_id=0x01, instance_id=0x02, major_version=0x03, minor_version=0x04, ttl=0x10, ip_v4_endpoints=[ IpV4EndpointOption( address=ipaddress.IPv4Address("192.168.0.1"), protocol=TransportLayerProtocol.TCP, port=0x2328, ), IpV4EndpointOption( address=ipaddress.IPv4Address("192.168.0.2"), protocol=TransportLayerProtocol.UDP, port=0x2429, ), ], ip_v6_endpoints=[], ) ) data = serialize_sd_message(sd_message) # fmt: off expected_data = bytes( [ 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 60, # length: 60 0x00, 0x00, 0x12, 0x34, 0x01, 0x01, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, # length entries: 16 0x01, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x02, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, # length of options: 2 * 12 0x00, 0x09, 0x04, 0x00, 192, 168, 0, 1, 0x00, 0x06, 0x23, 0x28, 0x00, 0x09, 0x04, 0x00, 192, 168, 0, 2, 0x00, 0x11, 0x24, 0x29]) # fmt: on assert len(data) == len(expected_data) assert data == expected_data someipy-2.1.2/tests/sd/test_sd_service_instance.py000066400000000000000000000022251513043235100223720ustar00rootroot00000000000000import ipaddress import pytest from someipy._internal._sd.service_instance import ServiceInstance from someipy._internal.transport_layer_protocol import TransportLayerProtocol def test_equality(): instance_1 = ServiceInstance( service_id=1234, instance_id=5678, major_version=1, minor_version=0, ttl=4, endpoint=(ipaddress.IPv4Address("127.0.0.1"), 12345), protocols=frozenset([TransportLayerProtocol.TCP]), timestamp=1.0, ) instance_2 = ServiceInstance( service_id=1234, instance_id=5678, major_version=1, minor_version=0, ttl=4, endpoint=(ipaddress.IPv4Address("127.0.0.1"), 12345), protocols=frozenset([TransportLayerProtocol.TCP]), timestamp=1.0, ) instance_3 = ServiceInstance( service_id=1234, instance_id=5678, major_version=1, minor_version=0, ttl=4, endpoint=(ipaddress.IPv4Address("127.0.0.2"), 12345), protocols=frozenset([TransportLayerProtocol.TCP]), timestamp=1.0, ) assert instance_1 == instance_2 assert instance_1 != instance_3 someipy-2.1.2/tests/test_sd_service_with_timestamp.py000066400000000000000000000021671513043235100232230ustar00rootroot00000000000000import ipaddress import pytest from someipy._internal.someip_sd_header import SdService2, SdServiceWithTimestamp from someipy._internal.transport_layer_protocol import TransportLayerProtocol def test_equality(): sd_service_1 = SdService2( service_id=1234, instance_id=5678, major_version=1, minor_version=0, ttl=4, endpoint=(ipaddress.IPv4Address("127.0.0.1"), 12345), protocols=frozenset([TransportLayerProtocol.TCP]), ) sd_service_2 = SdService2( service_id=1234, instance_id=5678, major_version=1, minor_version=0, ttl=4, endpoint=(ipaddress.IPv4Address("127.0.0.1"), 12345), protocols=frozenset([TransportLayerProtocol.TCP]), ) assert sd_service_1 == sd_service_2 sd_service_with_ts_1 = SdServiceWithTimestamp(sd_service_1, 1.0) sd_service_with_ts_2 = SdServiceWithTimestamp(sd_service_2, 2.0) assert sd_service_with_ts_1 == sd_service_with_ts_2 list_to_check = [sd_service_with_ts_1] assert sd_service_with_ts_1 in list_to_check assert sd_service_with_ts_2 in list_to_check someipy-2.1.2/tests/test_serialization.py000066400000000000000000000250701513043235100206320ustar00rootroot00000000000000from dataclasses import dataclass import pytest from someipy.serialization import ( Uint8, Uint16, Uint32, Uint64, Sint8, Sint16, Sint32, Sint64, Bool, Float32, Float64, SomeIpPayload, SomeIpFixedSizeArray, SomeIpDynamicSizeArray, SomeIpFixedSizeString, SomeIpDynamicSizeString, ) def test_base_types_len(): assert 1 == len(Uint8(1)) assert 2 == len(Uint16(1)) assert 4 == len(Uint32(1)) assert 8 == len(Uint64(1)) assert 1 == len(Sint8(-1)) assert 2 == len(Sint16(-1)) assert 4 == len(Sint32(-1)) assert 8 == len(Sint64(-1)) assert 1 == len(Bool(True)) assert 4 == len(Float32(1.0)) assert 8 == len(Float64(1.0)) @dataclass class MsgBaseTypesOnly(SomeIpPayload): """ The dataclass decorator will generate an __eq__ method which can be used for comparing the content of two messages """ # Expected 13 bytes in total x: Uint8 # 1 byte y: Uint32 # 4 bytes z: Float64 # 8 bytes def __init__(self): self.x = Uint8(0) self.y = Uint32(0) self.z = Float64(0.0) @dataclass class MsgWithOneStruct(SomeIpPayload): # Expected 1 + 13 + 4 bytes in total a: Uint8 b: MsgBaseTypesOnly c: Sint32 def __init__(self): self.a = Uint8(0) self.b = MsgBaseTypesOnly() self.c = Sint32(0) def test_someip_payload_len(): assert 13 == len(MsgBaseTypesOnly()) assert (13 + 1 + 4) == len(MsgWithOneStruct()) def test_struct_equals_operator(): m_1 = MsgBaseTypesOnly() m_2 = MsgBaseTypesOnly() assert m_1 == m_2 m_1.x = Uint8(1) assert m_1 != m_2 m_2.x = Uint8(1) assert m_1 == m_2 def test_struct_serialization_and_deserialization(): m = MsgBaseTypesOnly() m.y = Uint32(4) # Expected: 0x 00 00000004 0000000000000000 assert bytes.fromhex("00000000040000000000000000") == m.serialize() m.x = Uint8(255) # Expected: 0x FF 00000004 0000000000000000 assert bytes.fromhex("ff000000040000000000000000") == m.serialize() m_again = MsgBaseTypesOnly().deserialize( bytes.fromhex("ff000000040000000000000000") ) assert m_again == m # The first byte is changed now to decimal 254 m_different = MsgBaseTypesOnly().deserialize( bytes.fromhex("fe000000040000000000000000") ) assert m_different != m_again assert m_different != m def test_fixed_size_array_length(): a = SomeIpFixedSizeArray(Uint16, 10) expected_bytes = len(Uint16()) * 10 assert len(a) == expected_bytes def test_fixed_size_array_equals_operator(): a = SomeIpFixedSizeArray(Uint16, 10) b = SomeIpFixedSizeArray(Uint16, 10) assert a == b c = SomeIpFixedSizeArray(Uint8, 10) assert a != c a.data[0] = Uint16(5) assert a != b b.data[0] = Uint16(5) assert a == b def test_fixed_size_array_serialization_and_deserialization(): a = SomeIpFixedSizeArray(Uint8, 4) # Expected hex: 0x 00 00 00 00 assert bytes.fromhex("00000000") == a.serialize() a.data[0] = Uint8(1) a.data[1] = Uint8(2) a.data[2] = Uint8(3) a.data[3] = Uint8(4) # Expected hex: 0x 01 02 03 04 assert bytes.fromhex("01020304") == a.serialize() a_again = SomeIpFixedSizeArray(Uint8, 4).deserialize(bytes.fromhex("01020304")) assert a_again == a def test_dynamic_size_array_length(): a = SomeIpDynamicSizeArray(Uint16) assert len(a) == a.length_field_length e = Uint16(1) a.data.append(e) assert len(a) == a.length_field_length + len(Uint16()) del a.data[0] assert len(a) == a.length_field_length a.length_field_length = 2 # Except only the length field with 2 bytes to be serialized and no data assert bytes.fromhex("0000") == a.serialize() a.length_field_length = 4 # Except only the length field with 4 bytes to be serialized and no data assert bytes.fromhex("00000000") == a.serialize() a.data.append(Uint16(1)) assert bytes.fromhex("000000020001") == a.serialize() a.data.append(Uint16(4)) assert len(a) == 2 * len(Uint16()) + a.length_field_length assert bytes.fromhex("0000000400010004") == a.serialize() b = SomeIpDynamicSizeArray(Uint16) b.length_field_length = 4 b = b.deserialize(bytes.fromhex("0000000400010004")) assert b == a assert b.data[0] == Uint16(1) assert b.data[1] == Uint16(4) assert len(b) == 2 * len(Uint16()) + a.length_field_length def test_someip_fixed_size_string(): a = SomeIpFixedSizeString(4) assert a.size == 4 assert a.data == "" assert a.encoding == "utf-8" assert len(a) == 4 + 3 with pytest.raises(ValueError): a.data = "Hello World" with pytest.raises(ValueError): a.encoding = "Hello World" a.data = "He" a.encoding = "utf-8" assert len(a) == 4 + 3 b = SomeIpFixedSizeString(4) b.data = "He" assert a == b assert bytes.fromhex("EF BB BF 48 65 00 00") == a.serialize() a.encoding = "utf-16le" assert bytes.fromhex("FF FE 48 00 65 00 00 00 00 00") == a.serialize() a.encoding = "utf-16be" assert bytes.fromhex("FE FF 00 48 00 65 00 00 00 00") == a.serialize() b = SomeIpFixedSizeString(4) b.encoding = "utf-16be" b = b.deserialize(bytes.fromhex("EF BB BF 48 65 00 00 00 00")) assert b.encoding == "utf-8" assert b.data == "He" assert len(b) == 7 b = b.deserialize(bytes.fromhex("FF FE 48 00 65 00 00 00 00 00")) assert b.encoding == "utf-16le" assert b.data == "He" assert len(b) == 10 b = b.deserialize(bytes.fromhex("FE FF 00 48 00 65 00 00 00 00")) assert b.encoding == "utf-16be" assert b.data == "He" assert len(b) == 10 def test_someip_dynamic_size_string(): a = SomeIpDynamicSizeString() assert a.data == "" assert a.encoding == "utf-8" assert a.length_field_length == 4 assert a._length_field_value == 4 assert len(a) == 4 + 3 + 1 with pytest.raises(ValueError): a.encoding = "Hello World" with pytest.raises(ValueError): a.length_field_length = 0 a.data = "He" a.encoding = "utf-8" assert len(a) == 4 + 3 + 2 + 1 # 4 bytes for the length field, 3 bytes BOM and 3 bytes for the data including '\0' assert bytes.fromhex("00 00 00 06 EF BB BF 48 65 00") == a.serialize() a.encoding = "utf-16le" assert len(a) == 4 + 2 + 2 * 2 + 2 assert bytes.fromhex("00 00 00 08 FF FE 48 00 65 00 00 00") == a.serialize() a.encoding = "utf-16be" assert len(a) == 4 + 2 + 2 * 2 + 2 assert bytes.fromhex("00 00 00 08 FE FF 00 48 00 65 00 00") == a.serialize() a.encoding = "utf-8" a.length_field_length = 2 assert len(a) == 2 + 3 + 2 + 1 # 2 bytes for the length field, 3 bytes BOM and 3 bytes for the data including '\0' assert bytes.fromhex("00 06 EF BB BF 48 65 00") == a.serialize() b = SomeIpDynamicSizeString() b.encoding = "utf-16be" b.length_field_length = 4 b = b.deserialize(bytes.fromhex("00 00 00 09 EF BB BF 48 65 00 00 00 00")) assert len(b) == 13 assert b.encoding == "utf-8" assert b.data == "He" b = b.deserialize(bytes.fromhex("00 00 00 0A FF FE 48 00 65 00 00 00 00 00")) assert b.encoding == "utf-16le" assert b.data == "He" b = b.deserialize(bytes.fromhex("00 00 00 0A FE FF 00 48 00 65 00 00 00 00")) assert b.encoding == "utf-16be" assert b.data == "He" b.length_field_length = 2 b = b.deserialize(bytes.fromhex("00 0A FE FF 00 48 00 65 00 00 00 00")) assert b.encoding == "utf-16be" assert b.data == "He" @dataclass class MsgWithStrings(SomeIpPayload): a: Uint16 b: SomeIpDynamicSizeString d: Uint32 def __init__(self): self.a = Uint16(10) self.b = SomeIpDynamicSizeString("123") self.c = Uint32(5) def test_struct_with_dynamic_sized_types(): a = MsgWithStrings() assert len(a) == len(Uint16()) + len(SomeIpDynamicSizeString("123")) + len(Uint32()) assert len(a) == 2 + 4 + 3 + 3 + 1 + 4 assert len(a.serialize()) == len(a) assert ( bytes.fromhex("00 0A 00 00 00 07 EF BB BF 31 32 33 00 00 00 00 05") == a.serialize() ) a.b = SomeIpDynamicSizeString("1234") assert len(a) == 2 + 4 + 3 + 3 + 1 + 4 + 1 assert ( bytes.fromhex("00 0A 00 00 00 08 EF BB BF 31 32 33 34 00 00 00 00 05") == a.serialize() ) b = MsgWithStrings().deserialize( bytes.fromhex("00 0A 00 00 00 08 EF BB BF 31 32 33 34 00 00 00 00 05") ) assert b.a == Uint16(10) assert b.b == SomeIpDynamicSizeString("1234") assert b.c == Uint32(5) @dataclass class MsgWithTwoStrings(SomeIpPayload): a: Uint16 b: SomeIpDynamicSizeString c: SomeIpDynamicSizeString d: Uint32 def __init__(self): self.a = Uint16(10) self.b = SomeIpDynamicSizeString("123") self.c = SomeIpDynamicSizeString("4321") self.c.encoding = "utf-16be" self.d = Uint32(5) def test_struct_with_dynamic_sized_types(): a = MsgWithTwoStrings() assert len(a) == 2 + 4 + 3 + 3 + 1 + 4 + 2 + 4 * 2 + 2 + 4 assert len(a.serialize()) == len(a) assert ( bytes.fromhex( "00 0A 00 00 00 07 EF BB BF 31 32 33 00 00 00 00 0C FE FF 00 34 00 33 00 32 00 31 00 00 00 00 00 05" ) == a.serialize() ) b = MsgWithTwoStrings().deserialize( bytes.fromhex( "00 0A 00 00 00 07 EF BB BF 31 32 33 00 00 00 00 0C FE FF 00 34 00 33 00 32 00 31 00 00 00 00 00 05" ) ) assert b.a == Uint16(10) assert b.b == SomeIpDynamicSizeString("123") c = SomeIpDynamicSizeString("4321") c.encoding = "utf-16be" assert b.c == c assert b.d == Uint32(5) @dataclass class MsgWithDynamicArrays(SomeIpPayload): a: Uint16 b: SomeIpDynamicSizeArray[Uint8] c: Uint32 d: SomeIpDynamicSizeArray[Uint16] def __init__(self): self.a = Uint16(10) self.b = SomeIpDynamicSizeArray(Uint8) self.c = Uint32(5) self.d = SomeIpDynamicSizeArray(Uint16) def test_struct_with_dynamic_arrays(): a = MsgWithDynamicArrays() assert len(a) == 2 + 4 + 4 + 4 assert len(a.serialize()) == len(a) assert bytes.fromhex("00 0A 00 00 00 00 00 00 00 05 00 00 00 00") == a.serialize() a.b.data.append(Uint8(1)) assert len(a.serialize()) == len(a) assert ( bytes.fromhex("00 0A 00 00 00 01 01 00 00 00 05 00 00 00 00") == a.serialize() ) b = MsgWithDynamicArrays().deserialize( bytes.fromhex("00 0A 00 00 00 01 01 00 00 00 05 00 00 00 00") ) assert b.a == Uint16(10) assert b.b.data[0] == Uint8(1) assert b.c == Uint32(5) assert len(b.d) == b.d.length_field_length someipy-2.1.2/tests/test_someip_data_processor.py000066400000000000000000000043111513043235100223340ustar00rootroot00000000000000import pytest from someipy._internal.someip_data_processor import SomeipDataProcessor from someipy._internal.someip_header import SomeIpHeader from someipy._internal.message_types import MessageType from someipy._internal.someip_message import SomeIpMessage @pytest.fixture def valid_someip_message() -> SomeIpMessage: # length is 8 bytes + payload size payload_size = 64 length = 8 + payload_size someip_header = SomeIpHeader( service_id=1, method_id=2, length=length, client_id=3, session_id=4, protocol_version=1, interface_version=2, message_type=MessageType.REQUEST.value, return_code=0x00, ) payload = b"\x00" * payload_size return SomeIpMessage(header=someip_header, payload=payload) @pytest.fixture def corrupt_someip_message() -> SomeIpMessage: # length is 8 bytes + payload size payload_size = 64 length = 8 + payload_size + 1 # +1 for corrupt header someip_header = SomeIpHeader( service_id=1, method_id=2, length=length, client_id=3, session_id=4, protocol_version=1, interface_version=2, message_type=MessageType.REQUEST.value, return_code=0x00, ) payload = b"\x00" * payload_size return SomeIpMessage(header=someip_header, payload=payload) def test_process_with_datagrams(valid_someip_message): data = valid_someip_message.header.to_buffer() + valid_someip_message.payload processor = SomeipDataProcessor() result = processor.process_data(data) assert result is True assert processor.someip_message.header == valid_someip_message.header assert processor.expected_bytes == 8 assert len(processor._buffer) == 0 result = processor.process_data(data) assert result is True assert processor.someip_message.header == valid_someip_message.header assert processor._expected_bytes == 8 assert len(processor._buffer) == 0 def test_process_with_malformed_datagrams(corrupt_someip_message): data = corrupt_someip_message.header.to_buffer() + corrupt_someip_message.payload processor = SomeipDataProcessor() result = processor.process_data(data) assert result is False