pax_global_header00006660000000000000000000000064141507035740014520gustar00rootroot0000000000000052 comment=d3f5a082af86f649d4c74c7fcc946188b1ac9fac andi-0.14/000077500000000000000000000000001415070357400123575ustar00rootroot00000000000000andi-0.14/.clang-format000066400000000000000000000003501415070357400147300ustar00rootroot00000000000000BasedOnStyle: LLVM IndentWidth: 4 TabWidth: 4 UseTab: Always AllowShortIfStatementsOnASingleLine: true AllowShortFunctionsOnASingleLine: false IndentCaseLabels: true AllowShortCaseLabelsOnASingleLine: true BreakBeforeBraces: Attach andi-0.14/.gitignore000066400000000000000000000014471415070357400143550ustar00rootroot00000000000000# Binary and automatically generated files *.o *.a andi andi_* randomSeed.dat seedms testRMQ src/config.h src/stamp-h1 src/config.hin src/config.hin~ #docs docs/doxygen_sqlite3.db docs/html/* docs/latex/* docs/andi.1 *.aux *.auxlock *.dep *.dpth *.toc *.out *.pdf *.backup *.bbl *.blg !andi-manual.pdf *.in !docs/andi.1.in !docs/manual/version.tex.in docs/manual/version.tex *.log **/Makefile configure.scan config.status depcomp install-sh aclocal.m4 **/.deps/ autom4te.cache/ README ChangeLog missing compile configure ar-lib src/.dirstamp # test files *.fasta cachegrind* callgrind* test.trs test-driver test_esa test_seq test_fasta test_process *.trs # Coverage *.gcda *.gcno *.gcov andi.sublime-* # for legacy git only: libs/RMQ/.deps/ libs/RMQ/Makefile Makefile # Profiling: gmon.out profile andi-0.14/.travis.yml000066400000000000000000000030411415070357400144660ustar00rootroot00000000000000language: cpp compiler: - gcc - clang arch: - amd64 - ppc64le sudo: false addons: apt: sources: - deadsnakes - ubuntu-toolchain-r-test packages: - cmake - libglib2.0-dev - libgsl0-dev install: - export LIBDIVDIR="$HOME/libdivsufsort" - pip install --user cpp-coveralls - wget https://github.com/y-256/libdivsufsort/archive/master.tar.gz - tar -xzvf master.tar.gz - cd libdivsufsort-master && mkdir build && cd build - cmake -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX="$LIBDIVDIR" .. - make && make install script: - CONFIGURE_FLAGS="" - export LD_LIBRARY_PATH="$LIBDIVDIR:$LIBDIVDIR/lib" - export LIBRARY_PATH="$LIBDIVDIR:$LIBRARY_PATH" - cd $TRAVIS_BUILD_DIR - autoreconf -fvi -Im4 - export MYFLAGS="-fprofile-arcs -ftest-coverage -I$LIBDIVDIR/include" - if [ "${CC}" = "clang" ]; then export CONFIGURE_FLAGS="--disable-openmp"; fi - ./configure $CONFIGURE_FLAGS --enable-unit-tests LDFLAGS="-L$LIBDIVDIR/lib" CFLAGS="$MYFLAGS" CXXFLAGS="$MYFLAGS" - make - make check || cat ./test-suite.log || exit 1 - export MYFLAGS="-I$LIBDIVDIR/include" - ./configure $CONFIGURE_FLAGS --enable-unit-tests LDFLAGS="-L$LIBDIVDIR/lib" CFLAGS="$MYFLAGS" CXXFLAGS="$MYFLAGS" - make distcheck DISTCHECK_CONFIGURE_FLAGS="LDFLAGS=\"-L$LIBDIVDIR/lib\" CFLAGS=\"-I$LIBDIVDIR/include\" CXXFLAGS=\"-I$LIBDIVDIR/include\" $CONFIGURE_FLAGS" after_success: - if [ "$CXX" = "g++" ]; then coveralls --exclude libdivsufsort-master -E '^andi-.*' --exclude libs --exclude test --gcov `which gcov-4.8` --gcov-options '\-lp'; fi andi-0.14/COPYING000066400000000000000000001045131415070357400134160ustar00rootroot00000000000000 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 . andi-0.14/INSTALL000066400000000000000000000366001415070357400134150ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX `make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as `configure' are involved. Use GNU `make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. andi-0.14/Makefile.am000066400000000000000000000017651415070357400144240ustar00rootroot00000000000000ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 AM_DISTCHECK_CONFIGURE_FLAGS="--enable-unit-tests" .PHONY: all SUBDIRS = . libs opt src docs DIST_SUBDIRS = . libs opt src docs test # Conditionally build the tests if BUILD_TESTS SUBDIRS+= test AM_TESTS_ENVIRONMENT= \ RANDOM_SEED='@SEED@' ; export RANDOM_SEED ; XFAIL_TESTS= TESTS = $(XFAIL_TESTS) test/nan.sh test/low_homo.sh test/test_esa test/test_seq test/test_extra.sh test/test_random.sh test/test_join.sh test/test_process $(TESTS): src/andi endif # BUILD_TESTS dist_noinst_DATA = ChangeLog README.md dist_pdf_DATA = andi-manual.pdf dist_noinst_SCRIPTS= scripts/maf2phy.awk scripts/vmatch.sh scripts/_andi # Recreate the changelog, when the version string changes. ChangeLog: configure.ac echo "Missing Git" > ChangeLog; if test -d $(srcdir)/.git; then \ which git && git log --stat --date=short --abbrev-commit | grep --invert-match '^ [[:alnum:].]' | git stripspace > ChangeLog; \ fi .PHONY: code-docs code-docs: cd docs && $(MAKE) code-docs; andi-0.14/README.md000066400000000000000000000074611415070357400136460ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/EvolBioInf/andi.svg?branch=master)](https://travis-ci.org/EvolBioInf/andi) [![Coverage Status](https://coveralls.io/repos/EvolBioInf/andi/badge.svg?branch=master)](https://coveralls.io/r/EvolBioInf/andi?branch=master) # About This is the `andi` program for estimating the evolutionary distance between closely related genomes. These distances can be used to rapidly infer phylogenies for big sets of genomes. Because `andi` does not compute full alignments, it is so efficient that it scales even up to thousands of bacterial genomes. This readme covers all necessary instructions for the impatient to get `andi` up and running. For extensive instructions please consult the [manual](andi-manual.pdf). # Installation and Usage Stable versions of `andi` are available via package managers. For manual installation see below. For Debian and Ubuntu: sudo apt-get install andi For macOS with Homebrew: brew tap brewsci/bio brew install andi For ArchLinux with aura: sudo aura -A andi With a successful installation you can get the usage instructions via `--help` or the man page. $ andi --help $ man andi You can simply use `andi` with your genomes in `FASTA` format. $ andi S1.fasta S2.fasta 2 S1 0.0 0.1 s2 0.1 0.0 From this distance matrix the phylogeny can be inferred via neighbor-joining. Check the [manual](andi-manual.pdf) for a more thorough description. ## Manual installation If your system does not support one of the above package managers you have to manually build the latest [stable release](https://github.com/EvolBioInf/andi/releases) from a tarball. See the [manual](andi-manual.pdf) for extensive building instructions. This program has the following external dependencies: [libdivsufsort](https://github.com/y-256/libdivsufsort) and the [GSL](https://www.gnu.org/software/gsl/). Please make sure you installed both before attempting a build. If you did get the source, not as a tarball, but straight from the git repository, you will also need the autotools. Assuming you have installed all prerequisites, building is as easy as follows. $ autoreconf -fi -Im4 # optional when building from tarball $ ./configure $ make $ make install Excessive build instructions are located in `INSTALL`. # Links and Additional Resources The release of this software is accompanied by a paper from [Haubold et al.](http://bioinformatics.oxfordjournals.org/content/31/8/1169). It explains the used *anchor distance* strategy in great detail. The `maf2phy.awk` script used in the validation process is located under `scripts`. Simulations were done using our own [simK](http://guanine.evolbio.mpg.de/bioBox/) tool. For a demo visualising the internals of andi visit our [GitHub pages](http://evolbioinf.github.io/andi/). ## Data Sets 1. 29 E. coli and Shigella strains: [data](http://guanine.evolbio.mpg.de/andi/eco29.fasta.gz) 2. 109 E. coli ST131 strains ([paper](http://www.pnas.org/content/early/2014/03/28/1322678111.abstract)): * [99 newly sequenced strains](https://github.com/BeatsonLab-MicrobialGenomics/ST131_99) * [10 previously published strains](http://guanine.evolbio.mpg.de/andi/st131_extra.tgz) 3. 3085 Streptococcus pneumoniae strains ([paper](http://www.nature.com/ng/journal/v46/n3/full/ng.2895.html)): ftp://ftp.sanger.ac.uk/pub/pathogens/Streptococcus/pneumoniae/Maela_assemblies.tgz ## License Copyright © 2014 - 2021 Fabian Klötzl License GPLv3+: GNU GPL version 3 or later. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. The full license text is available at . Some files may be licensed differently. ## Contact In case of bugs or unexpected errors don't hesitate to send me a mail: kloetzl@evolbio.mpg.de andi-0.14/andi-manual.pdf000066400000000000000000015365451415070357400152630ustar00rootroot00000000000000%PDF-1.5 % 8 0 obj << /Length 417 /Filter /FlateDecode >> stream xڝRn0>TzlcCOU(ͩno;`Ru+E"73A#&/$ݶb&[]%%k i%(@X͚=Cm;nma(,E#u.;Xhh\{?(duYʩ;J%tӌ}1ş*yʴ22k?vع1}n)'rM ',f艔2DIW}jEd}?oa%y ݕa 4,Р-0ܨWrvn})cnjG0K8ZLnި#W< ПwZ@L:8w(De5k4iU$s?E Ϯ~dzFsSuK`u#[];@ endstream endobj 6 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./andi_labels.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 16 0 R /BBox [0 0 793 639] /Resources << /XObject << /Xf1 17 0 R >>>> /Length 49 /Filter /FlateDecode >> stream x+r 26S030VIr *T0T0Bf endstream endobj 17 0 obj << /Type /XObject /Resources << /ExtGState << /GS2 18 0 R /GS1 19 0 R >> /Font << /F1 20 0 R >> >> /Subtype /Form /BBox [ 0 0 793 639] /Matrix [ 1 0 0 1 0 0] /Length 1617 /FormType 1 /Filter /FlateDecode >> stream xWKsGﯘcr0==ϣ- `CL֦I}im@I3_%FqOJ>qsx;< ZSPj%n/=~lrU*WyK)thk<rmgAh%,%1H"p$Al?(q*^j< '-Hc+c:&^X`a +FE8@ҢV ` :@cUyOJ'*^7XeNLNPHvc6 :迡:Hm;.oRZ@Eg EY),E>J f<Pr1Q/羚aŵk_VWm=)pJkP56 X_tg<͗0Sl:m<><^~R< ҉F %Ҥ-YW@ҋRl;.*.&Қ󪾑7wwbu; :I fy'Q6=Nm.Z}ܯh=6Ul$tA"=]J:_߶N~ 7_eZE}E]΢Qp7*lri r~yb -V5bO9\CnڀIZSL^xZ+:jB_iJvL WS[wzEciu~TS*zUEDlev?=E.HOBc#*ʹ4]7o~QzA?{ 꾬^qA>I&'a"^G7A$؜`$Xmxv񉮂wmr'~R;q`MQ endstream endobj 26 0 obj << /Length 1254 /Filter /FlateDecode >> stream xڍVKo8 W62(5bg\[IvGK=i2C+JȏGI跻5 //h}[~,J)&gj )!QSLVUrW&,X[)N̺g`,%4ʉyGv͑_9vTmQ9֪nVCxaFRLr1(J7f R}v6m~5 l'dW{ɌCOl~J@]ٸU4m"w;%ӽLe 3ikc V?LmAly@7cnkhɽotQL 7JCQBн;_RZ_M ؔ2v.g<jAQ^(z?lf4KmcY u֯GBhA4ڗLnb0J;]m .yUqH/\c0LHqQ˒hZ{HiOr3Iǹ@g * h {wۧxY&x~w ws d.pA.LޢEd غ91E?.]G 9{01˦'r@'HxQGvyZa\A7@F#KOX $AqҮ!h"@> ӳɃ (~=Cu Nאh/VjWʅOQJs.83E9n,KA>j===d .2,)H-Kx8 eVP,ʶ1a<̚P@cS9_~b05<=kmaz{Iwg0Mn3 cdc;qFũtXA>MwEtFopԶ#៮)f.dID2>e'۵Á{@\ XX'nPGQwJ'%\$u;JɔT+gV~u `݋)n :y&S4$mOWvDH 窫n'E1޾`NC$2s^`XFM8n9tHjƩǶp0eٹBQve`}\q%Sjf7)/}/J]kF :S3WEZ J[)^9?A endstream endobj 56 0 obj << /Length 748 /Filter /FlateDecode >> stream xXMs0WI+ kL&ę<=0q=qkp?}B$L3`0ݷ"h:H`fB5|δ@`)@ Ac (8L"?eu*3kdi #dpa"͒bߍ8W ~% x (k!bbJ >'dEŒ8!pZ*;hQ%X?xlU0oW^5ulN!PҐ=p'7z"q@E1ks#(ǚ[bZ&sy!z]/Yf3?uN?جQe(s'.z.‹,}r<"{2ޖ&0xMi>K?[X9 h:Θok!P$m .r'%(NP Y[䮆I̽;9]T5"$"fUWz5ej|Y|&ZUEB^.M]5&MC AYX|:j îGVļ%wxp'i?,We岑Jr1#όvۂp$7ryz[@6~3oD8"R'l|JM"yh{3~[%*[DzJ|Oqi2+?"ϗ=[_$]̤$āo}wD~s}Y- endstream endobj 80 0 obj << /Length 19 /Filter /FlateDecode >> stream x3PHW0Pp2Ac( endstream endobj 89 0 obj << /Length 2556 /Filter /FlateDecode >> stream xZIsWԀUF NA=JMC4U`6t~=(6^轾~1"D}]}~qJr(k/('B|},a_uyde1<=mQ"fCi4FzDvKIg[Ru5+rO"H `A))&u֍KESS-R)H5` VbaⰨFm mgƥ$nbvk[X1OǹXY X2^\blڨ`" l"K +XhڗFHzݿj o? r/1b֗^9 iJ2dOߍbFĔ5$ u΂_;x位vUQTHMI#u G(ѱ<͘sİQ,]|wc8kE]Lwڏe~<[TkrӪ,Lq)Q og0"~z}7W?dC($mL"!3Y s1IX tI8R,;M`J݉9Cb DS \z\Q[yXE7&cE}* #DeU?ٷǶKDqwTΊԬ_˭ZR٤s/ R#9I}R EERI*C p|3kCQ9 x!L}Kv{ k:[E.-b0`:%`c^`Hԕ34!W6iUZfjvY`L0?H2 )j*[dA^)aI|ba8ňı;<ȞKeUZQ/paS&+6流IYO% ƈ M۲-"dƮP< }>Bm"˽0vC0ĦVqc~ 1r<7 .hta:7e @G|Cby0X2 M%e,"ʏ6})>H G=L,(u'u@uL0 ỹF4ih\΁w+u.f$G{(s(tᅙ}"Z0JLl-0"NI_[_tGQNhHׅuzE-]Ƞ:A!]U 5nuY5S,E@>"T.1j8l/fva鷲 玼 ,]?x Y <Bghlo3^ &HXWn Kmmwet9]3)*xTRCcM2 MA1Y+#ݙ^$e\6ߧ5!p`!7h |#5re>~[+K)|#ۄ)mn1)}=b|2u΋f8a f'É,٦iGUgx1tR=P%_&V)z=J;FUzpc,f#ͯ0‰Ed'~R0Бr1@̝g@,nHN+!͂ ʼ&iʆp*3FwWm~q,KwYCJ2:}bguDJDmmgfސrP[Cax8ai MAS] $"7ܺZ> Ɂ3⮜Ƒhv]W) Cd ' φUOК23qI]ØYN˜!F68bT1 7Ǫvb!z# iy4Oz"ű(gD;b?{䰧2hƶ!ŌތbٝXԡRm) ܙ@10z &MshOZF!T0'k /G N6#{t7FnU#O}dE!auZL;nvo.kS\+f~e.P뉵PLϥ&P:/')j>\^5hP=OjdǻJ.UVL`lyLzߙ>`IXM͚%(Rlⅱa,ʲ*|vnAHZeJթðQʖi=p,PLM{Xª\_O*AP3~cFMMYŴ S'VmS0`lQ>I{҄۶bGB qI *?ܼ endstream endobj 120 0 obj << /Length 1435 /Filter /FlateDecode >> stream xڽXKs6W15S"ěH'3mǵm:=P$$qB*vtoi΁:hoPmл< {EBJ-מQH!!L}xWEy7YY,Y^j'R^6J],= záD̓#AguF\̸1a7`",`W:ͻv,bGqa[O\L˵}ϝCk";L"NHRx"-;ݜl_Sۼye߮>'"U(1io]|" lSd,DI3 lj H|v`ĕ") Ut]뷋O.⪬h0 ٷU\9}|*rjx8/!rD2 .ٙ] )6ڼI[GOYB2At7DUY,S{iֵ=ɊuYـžAv5aIȎPm|F= .y|QVO)O: tJ!׬' sNp@ڐ1 ٷ( _ֵ_$_>f ?` ܜR4 LGpr b.}l(`oY$^dŭOLv.I"Qo-^La0rqBٯG5C^?&=h(CՔ  1iVlCjξ\g7Nu֘.s,70ʞ`KBߜ>F|8VbxJXɷ1Z:^*]eBJ.mooG=xg6u0Wt<)Fz`ʇ`&`Ge^? d6Ddm.gMɴ4$ .kϐDc*\H$LevʎLif61CiYG^H7Nko;y^ u57sO5{)w)I?^<]6s$N%mB_]ܕ*/\Q<g74 ؍LTGG\r~q H3LS͚=Ӵ`|U飽ԋg(j,SLKuH:I!xW{V 0S]xZedEwC(R!/v킒4YspMkR]'U6OC˔}kC"LjI7@;-:fW1) EGT` endstream endobj 137 0 obj << /Length 3216 /Filter /FlateDecode >> stream xZmP@ UR]Kp-д " Ŗm۠o D{H9cD(L}wm£9nHI% j~ 8ȒmH4CX;:KYymZgP}ޑvV7"jGduds.G5TJQ]s۸;e+wܯ4ww7x>SVF S7خbʹVH4Qv7rz? WrVa|vbNvmTW09S`V ?g;P ۋ Or&z%I4e^t_qWڗLkv-#BGgd/8s5c.iǸKc5 mV:CI {#$jZ5vA[~uSvԺ/?!@5oN|9wΟ OTHhQ1:&z+mC9$^jluvKg^?M {G99<ɬٷ5tFcK,\|K/чUm@d"yT?>Ag܇}58W,1IU5@@+8-S)ξMFl6 fd5p1OUڡwm0>{~*0¹.2t؜dG@Px a/XD}p,0 Ǫ=H}8@R;'&, tl>wY'Ը ɣԄ"*py\@f)SBqҌCl^n"p6>}岟5xe,7`ў9˦'=@xIh J`w@ yDQ|uxhiuY qM4a\𜂏,*,W'YZ$Kig\(QxR h+X"{-}M6#Qh;НgݩZA;2(ꮨv6糬UjK` 4:%u7npח?ÈD-GêJGnT`BXXf"q~2p*֌^0y{E0/muwb}1Cp =ҥtS̜1[QsjNWĀ2BbWA~#py|Y'TU=/ڼV].FztEӕ=2 _}Js-_coO_YB -(8V1 + ~T5v -oaZ0p0Ayؕ~exRL~VaÐĸ\ ]yȏM~\qՃHiT2 ^NN_*̡UB_ ^)[ m\-ln8GJl'8>s:NB|┛+sdlL+Gi<ݔ*WjUQPq $]Gg;BEws<*p & qD 2!ugi)St@4#64}|?F'iJ0LF4*r[&wCp9u}*s7PN;cDRj+/J$3,=\}$985lB Aq|ALh%Cǥ2Hh}N" UܽK%d~zs!PN$)Y0k_ɘMO+ h}Unޖ?}ԲpJ׋wiKN?cۼ;G-Xp/VIɅ$0#rvg^,Pn^irmIP>H,,hg>D1IHt a|@G\Ը1 j@j!h@#5:P}(þy.[ƺ@0[sc7{C,7z7kmhߵ}Es&[Bdł@D(x1Iw'_O, 滢cs^Fp>B!)vܛԠ/]7=Ֆ ^MsYvm>PbA~cعb8s&1b`KFgE, H@ 0~bۓwuя05BLhi{6/ޜJ0 Z-QkCEZ-%өW,b:ZrTϭቜaߢa"#5ʭ˹l!TFtF1Y|.b ܍+xf?Nk>O RS(pĉW]Yvg"5mEWϛFcFqvmaĘde8u+kҿn~?7c3VkC(][UFUi٨7&aˮ Nlb)x,UԐ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 812 /Length 2266 /Filter /FlateDecode >> stream xڽYn}W]XDka+[58I |}NnRT=Ӭ>S>Cƙ`&`xaø#YL1Ő3)A21@\C5AA3㓡cX%j … P #wHdU c9C%aʀ~ xx@ `ZOrqPXd#PT4+Q0K @ga0&#oVUX4l'"iSI,d5, Fz%L$xx rDO 6!*g1%K˜1W#L K% pՐtG!€pPVc}lY h.0'!,b^"2ImASr8H'X\< c4b f1ȤHOxqp.%֙ ]rBu ~'Z*9 R@ L=;y=gπ9.j҈fMqs?Aլ. FhhG%^μڽ;7ׯa+S'b<^R/QsTΎZA}3;gzS^q.-'l#o! bëU?ݗ/ݑڡP[u6QU'׳#;jN_Λ޸y;R g8Y$Z-[y:O͋?&M5{7]Ym rFdl29\.\+ل%zY5jJD>OHZHuǿGm ޞ"~A>԰Ro5pKsǻIyM|[N]pW1:k$ୖbڮSvFEm3+" (&,D9oc$6SZ "V"6 >(+fT(>?s_Eӳ,?_]*;Xנ,wQrGsGsguYCT(!dckos~Hno}ϾopjJt}_at5yI}X.s)Lɖ%T8jdZ.z)X[Oᶷ_aH>,ڃ~¢i=}-p_Z5Q֏~MU<<6C!Ճ<,e? endstream endobj 163 0 obj << /Length 2879 /Filter /FlateDecode >> stream x]s۸=B/7:!o}Lr7I)#S6TIʎgnۻP1>$!`]\/g4<Kf^_/"REf,Z-_->$|*Ju~}$vogz`"]W /VgIQ*R,D,f)h2TK|TsKgUfrCqV.+{.GV^u2#X(1!ݾ8pF0saNe&,vJTXF8qNXʷEK/݅8f2;$LϠtix l֌ ©*3I33xVߦ`*%3Hjpz3De2<=_fװU BjI"Xd~۹T0HEEVAHĄ\(P^xmbr%a:9PӠR=58L}lq߻캢raŀhY]MY$Q;FqT傎 c庄uMO&#]8 Aʊ=Fٕ'اO꜑4}~%?مEGv,tF2.gV^g ^;'U.Lj z"]:JW/F`UB#Cy%- }ir(R+nwLkWw‡ s&.mL!r2Xngqb0e}c/ zyHQƿTh6@K^`HϦp̪ЗV\DžOnLn$6DG"<Ʉ> $K)bSLef_;rW>sA_VCz;5FQ\IaQ08LgIX_ `hWP^D\Y@8 ^8X7X\bZ2&?'0\131qy0*:ֈ׍-`jK}lk|V7[qA{9rj+A] XInz:@qXlc+6X ڇ+0] &Mk𽠻"Ir p°oX!Q<r| eXʹ zK3>=|tY"9Zb+G7+-F+.8ydg!3t~U7Ad0* ?h{|҅ǧA| r;ܵ uNmi6QՎSJT6H ]06ɼ.&Ic"4ka_aA7?>G.Iֵh/~zkW$M~dY_k*@({x~k7:H6ˡWbflnu3EI@= L9^ wEUX\n{k> stream xڽ[[۶~L 55!:$;NӤn|I#Ak^dۻe:~< o0yWwϖQRIet8H4R:ERnS8~{V bߗ'#@nY4_ _Ff>ԯ^=qD"MiF\hU> $X"`m, VȞ$H)/8 sJ:U<|5j$AOHB˩@)δ#K="h]f ,H u^DF."--Y$Rc᏷ j^@I @,HLAb'$7(2~ In$(U*2Rm$D )?ݳh}8@U^Ta Kng ,|WY\?c&!,cr>H'xd]/t:Re5ʴ!vUe wu5ow -SVViZ_ ?,tlE`V +A h0呔.wq֥ Csx0exыϾ@6+XJ=4~eMs`]ۯ`3z"q`3L'|5%F&^h0@M(8"1CQz3kbW,2è`G{=oAxϿ,"B|\jw{X~'û*x~gݮkv^ƳeN~#P) \0:%vyڃtq4p5`Ulk&8LgGoyQ@Ufe}(Y Dz$|^iR5%,K;FlqY!0tW4"sY s"5@#=k`28㊏&3V/vC'B24]>[ʊա(gE$`6a!Gt}I5D%(ٞ8 ?$x^=B(jH/1]W3R m#fkշqUW+Cn memܡyUld6SR@%m[4`] f淥ˮ^wZ C?hU7Y7=Y:,]szіHq>$E$3r1F^XR@ue NhjYɂ@>ecN]IOxk8G)' 2茒ǂI*p7H* )֯j3/k@/&g*O}Ilw}ÅZkqCLǔOaEW|(|#8X[f6h;{1#i}r9DIh !4 "98YpOϘ|;_y ZzU8pWfbu#DRp!$\֘UiI09KXϪFw a2yAڂHQč99ci8ǹ~(_?b]_`!0A?TB>qD#q_YWu Œ+"8Y\owny5C;4)\  xz0t8M[M8Ѱ? *,ﳶ}";׌˸-iwfCQz[' S@L!}6a_x$K4>Cq)L]aŸLtD`WkU}Jxsw'7uc(`Z8/;ڟ~J"~6Nb7uL'|~bn<Ԯ׃4#-)_?5wE2"6({ނJá@J %EݽSQ{/ r gU[RL_lP^b ɫiB(wn}tmyLW\'H x2ӦY;[7>ZwoH2Jxrw`5Mj endstream endobj 244 0 obj << /Length 158 /Filter /FlateDecode >> stream xu9 A -f6{Z@;aB> stream xڵYo5~/!^{(BjJ+"<\Mz46͑6 $H<Qa-drɆ%bYdoa38`BmXZֆ#Ɉmlہygrt{5^ zp7zP_8e>]`{^{纗=sݛ讧}~=~9j up:S^/O]pzTHEj;lLh?^.X|7 -n+Z|p3^_YdXI͇jDtC5&Spz܏#F֦FU̻yOnzCsuiH; L؝Kl 3EA(Ԍ Fa]>T1IPWk+ 7#\+ɹT[av[H6R'1.doD6e} SQs2Fl}+"\p!a0k0!1k21kFp$߬ 2oMԢq˞ۻdQ!E`ʋB"t?6J])-^qy)‡[‘ڤ7OP)|n^p euHD ÈzO;z榒T'.e`*\eZJx{<9{8^|ubp1Sw(z?=p2Oq wN%5']VSv iUt\=y.Qp%c-:l~ Jv_)罓p.Nj˱{tE`'Ue&-6Wџ뵿JU'괟ST?Y?vs%JbkҭPk6,.UtI6,v|d"&f-&lj6WTTTRm~CM؈DS M^nj&,.6rAN1(lmRTmlۡ[q `@d@ɶQ!ke2d~h70]vqҏK|`KW]jD9;n?V½tJ҉}Snb77GpOiWsgs3 endstream endobj 250 0 obj << /Length 2182 /Filter /FlateDecode >> stream xڵYK۸WHUYXIlUهש#Qc>@)s<3^!яb^ѫ'pfW]Q N\-ֻEJ0a/?\)Jߗ&T]Aŗ2KSτja\;(1 锓źr8nb,liXvESflYqJm2lϣY|p8(WV;d2TI2(mceg)em~*`Hg/g )ɴFzVgT%KPFP4w3\d`h-Y8 Fʦr m%aL\O.u'9xG>)7IAx*.wG0Qg ʒmu~*B AL jocΒWapjntb!({(d4g}ᰨ%iEG)EXOpwT\#;ܕ!:>&D. ql/g&;!VF.b% a! ֛?}^oryiGX9׾D&W^&a4:RtD7{0(&arBx&|Y}FL{2XqsBomeל*hk^cY>]LyT&]/ማ&%<=[Ci{= a"{;SBK喗R*L"oB4 ;RԶʗ&y2*tYM6M`p-| pTc*a˘ܙP!Ul[O>&ێ9VYr!v^ '{[aI0&CnSlǙ[Iߝ/͠G=hF*<)PpV)O~z\T:įho4>@Da6]llVQ6lzj%_(j_̀ZUrqПY{m/zp"oGfPgju'~=hX2М]tlȧPpw/0cb: ؂؇5]1χC^5@[~LLKj%,a+ߺ; CcHuPry°83 J& RgJ8u[ܷu>2JP@@*y/L" и0tsm, wpCwk;4qޔ=RN &)H%! 2CmnM@fC>5Ư0gqP"W_CŻ mCSTJˈ^ % Ws>^ i94sdR>uȐSɾA'`+$*SЕ BuRs .]8K,cS7p,IMC_Ŭ3UBV& ]Dc1A">Qz[ygCGG}:I{_gRxȽ #E=Ny~zuxh]m -iuC0 s<RR͒}vfЍi9a H Pam"Kx`~k\zd #$ nt0cY2_fPwZOB(^l n_CꃽkW{o{fձ8!g Ͼ[ٷetUlTۉ\D(eS'Ք~_+ ƹ$>N{F5 &2}}W,Fzx}q9-hhB2 W_,U T>Sş@|*)mn.\(G<W/&!kJ/fg@34CBjlM1S|6]|TmAk,jl?ޮ_$y endstream endobj 264 0 obj << /Length 1621 /Filter /FlateDecode >> stream xڭXKoFWHі$CpvZhP4=0-*u;3Kp;;;oD(ͫo,ramk,ghj$~2I\t~>W]Wo~ fѧh3h+&N$ZTLqZquY4¯Upk=i Y 4o〢 v5YD|Y"Ds76[w 0,Ʋ$_rA j{J9dF QǭKJmfv,~ Z]/ĺ"I 4JW:eS[A/X-Ӝ,{*L|Ee Tcۡ _Qk[9sH!`IT2@Q^b`v$e2W(mnڻ7 I9@ whe]_cI$_tN[lŶg EWk1I('4W, 3&MWݴ` :;\u.p 5U'Lc:?1{G=@122wQw Qq%K^j~Qn g;&};6ԜmK^ك8o}5(wnѻ IWwqR2 bMTw='v㡲CYE<[-)v=P.|4qJǢ+Pu=RڳCe&EHtnbjs>L%d?cMkD\Ua>Ĩ'q +*`g09vOB~rYt]0#rFrƘݐd~C0I:4[Ӳl'%%p NI|BGa60O~$SҚJެ)G _OPٲcjcvpV_i: ^?&5aPΗz~,bF%vK70Q}{hv׎D)l%3{h=3sRt$*9 j;[@ũN`]ʢB=&D0M"ﴸ^ ,Q`R"hϕ$M$!hYО>Txps-. PǮrJ sEގT{JW Հ|q]c\oxl~㉁J%O<*$躥q: )9|#g\3{RR~&81k{wYN0;QJ7hn SQRs6!(;]`p3W4O J(xe $>B7&!Ϧ% Uӟ+5JԹ}AOUET96WF H½&h/w>&X&'p~ӭm‚H p@n(5mY۲_-ِrRntzWf,NLB/zi09\LYj 8m'g0OЍ^ک?[WsUrZ6m-nLȠwpCs~x{PѢ/'`{r9=BLk&!; PEN칫ͫ endstream endobj 283 0 obj << /Length 2489 /Filter /FlateDecode >> stream xڽYIϯ,6 )kO)I QHC~_o)+a o^3\ݭիpxi=z~s}) $ZV\8+JD9_d[o0 ~"_opخ?H%t%+n! E0V\busI2$0zC( >7Ey(' 7X3+{)-UͪYk;.#X0#uU$QOf-̓Eue<B򙝯u{AL0$9Tq|*اY3QVG(ֻ5i !&NhܷEuw.h&%YG85Anr<;爢PrK; lkO2<3ljJ^IYk>65%2K?C`y7cwV$?P"s$1\0.x@7k0Kh`]T]kip*pywK1U,9U˷HP$LᠡJ$絎@Hլˤ oAMs,9Ij, U"qΝZO&A#'%w5>3/KƶkMUy P T4& !eiW6añtPפ`(DWՆcl10]8/ '2^瓒#FHkeBGኇl.,-}13ݮn0Ŕ@DTb"]/ wrYnƘ@p8#E@%7\[WU3UF%7P.T`Gm5hOԪUU]KnelFU #~yV4矊&i+y; xZzvtYt,D u6}4Ei =T}R%ˆwѥ’^QBobE{+[Ǔ}쥾*x4ўQR@opWVՒTh0x #'!l {U6{wm,7揗 52E!̵3bu;=STw*J߯)MW9(8 N0Ύ..΁G <&OΑ't.8gO&S$b(qc]R<.>(Z $LAZI{{6%~PApKD)FC5F'4$F\$|e |Pk42 {'jiI6rdT +ܗL0DC@ۋ 'i xd Aոw!~En8PݙÿU&M(͡]x]&C>q2H'!EKmC^Nm1gjy=ރg:bC@뛁u?e̐s|m>$3:D `ҧ|4 _dy}.zL燽+}x=a]nɕkVM.+猘@f8")=\,B%lb#_y!{K}E- 'Dn,Pwp]f$AB|`h ,+F՟Mwq]`#Rp'74j,'}\vӤI5o4 ۾(m@Lj`:B@O 12krY-pCN||K_E2ԺcZsӘ퍩@ euem.`Z2\H Mxv8[DIi琐HO% A=^_GF޸ORn؃ 6ԍh b={֌Qw& ã41H4Isk"ͭ Xݗ4\%m] {S?&7S@kqluWztPW*? RQxYo<70r_rr#+ju> stream xZoܶŭ֣E$giX $'xw/vGI[ >Q"H~Wџg>89F,&drvł QL jz7WfşwO >aF;33I%c I𻲂o {4"0XU JzQBJEVV53$jI=<M5fKۺlUr[o*Fic쩷Y#fFͤcP RFėо0bx0[*|KeO0/וKUgҬkbКXIH+Xځ#M|ΐ-Wۤ,xI[Ն(*PJqu}%iqeTib ~TJL# 4?3 gHόTsau{L%G&WdhdU}Z': Lv XaG=l]f8I⧬ ՕngJcjͺY*ȓ/zeL+ǏS|DL Reh4FvLD_ߏE$a!'|"ذѺkY_SQU[РTƐJ\ @NL(-r]]iL ;ދ/kSre7Yݴz0̮  +`% ޳{]9xiUuW+`Y j{/w^ VB<+L0SVɚu -tdVnBDz#a"I$N`5s7?-1 Ŝ\ո'cWd/z{nmiGmB]poK]gwH )N44teEv P†u˦녂ocOj;`a%{y7]Iz 9|OnhAÄWiAxh= IIIyA0mszs_/X4( HJgOMp V@{U`|:0vEAthF9!VՅY!}ToU 馨 n_'O_۳^}_5]ρ c!(*d++EƈoW(FCTÎ\_ Gs/+56&H0#6zo|Nr= V;Jc&kH,lzէ74^HA ڗ៎F֙\g\vsiBQuu觏$>%A%xOOjb!p ! &!Zؾe Un;L$5I"62n0oF5MvkUn]umVg$@p$PA$'A!mR/A?r'ROӉBK2{[$]9ߵ[lK9MiV]ͥcTCS]%yn +A?/cI+TU=\繺v0_[M%kX |p7K)&{?g>,ov( endstream endobj 322 0 obj << /Length 1746 /Filter /FlateDecode >> stream xڍWKS9+|[ zψ[HB(UT`kk 0=<3o16Cb[jEF};!{'$='' -G`?1Wjt=|V֫?W JHcrhppa "Wt(XH% M%l # T5y$J2z-uXH$zi ʫ'ӌSd u6ΖhK&uV$h͢ήf:[ʺwN9`$蛩҄s= VOs5]9vWK[('B`P gߟ${SLؾ_{D]d_(u͝ *зs* ɊnAьQ `L= yIE5CV֮۳tYunS+kluW,Q<$YOž}Xdk$-=T)iHe=p8 lgUx*/ABb{SH4*p ۑBMpkh]w_y#!3{&,Ȍ䲵.:x V2;|F&ukɧXmgK' 8;k`}ݸc tGqGJ?&)MdT3B~^p.qBNstY&Sq?VŌ .UBYe.A}%Xv֮yYyW\i:}eVlUA5Qm: N&_ ,ƊjNiH;:ИfbNɷt"Cf.LJnv׍ k~fEo.7]okuˡ's,}BbpiE9HBA+N$!hp) fnq*{Vv%CDyA@E_֪e~d2V4~gY%m7SjȮVw˕ԣCӈ.aVg~@lmCEU<_v~X0N0WuTY셳 A(i4a1kQCuJwj=oǺ>}=e9DyCY#ERZp D^V8E7hMG0B8gaK6]I\TX%ȲT!xEdh'H #+D?blU$E-8Q@O  y49Eqyd#DPb|ʲ9H.s@SY%d3`$6IJRdBF]Zaf _ ]0iBiHQ+f,-(2DYA$'g#-d,,Y: dQH%`Mm1uT擔FP(@2I; ,/d!ٳ_|#ѕ C$` $3N= L{,?T|tF"s˰1c`,oFKQNkExAAF0e =2Ep_R&c*6X9dQ9ez / 9WGGG՗V5/_ xj1imʧz#@&G:$- 'yo7:ȥ}<EI/͋GTKBbҫ7*m6Ñyeջ2_͓2BdOysҼ>~!G}iΧ;=>6f]=k.~WRolًUB6:`W.l4# &ǶS98xq y[š<=]SgcutgYN`ؚ'"bZ/^V%ZE79ia𥟞Ui7,[N0' tD9n>G1c$Jº@YFIjw:Uzli/;非ӓ4*,R#aeu|5uX|%UaR\}9EX]~G/$u^k^^[^P_K|אhx= Iޮaw^;|S7dW?JGVă9~M4p+fS-잔n1%VaCZ#HrS%z=ray5NyK:J,!.W=ҏ+֤JeؕX+hGcX0`RsJ1(> onH!;[{sG[rJrWޔVU먌ȇhI`ϒ>6j~UrtΗ9Y*q"gIh*A!1k5:pzx}l/adӳKK>4 FL[Z9^;~$GAqA+^7B1ݛwh[nOՇo|Ϧde;| u.a1Yl_Amݓa8|)TbzH뭭›@xDR_E |%w+{Tފv_|q5q1ۅr c/5Ƽ\Kyc~ SytѮkZZDsyxkojq'kW֘{5&?H5|ٚcq_x=u6[Kxm Z֖.D}G endstream endobj 410 0 obj << /Length1 895 /Length2 31261 /Length3 0 /Length 31758 /Filter /FlateDecode >> stream xڌcpnݶ5vضm۶m۶m+bsvws[׬5ɈUL]VVVnv&z&zN.+_FvfIq u053O0Mnb`4?DyW+3?nl `PrtHlmiap75s9۹<-ffsW#gL]\a$effFE7c[+JR<\-Q3O3G / zjf꿒fT[:r30K_!zsz{3W]*̌,B#ۿo7r LvNS?DJ#;+[fVJar43Ur5-#[ĥ\S ڿO 3EIRV&6f..qv7q0\U\V4wUrÿLw-gl agddW;Wg3 +FRv11r29LLN.7qsv6wYkmn/fff&0&<֙9Yc3Db,֑NVԚ!0tOe2YG2aD0T &0U^lZ"|^wK$o;ї HuFC8fZW^y|^KCq@ `bLfH.U?fxm(0J$HwqUA"%RI3g  kq N?J%Q/"ZK[R nF0TB[?Da!<ی>[^v1FE`6$Vtv$bZ>&q@ He}Dg.pSaeG)m'i l.#t#(/dRUqH]OPKJT'FOb~|6깈GMAi+d>{=|FQ?=bYw$3?oZ+#2 _<*+}VXB \À<.?Zbun#.t(#%nrQ4dl~Z([zisȡmDZ4Ky؝gi9%\t7lن^wPI38j @6&<$y'/ |t3* umڨ=]v)mf 2oŭS8p\0hc#=LuXJOG:Vwv2r0b 5ADU4Cꘙ눨{>f00/9@|ƹ')%G5e؟[ Fg(ˡ!S1d@U[Az'kTwWSoaua*4*"ooyx읓)mǥqTI+Oաܨug "J x;j&R;z^er+HoSl?wH$; .bt0<å:[QX[]͹*%GI/7xq:L>.ݳS_.Pmه(i6'utWr cׇ)+A}BI%Ԯ30鎻#t@[d DdPґMi<+e*gD=Σ4|a( mqs%w2ڊr$O!v@|x< [_b:!ۺɬsTolt>8:) rU~eim=!%sV5:Aо哼 7dFyz!Z^)A$GЬ}>ߌ= 漖GdnXz̴/Ec6#!6ZBKͤjW׳?HaraX%c+b4* E UvkjSt^3.2AiN@m`a`7mqeCg%dqΪp >&%xR8UfħX_{g. Q7/pMdd#l@u=5OYe٩JN~Ɠhx-7`pb8/|Q $#z0cZqre=ٰ4sQYQզnv1E7_T.'"V$mDi 4ꍍČT̒6 l}K۽`Ϻe%\<NZ5K]pmZ"/ԃ[* [v^߻:hIRÐ_{1ɤ;Dt-<2YXa&ȹ] L5=xPOE srOMDf෯';24ɤUW4|p֛ B,, 2nw]ź寰j*_֕X^qo M,mńm2n.g2s1\]ė)"JޱP51H9iO H3U=ʼTBlx|CFXrQn7vOzD e_beq|֓?Y/@w@^ L-R;ܿ0KH18;`7mVn6TvtÚ^,E{ P[];8¨`{u@^ۍ)Zd[|o<#g,qR3ܻ7 BotЌvUŰ.gl'ա`bSBk7._y뀍{vz2~(tu7P"G:X@OPrq dPa%#gap2a.Uwy,Y{}TDLtg_ }߂,Y E"8tAʂ4P{='`FQxi4>$؞BA]b]u%7t<ت=; "4HP>^@ahnaزsM̀Ә!(,$02qZ){ 28|K wV.wڅ#l1=|0u·(`.#lZu8&SF*e/W`MP ATWC_<۳U|Z_SnZ[ӟUeVޱ1.(Q ִzHh42@M9{ٛ%Լ 27/ w(¸ϰࠕg7Hkܻ0Fѥ[gt ;<8hZyS+FwζflN"YJko.ƚdمQ᧺ge+>cgWrYA~&(Y}PmHK|>&%2ϐs~sL5F-).8)  5>`x+52̣l0*\m]cAhY"=z"|ZЏ,':: SP>k^ǕČ };#W"#YJJ(Kը(oqc"%iPet)/aX6&TC9 V* /b}=D;>ڶuACLȅ"XY"Yٯ/TV(Ee6L)6*gԮ>&5fN TGYnEi\p;nVdʋf8womQ2SrcsjG-DKu:FF!1;>|yz3 ª ௠S;6^JkCh\1֥,@h`6icww%*nS.Owl\[ h *MHJK"t~.#ib.J9h*zY i&<\ccSH@\ ux*F4G3.g@؀;4وGIҒz ܥXDE8!9/7O!B\iS1A" WH-􁒜3p2? P`x"m;=hMtHѪցe{HA 9Z9i(ǑT ż8Y!ad'{T8#,Dl!N5cH5K\g-#e8O?k`s[rrmB ~`; V՝GL)-@\BrȲgkDV!:oˁC](QCu .;EQso Ǵ}n B?פv6Yee$$8IP\JJVFEPXҩ !ȫP!Y%i&a4aVlLxH`$*MfWġ@2zx_@5݆t 5ȕU&; 7`}63zp63-Mu׍HjAunHJA-SC MZejwty"ΠNxKS;Zl|zt t׋-LR_b~Άٟ.tLmdXEz[am+uy*RkPgY6GoLj~X6x$T.s0;o;xf0<԰$PՃg/Ю.|sk2WɱWL4! Jtf^/Ofs]ko?sp1طO+=A8:wFGXṚSĬxS/,,m'`R^6r|ֱ%63 }p/Ay'e>#9qu>l'ZQtzPrO9Y1v>~q]vsڙfCϗU=ndmbS w,RXU>%Vb靏(7ʐj!;]ita>pϪgw߇{D;j$?bVTbsY;*I}\VtZp\DzcEKWHG<[<@sM{hپΓu}grFlO58x %:Զ9^|A6dqW3]4;Hc3ςv܊+F30x?Ӆo\DfVW 0 +dz*Ha)4Z%浕Yj\x?yt=S1!c }ix#u>QJf|qЃz;IÕ#N/=ܸ_Jm,Tg}>3\mQ,9+%=\*R^,+5LQf[.Ga`g>M;0/&XX$\)պ\l$'B$ǖ䂦~;F.y0;+mE\t[ٌy^ٓxE4ƪm#z9%^oS3&~nk*䓩9M7^U60Ruy!g3: 3sնLtZثzD|z="$a}7_7)Hs Lm_vE% ,]s~"kO~S3;tUk)sߔzF?n(V*DG}|3/+k^dnYa̫%$-j^@oY2輟_DĞ|}hpk vɞ).[wqPr`:ƳleS\6Ĩk i _ }vw-6.I^Z8A ihrۻ2Ҋm6E 8͑C?޼ qܨ.{;8l?e#P3GCԺ!ф"YAP֒C#Clԑl_5@b@ьkOg0mH+,͢D.VTq@Ƅ5@|w|jRsmLKZ`|[0r4/'h`OK: km0V#dtL_sZ:R<Ű,O@Xc`D G/b+2KiLǀ1 {$FG}{6E2rQUA]R$5BJJLf =qޑ)Srx4\ %EHy_Vcj`Ӛ-cƮ!{ԼvO!2ʭSh`)߽Z!D3">i-_>[?-:LHѝ$k)rOB[ l~ITFc3%HF?s $ZHz ZEN^>)Jj;Qe(=j$.9BcS8RK߾ӛ)+i[̨p,0"J/6@ݯG>vڃbpeGAw]rCz=r>0-wv%y:)1\ yz˨) [9M\<vS aW]֦grԕxsғMyVDH9Mڀ5T罂Ż|Ueq )oVj<ۑfjws8nDs)zn&2߽rf-6tNԻ(H${=Dq1sQbH i훴yN+@C*"6$2 Pn6g ,8y)buQc =,&׊ra¥"i\\E0,1A#+ҍPS_-N4Li۰M , |< w_J$'I8eħNS2K\ \0a赼ďgBXIس\*WטuX@nҔ! I?crI$)nvI^$NW16qiC@{zb%մ^j$/|.@i۫h ' X 1U" }Vj߾;SHͫv7&Rg;bxؖ6]GK8Gݗ_5[6?Th鹋ӏ.)%"fT۞` <錓,8A )jLcGmܢFĦ>L>H+Npm|1%`ђN_fLZ((2[>1ߙ^${9|kJ@u Uq/uNtf 4ĥ׵&XFpIɫC'ē\I610SÞT{wB%ih83L(bZ~g"2md{ƶvMޜz"cR]ٻ2Ĕ{[M_s:5}e+n.Q^bWHi"n%}&<้ ͭBM4D|U?;w ˚Y k8F#s @IUʼnK2 - &gHJ\Q=z,&2Qexȱ  ňU' J]M~7(}s[n%QH"wYۣ>rklScrB? tfJLI=,3| D}ymQW]-xCZތSUKo\)v(ķe}X45f޳z`Ugj`v.:tvsie@x] PP/AfH5$E: E* fS67ǯbzj-6̀~n嬋ja#~CUI[b܍ɖr _ECҊ#I <൷dsZ_vCsҐl`dAk1?|[{rB-I?!)tI%p0i[{B٧{paנ'ߤ-c*+*0FHT23@Nj>ַ֓8uBDd鼋P"PH2K}[`i[7ur =ÇpB허|/`YE%>狷sWb qYf& bL#^c E{'ML 5!ukrca&T [%e哙-`<ejR>99o9iMPi0NH`b޼p"@XUNkqM MflŤ[Buͣ>ꌶ"YRttM|_z hD}o) BNH0궾~]Ѯl : 9u) fl%26\T041qBɻiIpGV0L{pOtsK6nÀȎz-63q.;ФNsQ/^?CiJ\(N!{rMx5 yR3^)C2T2^3G P15\9(W8W%xBآ I}]_U lK<,a2d*fz`ȎY88Lak6jqF>*7*Q‡O|zXzΊ7rb^;t [@'sqsЖXEΓK =\yH6~H:i!>J|bh2E cq˴$Zf\s&Ƴ[wrvu8aٮm4wjU^[q?5pGWOp郎ִdmC)uXk/yry+VĽǛypE&HxY^1<<4g>GU@Az1IyZN L( >z igʢ#G4{O 0{f\4w[!&O䕋=xNj*QP(+[S;x\\Fvd>UR*;;P+ `Y<&ov5zɐSQ1tEc\8{E}u5&]W]sgLfvXW߰c,;t=/t€ntr%0*09ʹםvFeFܽ@X"L)8Ԗ6TxŸA]RYzoVآ^86VxQ-L7r\:zw}7/E'n>]ߐlG]&W?qwdMuJ4>v@HԞ~gBwd։OCU8(Y_0ܬ)M;ύ("xx(ua_&[I0y"&yj`Zj>X q+%P0&?B'KfjGqz^0EdHZŋ,|j#v'RQ:Q5T㫄]ݤ)`H%^ Dz7`p+XD#2VʷI`1§E%l;{Jo>"&7stD]f~g0P(vA\sO ia7rԭӏ+3`d43p.OT7) \L,\M.Ěҏ:]1̖Ot #Ǭ~uFCqWw||8>^18[(@9K0@F{W(f9:~ 7QNmE7R:?%XY9a'u!u[ QmEU;iJ0rщ#́O,Mje#mʸ ,Dxxɘ/g+ͻ-X M Z(Ōj! c'Řb1tqX,qә=6df=n~2pԽ4i=2o 3g hXHplט6$l$mP $hA0S)\G[O)G^KVe`:u ZvhN+qͳ &~%鮮ZvZZ|ͅ0P-'?Mv0%OBe8IJ_G;APcv5=zW.?"r6 N e  Ң'e|-Wēm2Zk1@tթmL[?DN#0q!귏m]px3MK j^q2yhq1}; q)Af_Lq͎ceӮRǎˬW{۸,JIIm11'xS"R꿎tx7ڕXf_gn'o;wXJn{Z5('ꖈsH+-Y0ϛ 7p3?ȴ$>Zz ^(G#`{H.sHK ࡔ8$Ow- Ehx2Hv :ngk÷![2y4\{)'CA7GYR.xs # P 1Klwt f<֍fYdŧ@[[{ 7_cD nVDe.Q) !s)$4R6!~kwk/ucp65` Qgy:VOJXґXA*ؔyg"Y`Wjt׷"'~kTƷMƈ gslf+O+s*˜Ͳ^h1='^QJx$eR,p67*%Y~ pLZjQcdX<^A?彰1blgSfXHj  sO><`"`,L砊tStOcF5?Y.޳tʊjazMspYqe+ц}d}߇~o ߊBհ]/Aد1D4*PMNX+RrƉ_ޯtqki=6_2]XquCmLg5!LG /bu8\.E@^E|l] ۻq6~Ӱa5-wׯQ.I<~^ͺb#u(=V QnLH5 6L{a!YlX0)Tu--aL~\gMt*=!N])oou"IMGꟅY&q^ka2HD+=A!p, 1rۆmͬqRn>B fL!~&I; ?1Dɦٓ#iJ0sZȲZ-wj m#ƛLΗk҅'؛~i Bhmܫ(Bx"jjF׮>~;uV6_:vknˤbʬZ^fڐ=Qt}0䑞qtEk;8YL F7 SZ/6Їuޞd~Ϥ΄\pq27ws Q&_z[PZLNޮ-u3jݏ(ַ\1x=OP(%"Yj1s=|Qi6P)elăEA) (ƿsddxA;@}F/!Z)Ȣd`T(AT?ObY<8 k/|3&սa yP:!V[nrsm\Zj_6V"Ee∴&L7V;d3VRYbhqєe6q(lTmcpI*lZnʍcY;ɓS3'P)򧚽ÕSfnݵ:sv I(Q~&}~DB'c_@tt!~~_bw]Ac@]AϿO:jykyc,b-!p$ȱ{YDw8 5M s%ΥA7iQ= RC;cbdw0e0R=*TzBl iʿw zO],z~6ZLg3gaVٔa@u[ڔ2"c`Z`gfwpzt ;hA `[CiT.VZjl;@π0N+*$H)Blab!kT73E0^~PB9 T-_ -D'klsl!YfduTJ+ 9c8ޱ,k^?T_T^$yO 10h;{E\J(v>Y@_d`!=YGF-##ȃ~oG қMCl&X52'ӓ h4o p_5ӿ˚Z>M~ɸyGQ7Nf ^U{lx8)A-p|136訵&Y"Р EɑQez(k(Im3/u!)ga` # 2A)MKiCwW Bэk {%Gy:%$u.,no7Wjs{ᒂLsij[ 5LpM4ֈ_>a;O~VaXMS_fht.`(X9TrԐJs7K bx7.ݶs0!Dc;6:0fest::eP' 1"mXD:O[R Pc|XթS22bN]s0XѪpU U3u{sbv:x|F~FMg}2e {8QtxΌW @,L,?hdS+VsN iXYEGD@} L a@p"nn#ԭr6+ڒi1b:mu^:7xC#TGPJs˂e}:" ZC1[#|1>aYALpHez, nt$h ʿ"FmO؜km۶m۶m۶ظc۶_jjz*Hby<9ŋW`MfH(ÿS!u\:;E~1~KƽѭJȌ5υN:C9'υS3G `Q0t*s׆G1T~up6=jTSȴrYWnOrb$֭S+cS^GUr<+)l#ˑ3r`MAM֕-Ws#`[nQh:kGQbgS]nz[l~PZl{o[:ζp|vXD_`lt&|eT^2W¸,{Yv>jԁ`fIpJ/>E-T2 R3OMB|pYEkt>j΋к݃hyޛㅗ>Duqzoi>l= b{,ӣ*ƀVv#M0 N+Rb"AWt~H^S."I9p``5ʭzB1!>h 1xO(y<Y=F$Yd^ƕr"&RABz? 7mpbI 6j$D5(cj% MEtٳ5ۮ|n PzP.-$f3Pݸ3FCb.D c,,JQ-GR:S0 YL!l3`rLvݕ(H*;y ! )Pb9,ZdS\iO=ރ268"3f#jΜp Q`5|uOBv>KLJyXwqY?72Cg4  A.<3GfЋspWQ v2g F(vQ[t e&?U5 fusv绣6i#[&mAwST#[!֨%*V~B]y6[ dB:i5W-!00>,^$[I.Z }ɠ&8t3Z/[/7e'#\r)Kd&& =2h1> 4tӜU9OLBE*W6+?)f`s'JhS<@mye6S97o2J:7;(-(0 Wq UpJ{6 ^T($|"9CkeVv(U^,u:mycTqqM$Z`ܒ?N"]ӧޑK2 UdER_)D偙C8c̚s?({5*| aJQɴj #eD`M1";P6* LkJ[]' x J[n%aLW^P0غvq eBd,S8R'eQW4-f8Oqgh)"[6PqSQ3= G{Ή6WFܢz:Al`1Կ7`A`ܒ#Cm+b 547.a3Y]jkuqVstqOgv|3 { fp4ՎT5[j`vZ"`soF[+o*J-iOjʣ?e;04,&y;N1g} /Gzv(M)2ü&kݣ5={REagbpHjgE*^i"@q 7 040Eȟ~+ l_W)xP>>"#FYc7xDdJy<̍O>7f/dT S)Cukv_ O.^L9g΀ѳ6 s>w W$r"V4I.I[b('ay\.9V!ErEbk[-#_V3|*[(w#oN F>>qhl +^ؿ_9ח?Om&:k,|zEP45(B!TV);nAqCkvdSyk/TJOܶwylՃJVTI6ϿR7[R+ѯr`/Z[Y'-*S-;%_Hl@ ;v>-=^YuCZ|op$stAU%PC&?wHiSGtPqj(I!3d[m(=9ĹweOA&EۍumYtھ3jLʋAqÌߪT+q*(ĈҡƦAt ԃ T7ՒKnD |0UJ~?b\F w<ˡ zck܍ϱi[q9fjC4 fˠDɭQ!3- ;fƙBdS *igL4,tq! ,J$6.`=]&tf;fѼc>;=ֳW84Y?׌7P3"H|JHȺ03/@ u4~BEPc)7k6uPbH$u/P?{`Moh =Sqa6{Ǣg3b\wd qKܡ=\Z=UAq 6'{ 91@x6<:2<eNQ6oYJv6O6oT+u "Iɞ?- *^ j;ȚǮvT-[v v@Ki&2#G%WJ<º,Mi<9*peD8k!0:8^Nx̢4lpzG "Sv]ߔ;d`iڽ\ FdaHEΈZ$ m5=qg YJ<ZVUH|0!vk(i\i4((;Z!.A\߮ P,p3 W?߂Z v4Gb b^~+6QEFǨ-fr'U469bDEَu>jY廒HTTGuPfQse31#{GD|Z al.2 U2B3K ql|a?ǃw>?τvkC.[8sx5@ t~_-a4FEwQ­͐5:ޓmcDŽcT C)XܷX]IDJgKy(b479ЩwyVBzDTvcVvy43^.Fi#+0ِ/l+i;(-L3A\2#:oi (}+|)NR%1Snz֘nk[ʬ`Oj۶JM?fH6ހ L3.1큝fgH )OOɇJyioyǿq2uiWSTl@EoMmuzyԂ ou_8zLc~&R&rXə[I}bD`?98`EE}=|ckv6V<,pEZ@'t@VLWe)`Ƌ+fшU>3T)D`?f~BI *H& |=d|VNbܟon,W֭KV LUI8ELMJч_-I=X6hHDՂ۩;_Ծp$suӕ^W|/grK̚q h"q)iza90lbUx8 l~ʞ`{:ƤXEL<6S i9#%|=lwP\@򋎣]ͬ Q Z͜7wyk``ͶC¶l-mvwg̠z/лPA^΅RK##u/ &4*/8ܬO "TXݴ*vyS#xX-*'Ś!;_[Pmߟ|Dh6cIyN}Q+[j">Tad"<4nqWшAq̌扒D =-@o@wTu,8^k;oDcn_cJfoI=ib".QōqKx xk@ϝ)Ȯ$jG"73Bݰ`J*t1?ًɞKA;B3l``8#!%x4ŏ d깱APa]fLjv $ʨw\|r8Ş)ȲG(:̲+-# P6J%?Lgdhe<29{!Ãݘj%t&  l$Do|g.8l;"VNJýl~$ߜ8PL'z ˴%FЂ>eoG9Aa"Bt%k־8bT2vT6-$S:{2f{0RR>7Ez<,_Ft6Fʼn:3]fĮїt~ufn(|~~M.p잷T `bR] !v)pr*[ ZԫY8-qE⭾N\Cx Z=t唍8ٖoJqZ$z]1 ZEGoψA5^J]j;Ȁ`>g70nx@q#ҔyqMq ^=miA)㣕0]<Ɋ<)[nsS6UCPFb3$ f{8 -::%{]qg{\Q*Zq+bky.VUI1:~8EN;#-høV_.dˍØ5nKB6KmB-'rw.k@h=w.,msjNowAΠ@^wk$YGjgOr #@CA g P{Xt5.d_Fӆ;{A-[*GJz-.sLyENCd.Y=@ tfQ]:Qu[?M^}$Bmk?4ds!3 Nݴ@_KZ1%oֈ  T].@uhZa8@ݐxtf L>N N =*AN5@"̮r7=Fq&B_rWp]mߊs!3T2[hy~ʽkDq0پ)Fi7]-E%f$Gà;3nQPlQypyY03)$_XkslB;Qr"ʍ(QLX4nrnI1 3U :v΢laUWD=>sz BBD߮HWMլS'e!K XXGjE<=2[1 E9 hFJ Cc9G@ 4Uݾ).:JK j<7:6EvzhnWCmmj,.UrQZ`ej)=aТ\Mp*-j-Y ?Mo<",J7IlNʸ"a:< RJΞAUk Q)Tv۱%- 2/" b0ʐ*9BBQͰ|!G2B~3}4˷W:Ԟc);0,m/n)?GZ3@P@8SlmJ0Kظ̿uZ(?nO%nSNVZÍz. ( 04JKpxb%.zftuZ{'I|l ׽64a۷jo8޼#R3һvJX BBIgܓ8­RV(а% w*F2Mi-oi"3u rĶU/mI`h)04g5_0B_9Ch(2 .?t[J_RCz{fG9[5UVetj$K#l 7[hi[_Ejoěa/ԞчV.rҐC..\QO՞\5?osRdW*=[В_XkzC I+k^wLbw>@+D%3CJLw B9āyf2kji`@Ie'ZB BcE;/ޝ*Ȯ)QVkgHߠ6@7s*ꁫ51q:g|Y^"{%$Yh#H{%5ӿ&_vEg M}sI\ʊw2S| {"U{fPDXS?ob/ɪnj2!ԗ/_,sܯÙ_G[.)79 $V<([cM$W@^*1ߍ'x%Re5$E7cJ&֪v($iv3okh!pM خ 'NaC)(}اTCmI)Ѳ/}SbVxaY;W2Zɏ: /[I'>'*vlȟ2i=aboP=l:y$ܿ=E_ d H)V=zJ]rx/!řEFdZ Q;>W۵ʰ+MiYKnYn(JC/U˲ʤWU|AU\׃B?D04lݹ)~ۑd葉4VgI-ZSMoM ʌ?;1*|er Ƥ,9%=,S ̋]47o|Gpns cO/άu;Ӧ3kܴh'yWI$<Hqwu2=&Am3X-!Z֊ҌG_@hj\SK,c[X[ F1X("7,ǯh/,DX-iW0e%ñ,.]]e[X//*Jy/'RƈÞ_6X%62h!fn)Tf ;.fckJz?%ឍFh9 naG ņ@y`J-t;1'Yk?#ل:`%$>ZԳv<ؾ/4w = S~=8.O:5|i͐SsZ9!|R%#;ٍUw?;$AvI c50K1St`uPsrlJ=!-z.9aV>weؘ^] H aN:[0`Dn tX!r~2B2RE(XE.lĕT״S>DPȈq;,%9wjz0 YNBfmoeA0@HʦP[UL$sh8؍pAq]F)MʻTsE(HIXj٥ ɡOޔEиnYE[iiӂW"R؞rG-yCRQT:ծ7Ox fBG!֕G=~ f!Ob~5 ёȾ惹J`!-p/nK ،_\f+@5e6qW;e<pAK` ]i%wrd=Y?rgnFp#rJˉLi-.5SqK팹9giԹ@ς"61ω5tOC- R/ FXKzvAr:Fev7 w^𣶛OFƙ^^e;iwC {C89C,d@4DS 0dLsd|7W"yS't\ݶ=;1l21%Ϫ)ayyqs Q0A27QǓ^FKNSC$o]K<- S}{"Ίofu4\E8^ lo>"tb]čا+ƤYl%'N$Ƃb4NPR$?aj 7uYDCzfDK5` ?ʥÃNg4kB2RM4GHw_(P4^ mH)AT\$8:^R,mE2y/Ft &\CɹBíQJk/v ]QT+h"^$қҎLH;W;3DrۛPFFſ:8c )]!E)l>zA!tvDˋ`~jbj9FrcMG^kx3ONLp4{p%)&+ߤEt tSm~(N~Ѹ8mn-ҿ%B{y?8Z[$J8]9ה"7LH M*/j̳l|/UY\ESY%F"4%ESb z6R{-F^Lw[x.)kj"V:3Y E~%;kxL*6 \"Bz<3לq*ՋO' sAԢwq y\QZfdhvoYCZt 1YE np*$T5u#yeQ᭵ yCMn?7x0E):LVO1.ZdOx݇Owr᷊hB$Mm~S#Y%\=+'|s/xtYd0WZ:db]\3w idѴBXtxS5a1򲥌GJ4MqAbK.G|ʰ4B@aBT}"hGX\v}.xdh߽wp8K@0X bE2BxI!LG,Ut8̍Ed*} wTkYk.ORq]zyY$Z]D'q|v:dd Pxon OGVi_`p5 Y6Æ$ӝ%$n 6^A|m=sݦ؝RehRbQ\]$q^m7Σgz2/(tX+"45iMU𵱵<zeO#q[DY$†0IcVL̈y@Z9Eh'U&oK֜ݸ8yn_$ ?6R@s"̃t\Q TPz'IߛLjZ5rޡo() 31JM~őlLzRO"$Fd"L\Uo2B; 7,4<>I\R'&܂rdIKU?5ZιƼB+A:IaqЯ/ɤQ$Ҝ ׋^T ʕ]57I*rExsx[r0~Kg ;Ŕ& dXiMKIO}( GƗ>7kIҒ|n]޴[}^Ӻ̽ "}7۹?Ʀ؛BYhQu> stream xڔs']-vm۶imN۶=mN۶mv<;޿nTĊڙVΌ]QdDtB&vFvtL܄[Y3TN`Lhdja'XƔAU\M\T?8&f$ekfGsM\j%W㿈vcSBʿ.KhAhJ*Y[(؛ԑPƉΌ `kN(hjJlgfhWԉFBQPRКP`n*B7_U1u76wy mMàgSs47ml?&z'3z[Sg*ʄ̌, /"21L?+'bmo__6k)™R?}'q"؂RΆ++dknmJ_&ze7qqK`lekD_,ӿ?ۙbe翝1t4ÿnEC%ZNH7wNT`;; '!3''! +'!+I7vqt4uU^fuΘ'2-3ݹ#whBT\mc2@hDA, soA+UL&і.o$LCUg QFXI#jp;Kr Rр>Y}O@6v۟P0.U&Q r`Q#gط:_S $3 غ 9`ly8 >3eScjC<ަրG# xFט+ $TŠQC|8;"B\={Ҩh,(tɗթvlHfzz;ZS6"@z ʵX29^)2|PYI16/#ƻy:X(-2}tӼJэHgͧXʛpuk#^kY~Sz`Y^ۺʦr1{yl3v(b֯,osrvYQq[(0?l3s\IOTrDU_?n&6ab%"H }lQ"$ZaZ!{w)2T&%I?YeR΢+p wpe05dV/]7[W`hؤ汞 Pt!Y:td)d-_ ~Y6p3f/վ ʄvXntFx@R$L7Щ#(Vi9` d4d~Bayʩ0#2^  ` mwVnMVҝ=#㟱>$)z^e|E6XcX"vHf"P(u#t8m4i$BEob")(:`SG;-ku WQx$v욳X] N Z3.oQk,ӝqe⨀8+z'?5b)%}[Oӈd3X)ué xD\٠4ԾR>U\%XU* 7RC2GWbG1M0SDD'fmSs:#vit 1#R~LVqvGf9GZ`-מUn_I:`ANMEn(PQF j|qP$0mS7\ܹyR"|opc+K,1*>Q F\NH\9UD[^WjucA i9ffNoxqG"[X$>Wncrly4($Pp]0pFGdQ"X\rBۭ1(>p3q Qv(js;^@"\>Ӳv̑듽roQOptskk,--׽z>1;ly ZzHVN {NY)$Y7vzQ+)[ | G\kIM|%3ϒPm*Eɻ=(lFJV2e 8P;KseAiD|c()ҒrL]9nb|meC5m~=#DC6jcA^wqpeL \3(@C *jsU\GC$".If\V3T Hpw86=>F\Jqhgiߙ1y+ êk.g-|N_6uk @<GdȢ B3hs^|+YQ,\j3JEE 9`K|wvn23(r{J2>v?E[>-'wA+69ti4 o2+dӕuQ,M? aH6!J]tj7myز9Vi ۢno}8#kx脨,ZٵDZqf* ^fʕT*n=DxZ1׌X?:{OKLʖwCY ϲȏbZ8QNxM|0u#gWGYaWNn q;$ih+;N' O9S_"kηNշ}|3vA*լw&&F<M\(zz77'Pz/&&ŞCV= Y!+j *'!ͭޡ [~(gM$/ nPYy_ir 9l,ÍrUьP?j!E.ѭoj䟞 ם卦mS)5͆It3=oJo-& ZwްK*lf G3"L.¡(dPDU >j AO<:z ,O b-ӌلRp˽(W6|:R*r&OqA^T`u[#&X%˘薇J̡>ML POxwׄ7FD%i$z 4B~؞h^0J0! wn uچcwr8tBh}j9HNSM-FE&tyL*W9ؽB5l@|$Ԏ.I`Ql^n9lq) .k!k$<^OEtW4qz+;L!ͯL ISXRV%w8gQuVɒql_QBeG ' })LݒrS076$s3o)И22븛='h!Uб-*=+nNO_Ϊb !f$r9"IlWy_F y>vGʼ _J0% `:;H;՚ҡ^~2;{?P `p6Whzvcg.E],OA HL #W RBgesBm$@7Z8,vbD̨t}#`Fؘk? -hDZ 8vNMb gή4 $5lNe}(;͡ GAXAM.R C~=ù̼G^+3JuS;ʸLy?] |2cK<ߎZa寲:_\6<HRw {63~P1D(cHqA`f9BNoqx"$(ƃY5_>3Ȯ_}z -Y3ŭ4M[rPw5!*W&_8,Cf\ujl@W8~X(qtCM:Fg)!3u߬yOSq՞EH:0+]OW,?ߎJ\ 3 C{ wtXH eż )0.dKYޯA8 ?Q3ȉ"j@:n)ifDVJkDI 8;qkӊ_e>ҍUr pu?ʟ3#\tY/ɭ7;GA;.2+j)@dZ&2Πd0I{>rKʠe8gHs\6X;@u=o8!??mP#n AF+Իym0"",x~*X$H\xʱKsWpU<\bSr_g_1]-n-Q{$q o_\rrRvm]GW5!gS5Je\TTf`K f [IZN8v,ҔrJ1g jvssΪ\ f5'ՄjIYl2X^#-#Fuύ!nj1[-K,J)XoIn,֣b7 ay)aֽn.4LӅ _wܹZvr6Pۻi˃ Dځ")JYbǎPmX$M,.۵ǘN!PdyK-.b݈I qG}Co$+uQ_D:xӀXM 7葺_j.Cx[PZS̳Y`_.%"XsftyW8[GhwC8R\;%"ӡZÉrҡcߋGt#BЫM%ٙo[cAx.+2ɤ4>c`(OJRU1slqF#MoQ{M=>՞)2e{FF렳ȦcLwVaW|u_Iƈ5WgVH-FF{Y" XmUpwU~JG.c=>um/A$8I+Cfɟ%hM#8F \P#6I;|r>V_A?BѠLd}٫xmK9r~; M[WKO]pWܥc+ vnDU"mTg7}I 9Ϣ-7Y@ L:ݬ9;A+W:-O]#}^yv wA Yv`=86L-/|#V+.)6!<4UT Ix:B~7Y(!sLDJ](Ɣ+gDmQk'VMtGغ׫XOI@9͠bנIGQ,}pJ*Įnz%b[# QFU#({Qر$!PJhH^:q7yKf30f)^e;N-pxiyxb +hHR&=@7Rc ,,ns$h%eI1Dx~<9W7!'HcͅvEJ{xOʠx֡KtLїN\ŷcD&%&|n=Hc&{0lZon`k#~{~%2qA@ުB! ol3i: nƺpcW{-GjLyhҲ\r%1T?~5.ܤu@fR|& hbeN[uD QAvX=jh'|Ѯ^YB‚f0?(i m<`} v+v!LlAEA5jUY6pYJvJ@uv5HL*ȕ¼sFb<891FsK%!n(-%y3-`O*(04-i/@e~ER7g{]-/4JSYie7ѷ 0mugVѷ3O4E gu>gu[)0~߄ 'ւ ~{ʷNzĴLJz6tFs1Y(4CD M kcYl:AK ™9ӢCI1Y_g8YYe<[^9Wt9d!# i)ÓjJSBaRߪM ) k1#?ͩ{yrJ}Jo#jթILKPfII]g"{ lqUo뚡NA Ƣy3~JXSD,?ke_U'Hjo^q\Ak&Dbv8vHAeZl1Mx։쬐JX 4[\ϺGS̲qRvG Hjc@ R?8.WR`Mu2nDͪr>ۙ/!H:D$ݓ.FjmQŨ9 !˜UR0쟇:,r d9uײ h1V$uR͜[ǚ7xUF}>3V}t`iǴy]؋B&q YHu` oh'GTo$^mT>U(F7%{)y LemeXe p"ٷҾ{X)$l֮7"pVU)3 XUq; (is1 B"8e͚@:b DI7į#T^,;rEcvOU5=R E-W'eə>A# F၏| z8}SK^j/-W0Bo8UþbGc9;KdqFy>}6ۉ#1r'2I&=A,4 f3g2dpmuR2At%5K0r:ScrCLEC.9^dOTO]MkeM=V@C1%dt;*'½e#M|b 5 {M]unf#F}Ï,Gr $],twꕀѶ'poh-xӺG)PN'u|G^)%=n+Zƀn<ȣ婚ߪ˾ۃzpc?Q#QZ3ܸÖkFhÖBqqRY-jl9qTj3Z fmאҗ$3`h]P.o4LzRc5 M5"bk~XAbzhl7+F65Nܣ6')B(l㘈,vlss'o/(]g ':<q+1KAz gr/K!UvT $]lMҖCǔzG*_*ߗ +âxBioL+wG,MV#eT?6tw5h@aRλXU^N]֊l~J`TpHoQe!lcxXHxpE9ʑ\ JZR,c. ߞ11džk COxp\#%@Ю[Zߗ_c c7yXyFмN`7p\fŠi³!&N;aDg6 !2jcZ Â@,GnΈGI^vt~1L@̮ ZC)(C^(kzp2;*w}nWK}غkœfv2].4WKd[tZ 5wR{dў<j5\ٮ#|Dw󺇓9=5 ӴWYw 58o%D7XB0rM( FW+[ӗ,S)vnE}{ 0Qի;e}Qb1%{&ĉ?QZU%' KPO+n:dazspMtSwT"LN=`[g4^D7@8 j> #%xOUEW9ZEl!Nk}%uX9g,WH)a&$r*'sX+ @ Q?ܛAʂT憄(Cu7zM#b);椓-ܘ`J;Яx2nS"{e j+xÔ='[2Vk1tmZQaϦ+A)y<%76n-46lU/|>IP=! !lV9 ^Ut<Ҙ -5ξڟ=[!uEE>ǿGS Woh?<}Iَ1"]ܗQLW=̲;w/ RѺybUq钓_Z$VblTP.ߥD.+|N}WZҁ&Gdž @x+Mc?Uu&|XuE/Q8UG'ݱYjT0]M^oųr]".Ž dlj$h#l NCaN*p'se96,OPƊӏ$`4],R^5Z3bɹ- z:!zD?q=fgaFUWlc97OGp1O1hY[46$9`FNj]H#~}c_-Om!#.%,~^$̉=QZy/=ðv,G%VﳻAd5)`Pt67jk؎T*͵goח u )TP:Fx }svj7F yCQO;%N)AXdHXg+^7KpBxJsk)gds?/&u+)YguH! J0/l!ApT lG#҆9vONej IU쟒`~r[؅ aJ}P+rAp#78 ŭlxCLU˫b3)8ǠK p|#]54ɔ4E$ >R+|x ؓtiN;bK:a޺LK\݂LxoBtzV|˸0h1;ـjpȷ*gI嫛yd]IX܃n万JND2(.esa/nDs f3-2;{L.즮؀@4^[P){IsX\vÄtIoϫCצ QCYlH" ?b#xnOR!o`eG5dࣆOH@r'.y =ƽ e;HǬؑ;vEkqk C'_{lԨ8E 3Sc o>u$1\D^7tw~-4҃m8]$usd,Hz+y笉!3 a(7MI? e,7+7ڇpθzCs^=^DjuX +עEHFXau`EU=)SBdWCP,4878cjՈ>N};pg-! 4x]PMrhowuBσwLݷ7>V`c#`8BB|Whڼ{}ᙆM5*3Kdu%"Ԩ:#t^PTH l=z(\ǜJC@8V#0F $ U6A_΋0Ed3wx-~(J*7MH/i3SsP֡SՕw:La{196 e;C.47jx9zf ! E.Pک?r.rM$>T9Akaػ0W__?mS(H?XR? DĪ==cH ٮmxW3 *~a[x悧M2Klwl RQ/Rc7A^ݩx^3 hm1_jr!DYA@)a9O"UqQCf⮫}IīEFz=D:Nۙ׸\\Goc>s\ޯ^5Υ \sJ`P)ᱝ~(bm( Jpp`LRHc؍\ m)?G|DӅQ٨*h @뗋]V(A]e8*9B2žLZPWnusFDE_&=8-3k$:(W. BЮjЙ\&C@[8@ m0>Q!CVdSOZtliIҵJᰧCw2j&xQB&B$W 'PnŇi(xNZ^'ӆ4SaŊ˴R하_#u)[9:cʧڨY֊N<-*rQէR<_#),Sh@xsжfU4!nL C{`FUj/Bf*`(R_3O!iHuX88"7=-,۩=<6j}BǁOU;F Og]ɘtו3➹8`IIOp=:Dx  "ߌTkϪ6 u#@ܿWպbi)ǖH~ J@( wv[)~?*Mm |x,/>gqdS>JN!D dɮ4/k&y~GaS{1@ǭ0OnatۗVĉ7R1'~/K{'2sMo $}u GWsJE"{o.1'5~:䁩n3tpK;sa6(I'?bsGǓ㱌gyMS#kLĒƅ<8ub'{)^>K1*F&-J5ӰV vxK!59a5lsLeIQV?VwM݉/ @e=dm2|oO` XYiޢ*0/v]ϹOܧuaze̚eYJJZw>ܦ³ J۬#>R7=GE\j;@ &L,p:7=F,,ȣkngf ?@o_gR Z`bV½VІ11B6=)ہEɱ4zCXKBD g&U_v{y%4"VHHv+x^RL*c`ƗBU4dq#ٴ?:o[k(_oTU |X;JyK#r/B=y F .Zg,ru\7t4-xEkPȲ·y&_xAmK{F$%aMuΌ:`!cJ)0rz94㜾KZe вFF=~ CdΣi]]NԻ;ίT@FVg@KǑSq'ށDZYN&΢ D7Pxj)2ذ>B.f҅ԯ1ce6YOiw ü, ;?RQd'#1^p|,ВpcKTsHwoԗ;:솛69.Ro=8+&=H~2V`lQ1qr*9 m<]^;w0nWV/"Jh TRyBFxE̸tx_C0<ؽhE[|o H ,X) X{6%E?vH)KxSSD暸&NyK9Xha Hüh .? }mTBc82cѶ09cٌ9b ;4/ni_S lDY< , O8ߛ$D@^NNRzv{ !OJfR6IN8mr^إ׶0$Zy"GyH G{KMjSY?M+4m5xznjZkw-f0s|>X_q28 oPh nNn߃s4qߎ钪qUlPޫr9벰*P*}%ᙬ}t~A\6ZĜot6QgHvrFX53r b`Nd˔ߑeFd}Ò\4Gas0ry cW=aʋ ŮE&,`n)(p,m~j//[:a.b+&AWT9d5(U6 !S5оuՋ]$AciVZ>X&a▕j JEZL >Z@ p9P;F,k2!kW~fΔPȡ j8Owc+$4Er&)>SY"a zR?3'FF"Ri2*UshJ$.ɺE |3pٿ*G(a%k'~Stz~9CqTݢ2ŐS(su#$4q=DgЫUԝ;D>/f!H!6hv R}eYޯL؞AbRS]YzeK@)nZ~u'{5Ca ZfcJX6Ϛ aTDs?iz\b mz2q"0 EA$AэGwj% 9_@0.Kǰ3?A]QXZn,*3sd:{"Ok5EpB֏)˱.BqK)-O aJJsjUI=7x2xԊN?@cXL6,/Y fSF%6s.[;LC~/aB-L 1oDjeD&|cfJ\|6 V! C5X [&Z+#-9|[zC8-FϨJ#ʣu\%XwiZC|V ' NiJ!gA";6-騋[Ly[$ܣ[7+HB dӎ]!~I璖9a3./ :ˆ5V뒩sn>a b`)\KvA"^|Ss>dv-|y/6ÃQe<}FA EO6⃷̜)A۵!P:QJ(i<ڬ6RM50qe2y0[u_~ОjQ''0"5vݏ>E*n;C\~K#tdL6w!SqHY'T>Ťx,sB_ Sڅ'yiM>&Lext{UHLW0kV Y換τ 7eegY%^pRmbϰe dA^itAHdC{10a&(r 7@R?LA,(\vpg<lṉA=fYsK2فqeNSjF|$z @T Dw0Ǎfs+ J'Tѩ&F1p.{ iO AP4H+1x3x72PPIl.9JSvϤ`@?.KΆ50&=gC gH dHƹx&fMs0 խꬄ'FvK, !v\Yp_Ku(t[hu݅,"F1ԫ*㭻.f&;5bTJv8&"?1(`۠H3pN>!zϗ.uqG>ϩ@aYpx awC]P0Q;D[lSIѻ'ӮrȺJWl=Pl>.Q)2uA5*EƉ #{B , ɌsXfȄ%BT1 RLSp|ss""ckQfK@t`A"7P=cǏKc$%g66% ܤ8}I[&F$th:/ _>oDt$Z)M d$Gp{#^oNk/Zw jw8d#kN7ȇG@$Z2㒭ѿLVE8Ö/a>Gt BbHwAjG6Udws_q- +BRft2gw7aJqcn[3=ٜ|qd mBKk8㶶LRhy 翅ܧMw2 )XݛF);e0svK: &5`(U+*>qs"Yj>kCMT\o֫%Cn=V;mIŧ//aޛq`^\U;;S1~XNRh xӯa$s(/`aT&HzﶗH'' FH+xͧj`.jխ -}zM( NpHwK2p1-|+IR<;ʡE4\9wHE0&!kפ:8&ҕSƔoʇ]>OKDZSS2ó5軹F MշuqtVwn]< K|kr5ȯ|94!} A9<Ċ(IV{7}3Ku³;CJi `@YB$f ]e깚<;_0L]$dmX) IH#t֡W|[Y[H;x~L)wM&A*V'x\SB 8T%*6F-0 m~ԽQl):#Lb ZZZ)w:GtB( uȘ׽@勐O`թ,ԐyPwU~М-2I"@{vR6ԡ0#w<WSEG!4v`Lb b3{OdH%oe`K䦍5QCJ*-{EZc+oY4) Md4 epmԓΕdU%Ҳ[S:[ Ǹ✼ngF!b?[JOjǮ< jq8in4a7!`BC\UwQq+>˧К/*Wh4Bt --9c7JuQjqQ{P>-Kk`nlw3Vk2]2L^pj+ Zr}}ʩbGޖ[~j)7i-vO5X)[$K:z4#Oft.dxdJF%uTųgt%E)ϗsaϞE5P$*voI}ZU.)7.w1>a%I`S R$vdm#y 99 Y=z$O;=@Be)P7eUK0,[mry9'sz0|nn7#:kuPڶ09ɑ]Vr%6kR 1bTUwV.gތK9[W~P'TfzY]+Oxuø8~wrh B~ y|4)W6>٪Y_ ^*{ЈmI-? GIʥH"LqZ`DY ~>}痧 KY6&@I5<5W+W;[N禸d<|zb`A;ed]~z` JxݷVf$ؒV~ H]Ay4j13m~e-95`GDZsРCK&4Kzz}_Wߕ!=lZ>\05Ugca~M4(4qʚ6u{Boo }[ 9}}ή ]ɗY7POFރ0qFO*$1%mP۹0R>U锏["i¿Vz/~Ӵo8&PGP7C|AMeTU(Rlݸo]%XvgYl2`!<6CRJj OCΟm<(tRO;\oAcl s[ 餅st *oK"[x߇?g濿xv/IYlRlDL M2sGLj3g+Q%C{Iۥ %l1[X>ag7; >u+o%gN#aS_#z.) _]f_E{p7Qz1r| * _ᖧb|ʓ<=ON+cC[I(vkƴ|+:j XV1*OAk,c|k(NZ.js'[ f3.F# 吏Ld52NMou&$,YZ<Iy:UW cn ^ LS ?aImiZw7̐$qhDL"#֨Wbi|pn2%#Vr/94o}W̫|NjЏݲq7P L9Pj7o%k/GDz|}@s ^d$p1=峿( eo h7p ~3?'[i' ?LsO-VfmŲnq[߱ǩ'mƥR#7ϮvTPݏNq%G[m D.t^p܏\`\~?TEo}eĵ?A\a-pqnrTcU"op_?KkKD3%8HdtbQ_# 2M@ႌu_2zmb-֯ wYuJfw߬Yf rcfS(>&,|*EjAǫCQw/;9Bn%nO# Ǵ5'̣N+lWSgQ1=fۨiPj7.-q7[Q:" *B>t R]OS #hqyIF_tzaE_7`û<ے5P< ٦2h2T>Ʉ8BiN$/^@l!SD7߉X儦Q*]PINr)x`ոװk5N,e}W5!͠uG|Z7x?8.0?\':`Mg )Sv:/C$_E! |M-p~o\@WLkHSS yp󝸷9f00}PE$xXcXo70Tb>a ųo΀'?߀Կ%um* pPIȗg[6;SES {^;I.L1 ;~ԍyujE}`eJD{NR讕L/fǵ82` W?XLYm]eXbq}*cbӘǸeɓEħafA(-D ^f7eK8CS󗱿a >T+mʧ*h4BF9$x#iQ<CQ),>>m8LZxdDDkǕp%D{eYV#`-ђ\ʺ1Æ9gϒ} nrёKjNzЙ@J b܊g{QIc~~pu@uX4uNɽ78ue QUoiVǡxV:fL؝hq/u$D:T/FG `ZrZP{YR-"#_Nden^W1-\0)K5qNZAM¶OKT SêGI&-]24Ye:.P7+e1?fq2q}p=&gTHːoJgoSP7? s%c-4`/9[JB'zHi[YA6/scBR(os"G*L3&w΋ԭ/oh"Fq{ `_32%P!T [NrpVfx!oB<SMhHp$s֥AWժ偟@LfrZ}N [D~"qa䔢R<b9q?a,7tkb 4:*諷1Ki"T&@b- 'zn ]S%hڮ;5%*:@CzQQE_M4*~+KB8`{2'JH)Y^-u;_PGi^ vnV\r ޑbJ0AWP>6C5l,] 5ˇR1rGt|~nt^_w_((Y:0Ix&w3xrE$ Z䰬 7u:rLhb6HZ~/Ksv@B88fсswwardD-bd&0"w Ny ?nòΈ]ȼ[">LiIr>,c=?cMoi7x1ȭA\p?s)~$vEΔlGwe#Eu>t%]m` Ds1vо.-(l3\Mg.Vs3Nou 8A`EbFu{Im 2޹3C(|ۦRVGK,j/?wIМl{GYǓHh7pS 6 .v\F9Wو2 Jh3@X[kIUfc$~?yI5+¾s FBJtͻF]"dRlGёPsE mQ[>ynƖ a 2 Ƿq5ټz{Yk/~gЄ楲x|g M)SEhr|^jS4̀Kaߪ5Iap=uy1O{ҞL}'WEE;1aۋ`y`|3^8k W1:K{SMD:2eJFh(z5Q*Q2+<}#ssל/~HX|*kPuLg\Diُ&\xzH0~p@D Xe9zMEp/5 8gq̸j9ϴ?8F j '+@ܳϽuEwة#RcZX$Ef5i_X% ozJ<קqV¶\QvqX=C,5y3۶c }%]cT_*NfrڙրpEW?Bnk R>wQύN9pK*l_᢬ uUu?Îaۉ'y)*mq6alZli澻3ќ޶ڔ7)P3GUniFWܻOiU4P}$,46(㼑k ! (IU,Lf#cH6N;e!e_^n:WjymOR튡LMҸ>a-*L26>'sin,:$ᴑKv#osY7F.d\odYKSlᵃ+7x-Eܪ*:C^S#]!H80?Shu?0DH}a:aF&$-7fU*) '='օ#)"WO0fՄ&dh]̉1`@"dk|SB=vuCV1V<֏!hB\z* g%SeCut񂺿rA`VQcڃ{iGF\}2z)1V;)Y)0%: E["p.yKP=HcC%qD v-fdᅱL:#ӏK͚C1z;zTzM:=R߹< 6 E ~ ۂ6D]X%e;Zt!s컊9mNt3#}ٌҜ~T1qL:1.>?T}=1YXήBRaV7m6Y4o|S !͗GKTT>>(#e8Oߚwq-7R k U~j݋A_MgR( `//xV%'wqysS@t0(PK'C`Aּ(WVOm$Xq;MnfraݵN'(+JfD6}?zAj=xp= U0 w"o~K%Kg0K]7%L`pb(;O4V0lO9!QbD<3&HaLks>!wF%9Xo#7{{xzGQifh;|Ec\ ѭauޮR/C(pAͦY(h5'[\i@ӧiuD {^u+ FbzaeiᅮWc+I4捞o(m838\s<4Xsҙc" ai:}OC%3ߗߛDD8liM_WQMN]cm kҐiuC%Fg ǂ}n2g1ZiHj`%ILgR<@SLhh/'% >v=Y?]|iB1ŷs#ٙ dJ9p=HV;ו6},E8pcm 2&Mx5_yhfY.Kx"/V4H%QzkseLH%+dHÜqѯhH ~H_z!Qm)|sj;ƸƖe pLhb>[CL[!X/Q*WSLU8kaZ6~Aj:~}x¼hqJJqozJ5~t.u/ۣ!f.̓A,9ʠ'E`geHKFNK4s~&Kfb#F!.'z5h̋~ش%(],9-='~ e|VyXn'OZ:氟w&\'ǫ "ʵ՗j0٫b3OO S;bL.XqaojΒ@v>*ZXIff' ZԶpט1yi# 3uպcsYq"FQtF =K,җ$9!~МlOrƓs;<'&k `5&gZ" DJ=)J%բ3eDA;8BJ#$uf\9&kȏree;yɍ H}Ъ$)dgùE;&*S?VG)"eH% oiWt+{& M 2lu[KNP%_ZUoF7Xc503 .uV7=ʿJ.In TΧ?я0{­S7٢Ips|t65fa/ ٫2rv/faZ]@E)[85F+k7mΌr"2(M#U^4y"B+\/m"NmmQ&\p#Αo{:gy]s U ]a?Znз*xP܀g8ʇxRC*уsv5VGֽ H|B|Cb)Do)#z{%EyBdMyYEUduW%qJ qQ2¤f_0yESI`~؜^TM 0֋My D^`6,(d*6x.Lbj#ɁYлF>7;y8K'Zz~J z4PU ΍2Ԟμ  mTL((i-_:3c$ HÎ?|@w] .VK1إf#`w G= :>wnȓ,pt޴̲"9XM.n^R $8n m:- lo.45PBoj $߾f[j-C0NA!:bic) fVؿ_3>6ԈE#ը!-9@0*R <G^O&QM0~.{je 4lpeN}[vy<fÇhtT֖WD%O{nw`8_ue0ĢIkn.kEK4G`LZa8okeO?d f;t|S†YTcSn1 C/h ]ĕuUo3w^`_7Ռ_m[H f+AyұD1.<p<qǁt ^ctg1Ӛ^%v=R'<=Ap5~*Íߡ8+;X9Q @ɖᬙ槱)vޤer饆ԨVd #VT0!ȟygy.,0,R}q .a%>Lv,#'v)མ!EsJViǠŽiV6Zs lIS#h0/2xIxA\exn.aVBWDޠi + BU0mWg^E3 u{cIwДZ tKQ^/0*FʊdlT6tp$~'z 0 *u+z"(~'^@Nn|g4՞u4&[>S~'Fg"bK_ߑGl K`MYg 59ylΥ7\%}Itr&}d$5pe~2G@M_n=P>;ñv r'6X葩wLA!]lͩXfkD N(?",-ranAx늓/>,N @2c^r~8 e%oom t1"$t6֋+W=+\8ݬ -& UGѿMv|$; n53[鍾qmu WhoF9:kMtq$`"bhVP<&w4+p"6#9/Wi@=e8r7WA\k}bk_6aO]Fݹ/vl3f1M] /@a@GHR7ZkYuhUcNP=֬ČJ~ũOG9uD Hpn࿮0"]f(ǍwTFtM )}a5ځgJ%A=Rq1Cf*l9Stx+9IT Q]& xP*+}ޑ8Qեv"Qm;!~ѓൂ<e,*Lw*(N݁S-{ H\z/3hk&߈?@- &ȹ2A3hHÐ(EY{L3XA+~2P06,Il> !?`D<2z=[y46ò8M@ 9kDaX\lH^{*ZN&3[ Z7Yf穈;Z=ytnV 1&W=&pV鬃m!)sQfBr s~ҦEDSbr#ƋJ!5Gv5hx z) -Z7x 5D u.Af%g.avSuF{! G OpQ!ˎ0.-{˅CBԳ|Ȓ*쯋0L},?vu* ԷyܤoQyo;NUIU7(;oWbZU&SC?vBazE֎ަ5"o1@9.uFeoD(2Mkq]0#r[FQ7`gv"s`,$O z $⡐kzo0qZ#Mhwpe`r}S?h;]̝t? ߂3+ O>!;Ė>&itL 2 G/6#1S^،فrܹ<+1Hٲ! u%wA/}}ȴ{Q=#+ >^u[Z{ew_(XN@O,*om͑X6nZoUϜF GG_Is#.8X1K1ÈĚuG@fR$fe£X;͢-áOQ 3Tˣ3¡8 , e‴L rT~sœe8m0YQ/y s`5dxcE%B6Rab26TPƢ&p_t?o헱@ 7ǘ*x0`9m3,~6lK#kD4^6$tH RQ>XB}_]̠SRdV@eؔQ$Ś!beݼ1/gf=}>E_REZxNԆ{k obۙ%jA6Wt?hҔO<#|:\ O6(,]`ڳ65zd%8UMODReŸ݄v}V$%u ީ7v 7il>jՐ wRYI2 7̬l=ΉnT+ۋ+*ia˲q66nd@.\1ն6Tixp\ KkR;?.k3o])r;fa\ENx>͂F i7~FۚĢDqb fji,ZlŵU2鷞k~> f1]vt=L?θxbS[S}qn9D`:J eVYqL]Ezih6c.Ð(Vrl ysD -GzJf{[*r/HU&̝k"e@YMf"e%!lﳜ&!$.-oRȅ{D}ЭX5%*11I;+ch=T,?dSl 0*qS€@ib F܍Z;cg;-ܢ܈jj'v.NX_/ m`kb7GD#!z4 GfdF%6ʆ<\ǹJc7q`Wj;Vd%xdoq4܃[ޚ|v7|D4T nwk2bP{6J/!F8ˣߪA^@[t{%#N0;X*Ř䌅ĆGZOی]wb)GËV {⺗ пkݲKS"{8"C@FH7~zVHn{߷Al 8F贊>AYv܏A&_]:u\8Ba7{XQwn%Pp/_ .e t|h9Co!4&"t.sT[q #2pn 20*ح7dض8G缼^0; DW~c!a^&27qrS|6|DʹEVܼ0kVɖᬙԠT+歸(Oy2;_)QgL1vCT(o+EE1d%p./Fq{_?6Xݮl$@:.߮I\ҌC< IWBsт_ Ճkؗ 4p.eT \6%$Өzbdin7uQ(}~9&kOb rz$aʄ endstream endobj 414 0 obj << /Length1 916 /Length2 29120 /Length3 0 /Length 29793 /Filter /FlateDecode >> stream x|t&-vv:mݱQǶm۶m|{qG1G=k9W՚ QRa676002䬀rVfN.V@3yU# #`lfacW駘2$JhnȦ%fleP[dfdjQ @࿅ƞ%K+[+#@֖N W'+ jd 7wZ$*.FNfș͜y$Ԓf@3'#[uiV.333](/ F8?%%,tqqebB@3]8lB#ǿo7 Y,f'oDmM/24̬,,]_jVVfJV.&'W]0 ڿ տ?RV&6@3ggXf86؛g1r2JFV@UOn/_fky#'+3#33?u?ک8ۘiXcKQD``caqx9}O?_ksbfafdo#:5#ͥ;ghBLR}c:ԊV3XTޒ!^$MF[ؾl\ M͞ W'5[Pq :!C}4X==iB>KC ۰mP\lf XE7fpom8({$[ ,+ 6? -`ъ4HirgʮV4 pkDDf.v# Ώ֘/9<(Gp6a p Jߢ@|/+WAm 4 qk={O\a4 )ns W!kZ+Bﶦ 5&TTCt6zxE'z-&R8P TdH*s%9hfxRE_v 5# ֣O4}e}{DC-"Kأ{ZfxL -#x'U%yYyB_'oi>Ϧ:^'"Vql>#gXFw "KH64}N~|`[0pЭE E{&L3mf8r-~8ka@/}ұDl@T0=UocDJ +8Ar7Ѷt4}h)2[Px7 E)P%qT2ެU@v r5P!o ɭ/84MP微;7,5;fv@mo/&}5`Hfԇuf >QNψBǷ$^;zü J:Y6pvf]h%]fTD发V KKdi" 2 1tC1O4Wd/J@X[*q`͘bv_ĉkq m->{_],a婜0#\u/"\F ' 6ޑa`C2]RHKn/U/y0mHjC@I{to%#D(ӚaC F-a}kbX<=_KWzɰ+H$/Jd_c7kM#A14"sc9SaxAE΋Nj(e9N`T޻~),jemẏUcvhȤ$.Nv}iUyњRQTJ J.ώTM.첕JRrX&ۼr(G7晋>,N$?*L7 A.+91cijW8o Seέor|19;E[nFA(yͶ˦&%".AXK}Clקķv0ojM''f6] jhh#)]/HGk`EphbfT+"ddªR,9aq/"oa݁{b20\wʁ$pGƛIn5,i&z쐸2;rAde"ƺqWpVkcHcR򎤚&?V?vM)I~=-L\x]&3'+n߼*64ZOS~N-4Y@EV+O2 1ڄ,u32g8x:8)8V>z`FO$Lиy1 \IJtZ<\W h%?7\r>J½H-BI_eNƔ%)ƒQݡ-N,Dd:N*Y),f{VQ[Eˑ"L>7I=&[25Ekڟ2 !!z{(p&Hgq .[=zva51 ( eł<Dc?wbwJ$$pñZoɮ'.̈́5rspR:{<G.ZTHM 7(i AnLDB=)8FV'i6|0E s\6V&̦amre\ pjo~P4?¹k(F+F٠xܴUE_y3:7QZ l) p^FZRTѨ.c#BlR+0/~U y[D,zxFޙ~otjŕytvH0GBr(z+u-^-*]eIb.5O {oGGjچ0(@y,8Qzd)Kwh ;![!JLo'T8}6~qz$@V }[8JA_Gc!t]pVHrzAPC~F9푎DғfbXM8#Z9p[Gz6k .- 9>=PL@#ߧ^graLxnb0pVKRR*2pUu|%zœKC#[疦OF+G@,lK-4xWh<EOҌL>r(CxWLkԄmfv ].2Xø4Z *(T-NiIqU_m'CKjKt_jDj9U'PjcQ2{8L=يu֪%5'PܰKvkE\8ʊ%Mi? +zVfm/bg,^͵ nZc J͓34f4PR1Ej{r-:vN0 j3P(ű aNa9k|Ƞx9q3=M5r]o[MFS8IT[(/K<|)& )ar#E\$w*dj,C"0XrTg BQ 9&=pu\? fg`,g!e%-\M'}-ГӏgoԔx:t|ko L,7H+S.AQ-e@f{[̿cVB#dŕ-K,]f>xT!߽AӜl/I=U~"T6Go_1O ht i1n9Ps&։<]f$U5q GdP$D@ԋ%5~g]Y^c-O怭">JX[^p!򌭖B3m>#'#/f]˴t-|%GTlYT5'VWch=saº[4 @wXpۉS}.S >Sdt^>ގ^  8嬧#_:˩2@gm G(]e9vXw%H,Hl[k(XPhG~[odU[qC(fBE9}ӫx "4YoG^/&>^d,)T;k#yHPhex]_h@TVsD{\ww|S)Ys(!ZzPૺVUDO_|$GufmzJz7JPyrev+/U6I?!䫕ܱN%[%᫖g O܍ @s~sy :[gl_-WǸ.<БU L3- fҏtp!ZJkρnr!jt@*&1]S:Ά1Vknl(o&L33gQDj:%% ,TVBcl0dqS+}<\QU#vW -$Vh3lRf 4rzS\= Zn?aE_ƕX{U@Xqg= F%GH1$٬QjCJɼe/ဿ=!Yz7Ev\s*CotzY0R_(FF|a! b)dӼ?$"x:F_sp4ii>9%k,'*mјm~ak_౏N%$bGpRQ޺D׭'Mu#|PJlN@6Zx"?=BWՋ%<<@QrG3%/?-T~I^>%SujR||h7#G8; N_)" S>.C.G M,6W2i X߃_r.: G4a⫰`V ] @Td9EhW1H膪 T)& )B#nN}R3zCKm~)sSU|>c6Yn1f"H}ݬ&||SW֫4Wgx߰ZqjSFR:X˚;k*?7Ԉ%zuA(UL6fO.,G= .%C׸̴3UZmƿϲKjab21³3{6bW`z@biBSfމ=n#b[rBrF@aKDF*HaE * "^w/E- Vgdt:)_фvi(:/ym?¨f~B_3'~nߞxMfT(Sӈ[?5E̊Ǚs>mރDV_ߏ^2:_&)Sai|l i`qm+v w).T٠9?[_m7Nw`55%[\śP >%!sa&0~*!n<4M{9v,}9{qʯ荳Ң_?TXOcZ ʝm py6I{c֝Qhok̤"];K濊h\ U+={$·ytS%p%DU|6SH̬!T[ClےYhw ?נ*d{aPB6cKc]]]^BF }Dv_Igݿ[QCPPgtvNY9:ьuEHƊy\ J6 f㋢Џ0?FjSy+`{Mq['Lnw!ڸP]wM6ihuNK5Ƈ3EH|x9t4Pj>-dcPhMߦh癤E 6(&4h?:yN: 1\PuhG?*51K3ƀ)3\J3VwAز*;ˉ;<#W2Se[aY WCH,A"~;Vo~ߨQJB3J۟M!K(qBrEs/YMDyN* Oo_e?Q*jBe̥ߡh|SHokcDO_#|!8M;>Hԥчw6V6` 7=Uc ,ʼ>2gLIBS9d:O7W:Z0؀I!Gx% P1 guf_gC&+~7ueS!}?u9[iv^:F=Ȁ67.oUzA܉UIU0\$o2H߮ J1 G5V1FvҰHUt.at£)=Jl?iaI_Zk֦T&t `=Fخ֝p J2E*ۛ"UrU$HOBCo9Xf"V+RtzPm>d}kuY $ixǫ2H_T>ˆF*"yr "&GTe5MN?+Ƹ iqzhP}m`ˆCMT7C2-=rT6y/" S#!n]!]`Lmo5UO}OA_\ 4c3ڣ^B0;. C]qbLg;l8z9 S@p2x2^{8lsmH%7.J<5rBz|-UU$>%(E3Ō BYsz) h!r2|G?)b{ KXWVmr WaQ5mU#ѵ@=(?\]LHuf덑%&JfEJ*K9byv%K7vK# MSǿPv[!z0bwD'ikXV&Z(\"ªxmiڴٰm-R3uz.?nɎ.>~Eme| %rb/@=ꑑ 1V9x/ LP->Z!+ ][IZ,;̞aPh5XՂ^}I+C@X4+f:[BM޺Ї: (`C"=2.zuF#b?|k@k6U`@ɺ8t_ZՕ.2ъ~<-T8/[6h/Pô77h-t~|ɀ`a~fb|w^_ xՑCݥv7͕LXƻׄ H'SrvAdmr%9d>2wbB/aq &\ _pY%3c])VBJxQf3a鰒[|xbh;G~-Yojp[2j fɦLV,[#4`Oj1˫_}2= k~<Yu#y,_cvA_!ӳq/FJ <PMʟ2D]M x؊{ADV ~)2PEe6gmO ܈/},fZW*XƖq,Rk yrljrYz* aU9,^w]9Wщ9]$0iIΣCﲅIx!Rڤ3}dԯU"V](#|l]g@.PyA@ܥ{}R%!5ŁZ,Aeg)KfDyM>/BodY[Ib/zh AD!H&!+~cmf&*'}š`|G*3DkJQ֧}Ax6;nuMnD|-f}hf|Y eӟ&h$s ˰@L_;fcFD`CyM(ArCCa5fT,V-&-QgΦؙɩ-"21Ȇ`v`Y(` r=)W}xqߨObjA_rm'="R{+ƚo[Ff]'F7WL`:u DAJDλu ڛ`,+3eqhhu;I Q}A ѯ2rgs >$+IW=jf]QXDZ쭂v cv2 J2"%d+\GD8!ug'ɪdd`BBRBOP__͋99c"h9uC۝=w zcuOܣ4W0 D*d0^B S–^މP,5B.h;Fu__iQNWqD7T9@iNTce] @08a%>;U~jy~J*R̋Xi0<9C/$ l޾3p0aI@X)$AlImy1Z[ߺPzp,$)q6`c;429`bz|Ua,#r3ҲɃh| $oͩ8qUuWW/d<Ƶ~z[dPOC4 /I,oS?z1tÎ$6Dh/)[3 նNɢf)?UAS!ml$4 m 7(DF:BjE#c4"3 XeHvA8/ h"S2=SqwL+/[ykle(J$Hz*emܴ3#bm쯲2:IݓB}Nr?d)߄3UHG4wa(psui}"LBۦǬ/` gJZ%4卒ثuԢgBGn4ݩJ_fv'Iyw. ʓfςu rM^f,+wELwaІy0 B#(v_vuWv2à- iupD8IzԆcj7Wm+_Of:ڋi H boS9KʗqE5 بdW5tCC[#m`=VMChw\"5 Sˑǵ)]&ySY]J`w!;R}䢊S۞h ϲ_2;A`B(,ݨUr;>L/%uߑa͎?6s5~vp>I?>7`!m<.h5op;)65HQA0akSdd8d `4E-W9ܤ#W^bm7pQ"`6{2~ BANqߵ֫&_DksBS)acxY!>e}p(+kݢ'x wW$Hp޺͆Ϻ&2rTO~y#)6h%I2OLځ*'={b܂OBBb|Xwm'X) YXZg`i˩g{ n TBO.Wܲc$(r2nf#qᲾ l(4G+|-b!i=l6wgKnuԆ?kX$Vj;nMC(P͎ B4TAnϚ3r1y; ygY]zT/An}Bxbx4n;d4o1 M2% '8Fhma.w=Nr}V6'Đsk Y^ݪB joa$uZW難`&!x5D]O v*z1<ٌ." |~pwjM(f,|γZPCF g<'- *M%Tl649%Fԉvcz;uY$e\%O1!'6 ap+|]G>W^>g1v3)u"jKCDir*V 2u(QZ })ƃIM;j h&U,]Csܘ)sPwiоd,L1hmzsR#6Lpp|g 6Vx/#]2FqH_󟡡j>_oYN7o Ƴd ˺K#Z^!шǥU@Y lw /'BC_=uMg32?'&8V_PWCei0+CvYl,kzHf`NCrT,Cr?ChQ9}rW+{1Yl?Ot+1rXm,xȩ<j<0TX)tMB;B4Ę-o@|g/Ԟ1+P㸺 y-`ႁPHԔUD|gGZRxH }{fAN_Y73ϐtV#W#{zƽ'tCϷ(#eyG#IMIwcH]l8EUbH:1BԸ zpl4b w4N3eX  Ag2b*1M'$:rms7k*4XpyuZVwujvth*2O stjɷxEE{c-Ӟ2_i@OחO<%?vNR8fkz̈́QUѭT'.SO Jlb$ S)z!p/rG&KK>i)\Ѥ5UCc5'/^j4Fe6MHѩ 2f.y&4( > dFRC܅+(r%-sE&C˸ex{q 0S06cfV.!vj)& YyûJ0vx`CAO_b/(z\&P3AVO1$Opu?'5ɟ ~4#^9WZ{xf(vxhO1D_Ohr3{0^r\3+Ӣ SIJb#)fQq 쪞oCF+h[.»~GJ>) lՕ O^!4miod|$~$4.禴mY~3_,V\`!;6׀4hҶl2fnXyM)93~ی4XXf?LuT@>E⺤;$QDc$j)w&XpylÎƱGߛJpZ̺zB<Ŕ5hԨ@T0G$i4gPPDa)gk`q2<- >dz*XB]K1HP@HOiD`+rI^%q .aRHD?_r͎#.Y,%g3ߡxTؑƉjr^H”}.&'ҭB%O5̒壥_Ey9\UOd,v?F Az"*0'ML/#?*Kwqo|π!zb^/-0 P1YhnY!~4ֶc]>w't{7v\lk>[J"mOK[O {B#-ZMi̜U״ $2Q0B :3jO{g QC,o7&@>Ii[,9:i~>?-뇊Ab"X>GT*Tψ"&^ *L7c,el.dYꐡ WEqKc]^!OkwT~ xtS'xxT3Mf?jXt2Tu:%,1 ->Ox:'(rʄf{XbwOʵ6u|&? @5 ut+Ev~7/BB;Mz™QE|F2!2"UP2㚋j=ݣw 4-Cm?y iO=HIJ/cb03p ~}HLv^ @Xp]罶C[jKfv2Sݘ]pRt̉`Xu]2DI$3Oإ J.d[y1%@Xg9K)ц?}~ь?4I+w NѢeȪ>񴕶 Hַ&=whI` *+5)Uyyn;4 ٍN {_lE)ݔDC "R#~L-,fAM鵗倗HY?$ oQPvZW0iG yԪM/D! nVP~Cd +0M*@M\2E !Uizo昔;)Y5P[#qq w ؞#Ri qϡ~nv$9eCT );_/q9:Thư&YFynI @Tө( )ڥ$FP 33YQqQJwp=;gIQ|"ݻDF.Ø&_l7š2GE#/E%;T] Rݤ(w[㴬8›Za'?+Q.w"*AE|&< JM3?W8핹gӛ@ L}R,Hmaz_uH +ko &`-@w7z˽C-uҁ1^o>ϴNyKԥs}!nwl)wf.OsZ@L*(BtvIyʶQKվ=+zyYpm!–~kWBC˪z 4siZOaŮ_ʶ,QzqiydPmPW'x>sQ<2?ԤD%~…ufJVMAM &'O!^Ua_YDAi4.lZ'(Yl(D(vjxAhhuDur Ԡ/ qR]3E`d9-u]l20:,Q'xX?2K\DIj0g$Zډ7fH8؏B\OZ]:-3kДD2r} naf4 \WG]a18įH[Zq֮y@YxȬ $r{JjCJmV%Jد0 iC*?,Һpdi_RKH՜8Pb3$M![SqwkF#k˛dN>)d?`be[ W*uN{!&ˣj:ґ.i>Lep)7d=I KU?[b@PXHjD#3 kG2AmΌLa j}+:߹'hZ2 $<Ah0Cj9Z2D NUrqń*`,n m%%0LbMɾ-y yk5X.*l!kk3ow;\)L=1%$-;ФywZ%͉o7#2-'(Lj>ތA~P^dqU_D5]Ez4j\=4皷J"6g$qBJht0_/Ŝ=jYC#`i./jpe"ayړ$le9EU(b zuYC@%w| 6;embbνOijtuh&KܩXoY#jkH \5.cӤG'! -եk5ɖH5p.QVީ@}m~V3r~6p3s=/pRwY(U,7s/:Ka-%s^Di1펊h))s4o> 21щkdQ`X:hpw&eםiJTmW^Zjd '1woLW3Nd1'f^ ;J 9<7JfAxVVcy!%}7eF__I]ѧ<-ь?]C! +FrbךM²YyME3V_stU p2X25zniV?K!Kd_^@˜y⬵2&bM< 2%67!kDJ Osp/7vZĐ|ʱyY琭!긄Й&PPF򜊵ض70we%[&!,}2֟B8CK{RLEYE+Z.oa33[S3+]^rèv-U 풭-/lzawƳX`t,O͜&"=A̳Yoece\HZyИ)A@4֟ra,&]yeɩUWdʍ xa~5Sie΋lsi8}|%rDZT8Hc2RiFYCJ\d z-$0+ʭ?ٜ;*=MqOXȴOt{Oٴ.3 &K+{c@P#en4D~S *^;9p""b\ug< ƌ- \ :ֆ7I%F+2[ urаq uHDS㏌ҳ1F YEW؄K >@Ly烐L(9D7:x-4qvC+Vz#*fi6yrL>}q: IU|͌4}f qs$@X\@2K>|*Z{˓jP&.8՛@7q#7S:d L>$S" srG>Kz$ 0EK1'A0FXN`'RKɳҐ'c8lcc+aĀbCM׶Y6H⅊i!\u{mTA)װKC'7Z>Diڋ m K_ "T.b7kOG±13#yBhCt>v\!Ñ^Bd+I43|㐪[R{aTPYuמ\1?1-]wOZbRJ5R=}|vaѻY͗)RJBȇwi7 =ܖ5UL8VM@ "7 -2Y0zdnߜ."ᇍ\-ΎPdyCZBW3J"fffj;EX޹ěj7-NJ'g@sphtif ^AbʿOWф@"vt>6U4@._`lOMijf0 B~gaX@v>S,#[*V%)Ē9PI XACDڈ4i@1b1~E# ZW]$w@xbCNz-u8kL{2^ag Sº8ߜs&sՁz \fkfƣT2m.1rEDCk66d(UB)!؄wG/L|u!jdxexD&E1MÎl5!@!$l?~lfC/yqN]ЇS Dٷ$a-1_H>ڞ5=.S6={Z D܁>N <] j1pV1]R.3&]/ 4$F\>Pٲ8#- AZȳ_59x_z\q[i Bl7d6o{ Ib2V&0uAeAt/gGo!أt!#'UV=Z2,E:Cc fޮbpe,;p߄f_B0hϟ ?Ѵc2e?AP*Pׂ~oy{ i^I}ނAX=WJ.*tY7.=sny^џq>i# iN#PV6qX&f da`C)#:ʭkC)oʥgq@?&Jd&] hc&㾞Eدc=kG&4XO?ʑy;LP&VJA eN Rb|E4"Z/ 299D/ 懥vK7j rO  ڑPV_`CjM#Ld=eU&A.9AEKŽV@Ag%7ݱbhA6fC (rSf2lqD\. 韆b9hyShdoWV`/aІč wH ӭ1ghgBQ%qG `"'](xZjrH2 }, =xQhXw«`C,m'HC sa'[tlTJbJ:!Nhjc9RHMAjQzkpɱu%+^bY^9f9n,:.TK^>GF\Fˠ 1,M1cL˓BuȐt>_6+}5|=XL٧d9WPލB2TOƮNҵ,9RǨE8Jvq=b6فh 47$JQ٩iKVv%kE+8et/

G_+^_QP;<= uD(ɿT9т]UrgU[ zv/ DZM9r\r9w^wf֖B(39dHI \kر:DI >̡xYQIpeq,&-koRT}M3F9 ɇR5s{,Jl^)Dr(OsIo#:+.o<+Qvߔd'e`[Ju.$&7%G񍉪/dS$dr$7:8ܭx@\G8>-FaM-%q'eۻPYHHk Ukne~4M-vʑho1E 5 8@LV3_"')(5i򀝑55Ove`n=]Å}Z鰸.k4P(pʤ}FGc?ĝ\K^Y3yKTG~[ Zщw#*$CA5;Sv5kR88#¸CS|@RURT~H rր,V'5I#\B>^N ,ʍ)8=emNEzƲ3@$5V1Z)NrOp3kʪ&@x#C\- 氭қ*e/_ K1-jCׇCHW%X;yyp-6XCn7c~ֺ Pk}Jn_C)Mg%'ȭ  MFg)7K;Q3JKwlf9*?_r$6CSR#֭<@*iF=5s7kHhođ욿}A!!s}nD#$A4 ~w Q|E,UW^ zeR@盵/iyE/ SL^e _+yKG6IJ%K]E_Ƭ~{ù3+3͖"o>6 {nzE(aKTHjį.!1%_X›NY%QFgE/gzwRݗVW~D}>{x=!5grbR7"7p'}&(ih_>)Pk6"4 ndcߊ)1$G{y3۴0aj Q[8_XӔᨄNSB j 2IӸ),0 &eWEy첢V1a`g/կ uWؑ|kDى̊sye ibY5 vR]pwc7a#\rElWqPb7jA^ZG馠 EGm={~U6Nscdm]Vo_1M\3/,1LVsەytV 9ӥ~]4,ͫNbX@S>wLz}EW-S|j3%a)*mbX=-ەRD:>*KT)Ƀ,?0Q5'6a]e >**5a50K_rlˤqREdT3IMl}ݍ}q+\|pȔ-_$4j٨>FTLOYR_fdFJ:x F8Qk:|dz~#:41sKLZ6- {#дCx@>}gz 5 o;DEh, y5sA)NRe}rZ\s0y]IҠk-$uwgّ//9$l[!2܎M5bݛg4\W2XcPݕp3nX3Qf=c"m0JZ\Y߰劻}› V+і0lX~dmCVWe%j![CszM~M  ׄwl0l.-xw0W=ڃ‹̦CΰJEVz}/Ӳf^ĠaP`~B Rs0R)4ߖ%Z8[*K8oQHՃܥH-=0Uu~>6v4$hWv0xbytzhlEgB&]SzѓH2!ZJ#QFT3Sk傥OyUփwW+Jd r_:Q&1I&EQر'XJ#L0J|CF^-Rq bwζ!v <`az GsǣMpkK>DpiYdK`…ŗ88c{[̦n,ސ 0~j%hן5x;Qq ե2r60raͬoIޜK:+U="=6?jAdbMNȱTcePMYn?8N !ڝ0(FAׄo!Q 7j0MR4K0/lz9=R &89EaMwQ3򛃊,狋;޸9ed]z̷xh0N ~}ӕMh%vuWcqBL bQ{Np Y &2Y{ 6SlwsX*0Y! 8s{YBep~X[Z&=LQ+v܉X:L5^XuW$?&g;$;m(C+ j8eQVݳ%3֗U*-AQ{6AO|^%VSa2oRšA055Rm zxS 0H: KuMTf?W>>i[Wy*al/ܟԅڿVmkxۺ Va˜zkMC{WP;+QuyFZ9机+.ۑԞ&p DY*!Ɛ.8wt4S aDIvuiD̒-XwX' ;drsqF]Rk0Csf}]%?ӓ"s(Ms,;\o—O1ӕP׭f )-x !lc9]G;*@Mu^812\R%KDiFHVJ'LOpÙ);8?eg`r8> <z7ס/#gmM5pq㛺%۾%E0,3s\FԵUGQO a^D%o?jGzw*C.}Σ,_^ ؐH$USށ>fTH^)wZϧbYC06ydȊ(O q^ZJL.Ez/b ϖ/ObþK#FpK/ P(+ tM֋@kB\X,Yr#v#ώ?a~VjU)zֱ79!Oa{^2&EgIhr6[GgfiIg EzF Պ*zdymo-4 qRQ}u؜$'?,/;f=si$Ⱥ([0zN5C D ooV5´_;)ƭֵu=[=3[diл"_7u&NM}T}>(U RākBL%Vֿ`i#`u1LUoR1)ɟ}<ྀ+;t Ejeju)#–[aj܀D;g R"=^okvF/D.]M~Fߏ]\Qߧ3Wbtɧ}7jBF?"f:Ĵv/5ϱwa9&*̻_ nVWJ؎@צߒsuNC٢>}?꭫弪/1 @u-:oeI w6$ȽA|*nٸZOtVGڑ_h{f6lKb)b4stpnVki9."&EGGe endstream endobj 416 0 obj << /Length1 1748 /Length2 108730 /Length3 0 /Length 108718 /Filter /FlateDecode >> stream xڤpfݶ6[tc۶ѱm۶ӱm۶u=NުQk1|3Z^9E~#ckGZzND?&aHTm97w3"-mc q0988\00hc 1([[[;غٛ9+_ rf涶1Z%emdmdl'`jbnm 76(ژ8 mhl`oaD9'Ks").fa"R/޽?759:r_#&Ǝg?43Qe,[ֿ-ߖoew0Pl\_gddoS՟90 Ʀ0tRr50Mq/ho ФgוFl- .oe WS֐wU # ` agg0X ,(ofD_&6$nd!k߲{$?E0KZ,ߒ3ʿ]1EWF97e/Kw(ZM3/ZG:YZS"VnC_wAHiW(Vq0BR237im`G4?,ֆ6FRO 5״&36v56YY1 xv99,4 YdʺUv:UG}E~>]`AqxdK bsSiՃI\$^<2"CLx"îU("^崶wJ%4'4S_<(ϣ#d0nFūbiTADsקU`;؄ڼY=3g؉ Wm5koRRw m9.bPMc>A'Y͵ zeٮW". c 6?6aCT)@ ` 6#.Z<1g(Cgk jd_ P,Yַ24 ಇ Ne@q86Σ;:d.g'4ɵ4%`j.D9$4B@f _]Wq2ۑx)և&.aR0@TZL/2 YF{>jC IL 2LA&ΓFb\ 6e7%U]r&i3~;b&I (KviYP괈WԳvxNH7_K4\Lrv+raY6ՇZn_e@;Ԗfi{N-v)QsZ ۾1@9йƍzbvS@ӕno;[U]߾ ?Dԋ}Bm'v}Uj3-*+Ѻ KLDi-ߛ`ZgUN\vR(V3 08#XD^oіDÙ٥_ 3I7.buÚ 6(]'嚅Ԟf-7&"+-g SKBQ'<}ֵ ^k" Jt\6.SyX(hŊF~ȵD*_^ 4ķ5ls ^^Hk969^sf@hd#Ly'?j*)+Ȣ"4)%OmF+5o~p̈gYgzT5жL8RְgB"ޙ1BD6)=%ͣe xR8w=L]?DbIYr5qp/ ~k_h;[RzXϼ=W8K9[g;hE5K3<}4 IqoOh>76ʹpryˈ%ۚ3.Va$|00ǛIuiP*gJx;L4@VWOA͂-(uapRbC@!8~RD))ӘǼ*{/mEXC ;#RηDtN1針wC22g1΍G'/c2HU0)>6nUA~ Loӻ! ={^[[dˎÏk-N=LH!R(*Q*ìT2 ~XYUH a7}'ͳBǭm5 ΉZXBIQh98l=VqZpK FAm-[zWʳ~2R[ #lR ЃFReg0z_C1d{鉹\ˈQX ; `)%Vw%6Æպ%͉r>FF!'zhuT JT`esT>fuaO=n)yCy㣆B;MĕAMtH3 +fd7-d4 <,DسG4ҥ?Dud W

RxV@pivhX9Pט(,Nп)zS| H> 걱P{z9(QV.<~zikE8EΗt#"$t*|D~%doJk@8Eb!i%|csa̍qmD.' shA]U'S8jWefuhaRO= "#q9RSN<UV.MaLܕ4<,T&"{[e~_b ;#d,Dd77e;@ggr V@h [xW oi.Fl3)U/6pf#龙-Ww_]jp {R΍yUp9.Cu#8x[*-'DB&&%>{7H; Nr&&ֈb^|z@%f%P{.46^0,B~Qu~5n.#0O,Byib=5 MD/_L":ݒ{Hk&&Fk]LI&0KGw NU@*)(-Wt,Dv|lYNo6gQ2[ԑӶzO ^Er7gSd]\S,ʉn ۧ-([1JvlG@a hejVjʂ"c'(>FT I%,Nt)i˛lkf]hE].Jê|S'c L2xJq3VsL[Zr\F'3C7FE iP%77yKd}ů_3^UX9KA!)Կxՠu}zJ R2!,;? qNO~ْzXgۈ`xL`EE^@TNg~`Uk,̓5ZaOAnbvoGॳ AD.icG+;2qXQ8 @)L|8:t O~F۴Wfd275}.*x*{ME3F[GIo" _FyS#}؄eCm 9'6n8"pS}&g;BC 3@ܵ:$<'_QLo]ܙ~;uv+,Ep\l64 7MEUXՅ Q_;S9]l?y^J0zaPU#63xaв EPuIkۊFDLx UC۴?z5;?KR"Zʼn6M7FgS0TcpprI`۲0^&>HW"@4'ݒR!ikNN"BC&Vfc 3d1, 2]Z^{Ҁ@f9u]CxH ۻ3J]O6Sp̈́Xzo< 2QPvT vT~ @N@sb2WWO 3 LbcqL];IZ *ry'UE޹i=W^Kbzj *p 7I"dNULNYwha}d'_LfM^z4ӳJJ4#%Ot/" FH\DxMp-߲YG;JΝ<Ѕ.lߴUeuVr/'|zΨ0/XJev{; =4" 'HٺB>#،_*ms@_1 sOAF Ȩy`]'"K+>c5DEN u0փR-q5]`} [ܧY6YfFA5,'Wu8#gP 3E~~I`.o 4){AM3eI1i@;v^(AiVPk<>Vrge*m|+F7b.S؊_#K1(ղ)A *0 ,"JKсK^#*BhmB^m,*^JVfF]/iZKH7iUJ=Ny F%m8/ZTT`{qѲnF/2OAЇ.pFc_#}`>v{L\x{\O+a!؛ tu-6佥߁D L9P?ۯZ:xq'OG^//!^->+*p3{6D u#hn Srm!O[纔poDZY;"ٚ>Eh?fÑCg+PС2~SGhB/J:ʓ/@oOEi?)n9Xc Mp4ujy áw={HG+(<?Bl\b~4A&{)aLS"ґr4@<})ρJ w 3.&5D3뤬4vLZȔ Bȯ[ 6À y᭟zA1@E4Z <?"K[ L ̳ k;rRO'ssU&N]4vU|ŠizaR6;)FEu@>Y`9d#r٫Lizs֩_nݘzdհ̅rv00Ћϯ6[5EeU`5]q)402,II`EU&-R3`tXګtZй:ЛPZ>j4b[ j}=\(x"+(A}0}PH 'w̗,h"֠SJ9C=|⋘_hYWp N 6t)`X\(/^?c ;Wgu<ŎU<1}QfI?΅X;FhCg\xɑ%ɴvPM,V$-|EI0ؾIZ%,nqX"z^ m9OLk#tY' 2#IlWMF&G%SE? 'FZ7& 8[pBM\ #DQ6TZW2 nY$9*x(LK&3,՜> p<  ; VގdOȠb /H6|cܪ,,&lyYY<_úii e:?_ܘU>.{{hq 9I7Ff ]BcǤ 㸞oqCPoPzjS {Po^;f|B/,aOሎz8?(6:^pD? ]ˌgY<:)Ln])ql="b$p,Τ0=*W ~>9'L#N$6jSz-;uYu*Z YU.T8irQyS:ET=7bH` >xL Ohm.kQH&0rDXƈpFr&q׋pKu_3kzvV|IyL Y=1sQܖ(%5Vݘr@b20NRcFir{0~U6i)Q\{nv޵ ZΤʫsgx`n!b^2Df-p?}ÿ(W2;? Sfw ;fҥ[FtIa;j5?RI3&b:8n$40udYg[o'Ÿä6=:+lӾhܾ!"t?LE~P?Lw/W aCJb?+(TQ:х\ KVR3OvQK|GG$Lq]cbfSMuϬE6ß*4w{mrYIaT(/=*5_ޘ7s:;Й]ܻ}\"k!ӣiOuy<<}gEg%}ޯ*L乬תl#>- *5΃N UF)#~ddR`t=^:!{_(Neǖ˖[`oф9h$ oY / ".Qm.-1KT;J%e_B,]W 6D_wtDh >mPI\(o00Ă<8@`ko6f]$?]yJ,S蕘X.ɹ1ЯY_~!a<(hq4uT0b 6O‚c{*Ъm< Y=rK s]l㣨[FTN񨽗dOlN%HB o%(Ӑyj8\ Ónhaɂ/_bi}Ijn:WWxgᄰ J>&L 窽R ܷ8%ٮ4T :b;\/fXC4] u U}V0$IdtvM2ôSuV4+e=uj\߫I{5M4E Pk' "etB'x5X[Oi !50fQ9zZ8NW `6Y VFL)yc4.37DJϴhWyZf/CG78uhyjeԨpu{U>9>%IРyeÛe] MM( q|~1a Hc,v=&ƘZ@"fٙO\Ydˉ7e-NIw7#[JbܰhLry$iMTJMG]]&v E/80+hS`q?eީYjW/]yڧiqJz?dz{6/qJGŌ7Y6XZɷˉL摓YvxWNjF3+ݶaiufOR0=yud}Y;\YU Qw 0+s]p#|2JrH^4~Wc91^CPy"*@IHoGḰйccg5HE~u2hT7{}_rU谪a|}= h62;>sG[Z"*cȸ(vo|8h!_k" 4'G2( J&P^ͼo,`Ou+'ۊJ(Ka|gilSይׁM*V3U)]EDY%߫2؈wsYaT MNt!'ՆYܑA#@fgkZ/OY ^%!3e5{Dz ݋ S{dtr3JH护aK}3&3Aa0ZƎh΃zwh1Ls1֖Aģ`  RLy 왠\/$ˬ.It&- Q5sb`M'3̼P6%/ JTt$NȂ 64G0N<WꂀM;= ְ5Vi0t)`L-Snoqp CY/p;]6:jD9 ,H5>VKwlGS& at/-LV`1jɿoH#}M~H0\?Gg14o`*K!텺&IYp$L(K !D vMpRߺqɻm75&Ui#&Z ql)dTƷl°DZ(ZhPzRsL9tOH=6\)zu,yiaQ1mt_̱[QbEQCoZ԰a^e#@^b3 º`c#c0KE@7^7coW__&Wli<"~ٛ#r0[pvBE9᯹usbHs*W&<)l=sp!>fﮥlzoO؍ =% M_`ZwUWer(B8f}>ExM @unFV9y`Kֵ痠@, J[ =dKoÏ6G*f[b>wPv |Ej@3|l~@K+vPPuр5eij]}|}!焥 ն;RZo<hbPPz;&U+jZ$uhԜ4OJPj '^84EA~W}=BP3r7QFLdl#DϞwUIbNd&V ԡd0T"CB*9r53aGNQVp#_;%*lv嶉1v Fjyl[Wk*?V/ V&wq`#{>aRL ''NZ3Dv3ƞqC߯8V`i\s.3W)Kʹ[b좭3蝫UW$(=U|E9Ǡ*h+ XdnRk>bѮs|x7카T$v&3@ ? S_7ZQ[p/\'Gfr n?X J8`>'+X9};u Ջ\?QI@&l0ϚAnT1);:~OtkR[;-=)0 gUw<ެ p)HވY~>]KU3J`ࢷt=r/(\rF_WVgQXUzi >Ò~NDr 2 ^A*-v5Dcd^&YT :3l=kb&RF12BN?IHP 2s)u/`lj *<:|pVA,V$q+qu8yU,$##;y~!?8Ow6?B; T4˭Dd\~t<*wmrSϤQ0-xV_Y8 B<,fS 0c.qjK*&Y4["3-.s X vM ܩ@ Hx4&D/ɣnc"W?pc#dmx:zEqOE/Aw"oe(\ŵB< 6)5uw;̳D TY+OpU4*P M|D-hTta[Ew.L'e`4IKMj'4L$[` iз2Q `X8ٷxyPj S#96t*ڮ$ƽD,)AEzVhIH=1k챩P5{3u:u3/@,T3M0Na"1 {zHC):ӷMR! &vlŖa çͩI,VuotpCI"G!%', %EmЮ K=7x S5iE@r,!xP7)vorGhZXp>^o`C+Ր'[{ga @Dl CV2*õEhD*%Je{DؿwP+sDa|T ^VM.h+.ۗpοPm9PtpѶwք[`a#_IjRA o r/$"`iVNhX*> vWxgEh0?}D8,HX!$58s3)0yw^P9*]xTl(9WPFUO8NvPF_Xvmӏ2Yҳ "Hdv Zx^6@/o ^ S7m@V` C(gi2!:vـg$C5%զWbkowҌrV4ycfqeY{=NT֡ PdDyyyx76=,#O`XG߸*G/`7w?L!@>Baeޖq+LWV57ϸt*64ok0y!se+coȬ7UDJj~ZczD]@%DU4WMU3Xn^ 1ak(ގrOCHGn۪<=4liis*p4kW>PRr:>0ë+hbHuuJ 1$emDTǸn<9_]~$XF@Qh_-P.,: 0hv+O?MuO"Dk)x>$噾1hP$X^tzDYٱvYZDN'/m+dU/TQh]$m#s)<.DG硛f'\/ñak5-i"M$X}*E]EK3C db]ֻ-VA=tAvWq Y17m[ %׺@裮}c)&<'qHU$AafTru|ʑ\Yn뫮2b"W &{[f.47] уL)Q/M0FDZȀx>E'li7Q$RU7;>l{Q&۲r**sEmp NR 8`!D\c)}ʿ~C߃ XW,l9YZUg\HCjuDT {ΧׁGɖj"]N6;x/'؅P۫H-T/0.:jOqfsd*G'DW:[㼐M,*ʌ8 @Aq;#no-fSh(3 IAfJ~}8F`ҧ,4p#Y T r2'|pNSi5Ƞ2|_Y˅UkFOjw39p-BhVC) zದYK~ Ũbi0G$&G2y⇿.3TԃrvT%mazUw]6Ƃ*\[D3i=%VUf6B͔وpviPOn%$_#5EcpVw)܍hJ 1FU\rAkJ]--̦Nr˰;^fJ`f2(EQtI-%m-@V) yR}3ۢ]فNJA8Mf|k6Hļp}{YpzObWQW((ww283 <#DjnKAgvBESb( 䴗lbF;K&&J1 у נ=LwCѡ\o㼬3>u*~hb}\ĥz!mPPFS@yfd Q7iӁ)6-`/҂<%i>\Gݠ\S4zDOya^—֫VmR>Kո気W(!M*ބf~oF6R: Sj+c8%aȎm۶m۶m۶m۶m?cW[?T*;I+Ht.z~P:;aB2Vt-?ǐf`aKpdpSt%;D.J+`}uJU.d8Ѹ`8Rm[Nx&H9?\*i7O|Vezeb23M]*||mt(@de1.$ȘմQ-o&`re`qytIcAiMjypb(7/r "PYfaN*'<-M}cfaR+ ^m_:YDRQPM&>vk&@GûO3*P;ČG~QV)E*q mfo BQ]P9hcΈ1 ?HQ#pdle IƧvpQ~(n|Us\ p֞SeC.߾04Q#^:= "w1e躲R ۗ(!ģJTG\RY{4%Q:#`eyܕ"BB{Qz|bND{  QrW]y`Yil4۹tDuF'ݶ @:Cj% mי;ܢh[SM"غVt@>m,* !cB SCB7o~Ǩ';C:Q`*$ii+;Zq gօ\6C}}m k]'t#hr2#J74jQho T %|Z7Kss L5([j"uf9pKn%4 .Ā(;ݶ#~lGb[Cɂ IޖUoӶz:2"n"5Im1R~\PCg9"tEwFLj~wU[wSжma}Us}KJ]"Hu,',<[Hn;m-7r"ڙS8k7)_qd`'d%1* e ̖#ô9%m0׹uEyn&tǧ oh$KgB]SPw:>o X>l87G3t#)Nl=Y_SZE7|P{۷|>ҧnqmgNJrR9gSx9yy9:Z; qGInl-}Ү3!|Ϧ̄M`G>HVghfo>DI7^zl<{n57ؒ6%AkIFPvlŹqJpI88` T $@YUkllsOإzЈY[c%(HϨ1)b2\ @޸|_oUBv9m\i~y!c0Fh򯡆޽O F]aݠ? Y<6Yup|=rWW1 ="K%6AEgq~t!Tf:hw S`k;%i5]=G)]{?T9 _W36 Tt0M3S3zoByg^a 9'}R@R. ?ɒ"$ӥG1 C HqoEi8&' &O43YpJ"Өt*/lPsPλ!"4yicSbp(-4k-޾[U?~GU=U Q !%?Л 9`)J (Ie;+E1_DF8~]tֈd)}mbECuwF4W,A9q~N9=ŀHduq:eTF"g0`d$ [zH[ъ]Gi:_(Mۥ1|̑#{ݯ[,C'?"X.V":P0Z ~m"xE@xcEP0lWR 싘{X^p.IIKEOK2-s]oCmMG0B(`Oݍ{UB"rl>83M"Fu%֟ ~As|&:_29c;I.`jhbFLY| +%$\M^*.RJޣHuS @^`[F㚾ƭ>z횲'\1jX0x qb22>25=1dElBЧ(gljs 05%,y ꚛ"bLHc%}'͵l*Om({[&h: e19c '!n/0䊒qlSB阏<耙ĿE*dfH>/ ~A),ޡkMRd%m7C˻&Lv`PҒBEt_2tRۢ~-*8 8p^0ɿ>EC Vۨ3nt!ZITr6}$(L i:j""D>'yE%d3wnSK @>:G!Y H԰QLխȺ4.k~)`Oe Ҫ^.|n emU s ]"94SleZT2Odbsk%F Q5PR-⒮hzPR7!9Y6((GvvKÌȊK}7+5G|v:ed&"f+rSj`WnJk]],.1M^Q#T^HO#59yU(C}Hٚݶzt'S 繅i@u@<6C*9ҮNC u7Uۼ6X!'YS ׶&6*x9xs͕hq85\f2O$yH/h+`Q_jBNpxFjo x\wlZ!-o .nԄ++& ܾl鋚-FK'"$ݵa|\E#iE< NilklC;"'C$woEOmŋ<:Я|R f ~/ 2lcLN}WGTn~Qj:Gdn5\A:4F<&—*d@Hc"e]v}֕<ǐYTr \[5R?y 1{9h9m󧤒D ?dDYdj#5= ܜ?o@#CSd7x1ŝ~~v#%8"b &"Pݽ HrbMdJ;',ж=-$cH8^RIP[^(tBE El[)|oөT.ŊD[1bO `r'1lx/uQu麙%? EmЖuJ oezEr`셴[zǧ;f*k?SbB1:/H k^(q`t_.~J0wiQIpQ r=qyBRᢣe~}թƓYj0+G9E˳tINң1V2u;{~Wz >TܸMt IoAW862}?([p.cЅR?@mj/eaOmrJɳD0Y5]:VpV 6,AD'ɬՆ=mmƥ }=MoyӹfDY\X5Zv IBdB#ǝYV!~0*qqB]N'iQDȸTx(=-k3yexs0ӟ#S~Ftl.RU8>/ &|-ۋ+ NJ~^-"~^UB6ܰS)S=ޯlB.R1~ FOMFKV\aŸ8¶:>Eo_v-!tk=zg@A2~`7`{ރTcNm Ppp}zK3 TL\jMUhOǻkDQF~-XSN9ϼ#q 8, Q(Dĭe`|3֠1׫ ɚɥʁEkmԊ} )j+jjwR NioWe yoo@ ߯"EXIذN;ۻ$B릌 ~w<&y.ʋF5ހ:.7;vUGւJ*sC-ΦB`./pp5qU%)zK^ELxV` | l: O@4$p arm`nͫTW!ؼ)E'%cei8Ѣ\4KB]~2Qsqؔh-㘜eҋ /V\GU>p~. x7_فY@o1y/;C ԇ"W$J.}=<5:a{@+P ה!/CRr:<.GO+%tǦ hۊ~Ӎ(At9njB6>{@fᵰ$[! gWw;>$#值C, \΍=9͗TWXw-˴00ro߻M,zTD@ܭ-䭯K7j&;{7B*>(,ge|r7U[^PW{͛bw5CI*QcT ךr {! kڝl+@_R^Lo <}g%  Bܱ1sٟ [Jd&_d^j#l\R! Q39ɠf[@u-H⟗7UszH>$/L?8C 2d)Rv]XrG̡7?vdJ8ا/2hc;`D㌤j>skX{mRǛ0hh`:}Ha >'.9i_[xP7zW%X|hrkĶ\X/T`}ޫuBs DPp"d71j^p(gʖ!\y#Ȼh.ac+`dƾ`.H^e|NN=_ BVw +XB0,"')?+:w~牕:Jbr )`D EfJֈOqQS ?c34A0-jؗiC `-PAza$hEF@9=6t 0bU݈@TRZbӞ5䳊)ݪz5@- h'SĪU}D?MSw ]'k_an_;,`"h$,-9wQ2TIZnE.RꞋ$RN\y\,~]: BhqɒQqmw&CYApar,e:خS w:Y'*RޖBT(\dc˝!wˋ^"%T}ܝ2zH_0cO!eQ^©va(o{75r1 Dbm:Ik(qLjAdUrk}:O0fb8Qɥ"s%@g2$ v"&cS]e~Ѯ}OD{D;UEx"Ener86ĕ>skj|%c5Q)8Z-ϛtf͌ŘK7N~Ú)\7Ռ(D%cGzt>!Lyu>W3UY'Zbki{' P(*C$ut&v,_"rxi&ZANM?%+> \SoxfThAyLew)bFi鎥xjQ?T8[7(!l? eFG\y)#/RxTAP 6EDB lhA xkϯC'|A5ɎeF}Qe zD ϻTҭ_LIxRy~cv0r Gj"NPo5!SևR/ew53&@-nh~߃0;:3a<(_NlEtD'F[ْvx3ӿ"#Hb5"~'"0NB?XkTyX7}ObPC^..o.wiV,O6dxhmĈjމcw3!IB ,E=1i!Ó_ 90̪ǃF٬a]vXygg9VWMoVHU3/(ٙ$̯1/':<G[ga΍$5@DIݪս+*@:`͡6wy"hnt8Y kbJ)7Nߍl4CH1u!UWqaȠ?L]&SЄsSDdZ kzF‡4]j=Б'T]4ӑ NOgpY{i> 3G{My gK͹OW߸5~s~dDdP> qa.ECOL6}UdTv߭WZ3:͛>N[;OlP4>;W~X|Gtjh˚UEmIH<.Y'V'Ҡ P\_ky{0*0ڳmӒ۶f6 LEG|P sQ\!>}ؑhg,hzs[-L\hI;/]349К*{@A6mt0ik) *8tScx]b{/^M2w\t?^[b3Y2eAR9ҡ反!d[HZlDr;qlZ'Fq`du.FnCp:QWNc_3a 窵LNɄxtfyo_s C[BZkBNS(֡ nO)+p઎ABa o]znCPL#7J p4!G Lw} a1$g$ B "cogwȾ`ct@j+n=VGJ?!vX"UM@p( YXzrDTlK}lI=mjyf$4c{9qRLt1PSRyR]@=52X)^ )c rgj3?*;cp(QA}P͊dt1)IwYwC!:s}ޯ>54̢uC[_vߔf4 mA`ot3<"+SMVm]/#B8y ϘDw@`ԐNXU!΃orseN_l@.fzwccy+^VkwMl2Qj@Okieg!p?A9gus n>-\8K\Ϳ I\bFIJ|(;:. % M")b@7ֱ&hyxL^6Vi*O8[xzġ0>!c DZn}гdn@-{6Mex zmYPƴatcmS!^FFry\ WeK2@>!!dj S>6 ,| Df!GתvWjP[ѧwwJʞWTD3jE!Uw-Cמ|mJX1P_JeO%֐D&Ă8ު f2d|T:eX'3+‰ڛ3thubGP%ko.\ߙb6 '(5vFvLm8*kYF}'.-xC`]°$eMl0-}~fdБ t4HYįKJw;gc(T$ИhOVP\suZV6*&xVFQn4l!ڴ=خp₱+L><;|qs=WR9U؇~S!4a[gn2/ش1,^ ~1 (dvkUjRPRE;cN4J:Z2v k]&B_ ol̍V,lGsʼn?6R9:zd(}-霝t0dGWV@ Qvu*=^W0vZxlEvmkiHSFd\V/457}q[Pi1gD[YF+tgx*"RRIkDD( Ғ3hŝL] I1-: elCe{>4;ĄlI&(u.y>浚%pWsx…S3QB$Q(S(M8;H1Pl%fֹ՝Iv[%n@dY> ֯<8gn=9YaI`2k;sq$%1h3|ɌσK7(;?B$1 uz&:T!a"FHOd9ŁFte+N++RLڊmB4ӢIj!}Pi6mgF,ޝ$e rHt;#CjzaB O1 j_J'1'jX(&Fp&ڦ}"jO RδFa><m9Q_le;;3őVAԪ8 pb<5v 5v*iw[Ua{ Z\w7pxZC3kp<ҥOnY"ѼfiT5['u%oRor/ŵՠJZ D7Yy#7Ebac8/G7`D`앑 [Pi,jDTdUZe\1piQ $Fmv:{2OUȥGxą"þY ;as=rKGƊg8CfH\Xp~WO} j񭁋ۚ-%뉛/o0USqۨs8rDOU)(Do,d{c<7By~|bc [d"+d3<A-gF"aO6d PJ7?{S(ÌSANРbCo^G'P 0",T.~+9D=ENZÞ d9}5>/{hʛhfy2Nr۳4ق6 :(b"MuޢG\D?8WoY[^[8oɸȍ7}I=@u;ٲ`Ȯ!,TW A8Ŀ$|%|Unf[?#BfOOغ Ϯ klpg]bKethh.F:yAb狳0޶RO;s(DgKGQ."LNS#6BJNd$}OҠL@?ZH_(*:"Hx!s<;C{(.mݴZbe8r[vY yz{}u/h;@tףWlmIs>Mi_K4ίW5XN\m70s/軁3"]Lu.^l+KnVAϟp~6s  Scӏ:/'uLr!7?]<.<RotT"Xp6 TC@O2_Z@\=3-U޿zһ+u 2o'W[Zlߘ'nғqGL3zdYJ'LjA KɈnYW6Z/ XG~iCL)1*8+)-f@(B ZG: zn ltٿBNhmzA[ݏgܽ*ꢹ$ ==EH9i[p< S%'6)_PG*!*'>1x[$!m`ϝ|ʀp¢6Pm$IFݧzJ9?a؇@)K6U'ۃ7 P,|6m, 7/sBMh7'8ق8wү9 #wM:`nуI={* $5<{ XbNF9d1PTDO%ѸtS:z EYLZއ%~S`S_oU?`kHd떇dꅢD&\.O'h `ӲƐbOwYĵk)@ xX֊J.HECI{eǪ=#/n2B- o Z2njKH81HT~Bۈogr_4Ki֡ÙOM`K R8\[Hw ӬQGwF"f`~l?xM cmp6ؿ){'}7#}8@aI%r̓:Na#'= Kx.P!hqƯ+g^Db7]׈;VU/؅<[qF (|Il;P#>+eF`% w[wQ}t`aQuP5F }#87k}=F¼#؉s`䰵t ;BBQRj" Y:bOˊ|55exc|`vGM[4[ s d|ϔR+4+&PQ6rl0h3ra'76pr ᛱv,vj0;vjŞE+QǰDvo 'lle=q1ac t6~"ꮩ1Ȱmjv3j|}`4f߉W{w+MZy$ᖩs9čݚ3ҺT+s2gSk߹>1W' @3WMs> }2GxƇ$`"Q|1jHql7ZesDp& &L"u%%X T ?;J f[*˹q!˺rq=+-գBqj׃7E?72(Ws&2Մ"z6P*^'P@&(w#yxp ]r4vɍBA1j^0ҁ* 1&tǘ'Iy C!D Xi'plCR2B=?MoB 'ku\+m 6c,cq/qӖSJIį3%08N y ˥|sU}$4/{4={ۏ̛$(sm>;)c6Bvxug@PS ~d!,jn XQ!=<t_4"{Zqߪ)E5'x xN@KOC^v>{-S0c&c놆Nͣ﵍ѷJfڹM&76e%Y|j8#@J͍iݻ7\^9Wt sȟ_syFj Hd m"(J8k:Gjf{N4)@KE-Ks:R<__nTƦf3Eh{xz! (J*YtaXcm#ʢ%WGkG  1Ljmy~u+W:EI {VQR!6WbM?_RWd GWMgGNV݈C$ŗs"g6CdX&10W{H/斬cE 07i,XyN{_3=dHqݬ$k>MJL1lNc!VZ!vQ偾YI1B6O'Vmʆ@@}Jn~ SD;uK}ntV~?%"ueo_eͻmq}/X|FrѐtEn%}W?0 tA7Yy $ (gdm$Yl3HFMa3:ͬ䠹Mj xGE&)\"_t T#,W1C  ]w*@lmmgЁYtBCW%c^K!(w],H:;(}Jٺ#U*(z}PLe``1ǪoPf*=[#<@;;vJy=|20@E܆i~(O85lj\Aж1܌Z0?樾4>M7],_iuT'Ubu(|$=9VY8,ݓ C$hi-K I{akWCLY*Rh!R2#%q.K2邭GuBs}yz\BbBA [%C KI8e*A [~wn]/c'[vt9_^[ > 0 ?F7"Pg,W.鄥;oY$jzR5_yBu 4ZbAZU{;h'͒ڝ8oqk1FNFW:w|Z>Zyq Rk3]M×N9nvs U6u VRzys/ Tsv(ڡ%T(Xb+@U`,(HZd- -_~/`-!eeB:I tV Y5V"E (z]SΫQaޙTZG2"na@c,BGθ8I '=@1'VE\UWR ߳P[U|r=[Ucu{W!B 5-L/S70q2zA89)@w 2uisvi qe1K٘;O߶ro7$թ9i{)pQEM1_{1KXЅ 8 <9Vg+pIu֝_v#Hc> Iډ2F$ްk_kGMXG2} ('ZRP>^'ոݸ/ƴx8%bFn{Fj֝ >Shͯ^ k(8ҵ| U0 ݝgCe?72o0l&ح@T[aNAVʑzlLLY6ymï{%0;m,bq\ ο ʙy%UV^YRYf1/Շ5JV欯$»^&K$W_7!њ纷e39JTS~g0M[BYPy]{ , X[缎6SR3ʍi/]gtw={ؤh+ 7:?OpKc>@YWD 6IלI#1v+lkKV\fޅ>2%<|"yfa`kA6ZIj:Zj|*:l%X-- Tb+"f^Jy̧ KPlnE_ fcǕޣnQ>,5SrpK頰HM֖I!2^-<,6#\6S\4Wt,k¬$ݨ6@ ~k] z TGJM#E"Rǣ[HN&uʤUÜ;I_wq_*;ŭPXjsQhWz|fRݴcGNێWLϘ-@'iΒ$2Fzwf`wN]:jMmYWk?pf]E&`h xϜvR0XkBѠțZA V25RqI0'Yl:%èhkITw2T .@i)dnl\:va#SNBB¼ܟxKC/c._+]#y_ֶ f'-,S`vQM^mxa2Hwhx!\ܰwOs^nCC 9?$K@(B=/[TzwM& VƐ˭MwhCu#1ڑ:o?Y:5+`n꘦>&e؝2ķm]5E j9.pG!c$'8:j]mfv#nQ{wQbA lqW_hkgx\Hٓ7dHDۿb:8A8k2VJIu>{OoNd}|U:ôIU0C7=g1td5Wʪ)!DIks) w ߠNʢv5yb$QpV b490tYj] *r2uxύ5G9LYVT? shQaYMaєNK#k(6Wβ9FyҪFp4"dqq#va.8=늪x,?T0n-hڗޭ vy[ͭ:,%fL 6-ͅ1lǡ?*q< 8#B*ȋy;*4.#RhJ<eu+2Ɓa1w4mJ!*Φ@G\QeZCA~V큿| æƎx'zzi+=>BiNf^=PP4(0yqB y~+#a:SR=;Y_u?ųaأ2fg @H Tؕ[lIPEkn(R?kOopߖR: \x+ȯisTK4zKt'?LQ"MwEWV!3| NS09V;CDo{'oC#Y3 ϠÃg%+oYgHA1gJJDt"/vIǴJF!+ ".&9 Dα5:Y֋{6Љ*r,wjF*4 AkJjC}l HF+͖?6ŭn.S6=?W <-GjF:@)*cjw%-Lf"$gQo+NQw)lÂ0VtILdV:F6og#[=g@<1A~ _.QvO~ G'1!ځF2+soMKtKPgf5u<$N(^<:u*+ h<5ν:L,WYđ Tc6/b`x}W?Rơ uiuM43ȍ^F J◭Ҋ& ;>Rz??ie\tn/Ѡ]1Rà25yW:AXf]S7UuOTN^~Eu؇$}06ӱ,rCErG~n2_~\kZpǭipj&}oN5$t=:1/2K2x: ,2Qv6>cZyYhRhExk"YDqm`5zGr!ie6̐Dk Irn" >01Z0 !y"06- ;.ݣBn)vY dק&r _u|ڞqʵ"(ԎҤ]?)e?PoLA9N.$eGÎ9E)}J&Svח;rԌ \mkk̐bƛ2ka꜔5o6ɳ{ o⛠vW&>$VU"OPn\&0VHT^n_N"x+RE+ a\f_b_nn'jJu gCOa^;͛_P&Kߒ@Ap u#W.@t6o1؏>¯eZ=C{Aˣ֊:$E_\љr* %2D Hha$ce07vLR{.q0MQ5؅B~L*U!A2s7^7W2䎝0TIЂ \;4x_F5IzŬ3Ҭ6?7Q>I Tݡ1f'ej֞uFXf.t&S4o*5zaYG8+k3@|++gsdv!LAAiVrחWLlE*LkӽpMI% mxe -pϻ$XM=ذUJVM޹Ey%VoO| zWY=:Yz0g3bl6՗ D&>,gd`aGwfg^K׈Mgg9ZV]#ISJX""wo ڶJc[k]V$午I=pQA4BL,DJ!=j5~fi}yGn"SExj+sXpX`ŪQ4Kч2Rk##^wt\Ӗ6Za'9!dwo6}> hXB/P.` 4-(4X OK-cWl2ɉyR ^T`QZp O4 be𨱬1I^20Zz`0VQcӺ\ RZ Rn{}ʶiʖER Z*^G5QsC+؛B*.*΅ vtJhQl㓋uPA!c."Td3Lϒ&M|=)_&_{} ig PѾkA0 @:A4w`s,rۙh5Іotwfu.k=b_gJbL+wV};Q4*);A`1oi1)r.`y.*IG9U&w86е|^_IM4 =5dO)AF 6GTj٢~*TiopzN^2Q6u0Ңv1;YHExy:hpSzS\e-!7ߒ7Ů_4_!\w.q5࣋r_w#EW)J ?wq۩x/wjKϵ0.ΗXLGY_t4S'dV.2扺$D ܬDǦ@ lUAsN@C9) K} 7ǃՍ(j8Mܻ8` k6tN'Y)|Cr'*( {6{zzSH>_zۚl{#2TGl" D.G!61]4/F`I\*bOY߫0i>oyn@KΒ:ngïSY[򈦉fn6"$ ;%u#˜RnwO{e#`uXt'i5F"WMŁc+8<lXǸ2u=ߍς&J/HJBMcbjMy[ݎ6Sd{0(3cD>;:`TxF ¦ImE%#x@ U*3P: (8q9-GS;s81 lc-r6vwDh.&g 5,#O,vd3-Tyh0j"R5FT"*}1Mtpv{AT}w[L !T6q#ncKjX "U-qm2Kv)pXGD^B o^qTYܟPkQGk" m4Ю]snF&8 @:6T#+FmѮ=f"dev0bɤN%yx|?֪^H4ښk+?17A/hR":잂GM[ :X8[.V-;asPb UF{s A+C ` A7'vm܍U-{j"bɠn;`* hժwO7J4D(6+e||01_t!`7LdH܄5HRO[? Df FjM3MCeJ@sn' Q !#y@_Cp)j@0a%=,b50,BxXs}]]4Z3Ŀ[YR4xtPKEb5Hgِeh# Rf!>'d$ y ԲJÔ$mn/8Ε,# H v55~Y?< mTbP5ڵ%neIiU9jDZ]"')DW-fz2Wq `bMpbUgшSrQL@hQ)7ޡsAnt+B+Ay:ed=NIRm ^|;þAG?X]+{ΆR"ܳ_yX-Hu4!aOg;r(5M3MCڂXVn=/]`:wrXxoA!C+Y >ut4NE5%ퟑ5)\)TWɸӰzQsqZ&zb7F o說rWMrЮRc֝~=&nt A)˚ ,h[@|C1'_i5-dӼ~Ilf n5jW(aPuWHdcV̖컒B>Ksq)X7<3de)](' /-~ᑲL|&m3Ni#%/=vR83 TWS]@]hVsndľ]sYKG)gx)! 0)b^sTM(f wft+IBKq ~bx,dLukg>eٌ{@~9-xir» C/8\ z*c0X"l_!!m*a7@i2)Y+^̠{z<} gq6Cn DD AE`"fS7mpұa V=Q2ef`0ѯ%wQIV5$(Ca|U+Xeh2+vd\ZDVҷ;Z=(=!)DvRiƣKF dFl(FF8N[8 w|͚Q]-/W5&# xz{쵠 r9NEG/}$ba(G ؍N5Ӣ٢r5a'?RpBHCw59 {GT^+emLhL_xdG (M*+.͡#췖Х3a8%L -ro '0a?`^f+u*f@Vy0@8:OeoUW;1A4_C,$vyfϤ⃏ }'z(欥֫˜ ۀQ+NCy3tl'|EGfJ+{8xGO+o{2ABK(x2B c!ĈfQqFU?G^!EJNOX&~,"OpѿUOZVc\cR< 8Ӿ_E>g>*IU󻛠5ܨi\l|Gmvw&_qd||H(\x$t} 1v(ǭl.CS)UsY-T2ZW |x &A+4î!I.!,e;>fVv ޴j:,cZSq&a&3; j KEgY: Mh)iG4dȋXD]ӣ Ĉ>HSA(U!yqa9^}X dNĴ%QH'PPZUq׻IZA@FeQRM' nV"%z?joh [<^DR as+=g *ҳc,OEiK*& (S's0gv`8'.Z~8HD CyTɵ}V@|iyjHX[&9ucᘳt" P.+^i7q[4$$&(KtBsxq.L=brT*^:,@zӬm\A>_?s!H.C%_k}YAV#NQpFRL gLk/NBRDv#b/|VzӜ.'ǽ4_Ojh!RѬ6<2Y7 S_Ϧxwm~=ܱ7KAh)CejR C埭94+>C ҳ,klAM:yu٣#FL%oG]%-z5!_\jW {.!/JO咧'mYcL 炫asrc[wIxcaϠFs蝔Mm &>Xlχʑ9o~&5ʼH]I%"nǍ  Ǐ\5ݭ #!qya$8$zHHGUVϚ ]Dkb 12q},a6Tf2qz4<r2ڪ;\3}*F}p|ܑjA6Oɐ\7)B!]A&]C EЖͤHA3G;7ʊR¸_hHYqa.s*Űr> "r%owȕc%,QEȢIsh~ cR~h8@3 t.S9RIy/} MKʉ+plN$ϖ% E.%iCWu,>.^FC(5c) fUnmUTꟙh̑IɎ,'YG<<j1ɓEjoUdmr U.>WLz/7ttGGrԦUk)INr3.3,ʄUω=&3Kl-oj4sڿN[&P<9)>mP#/n&,ΐij$xKg &³G0Ƥ? 64naCvֳN)V4m!0Q)Wx#_ߢ8-UwuD\2hn5P^&SB|vmJbeALsм%Gʧ}ձA (_[ s?|ԱRR8A+临' bd UkzQpÖ$V#_&{&@j7&,`lg32&A8yg 8 ^sՏ=^0:@#IMq#zaÔvA3&5AmhR|玗˚n#=->wײ EĺwhR%NHtz`@{Q]]sRjf\k ǹ4\pt(ޞ=9xu͕PĿ6' fp/Մ=+vT{}`kuJ\ !=r)O4'%߈7?=kJ;)uEB=-ZhL(  &~~tnP,IרsQ,q%;c+K&qq0p@,ןDԛT_ʼn.JY7cf7x}f8̨>ռTqD$:0hV}Y@._/0abNdm&q̷51G?*#O1D%ʜƺC]O՚|eb;b$ܧ`C8BZ'jdVݺQÀN9]1l^Rx&N~"#g RUįvhpLwIux¹vCXB19؀N NN"ȗ9F!aW6IjY _}[j[,ɇ1jw(0ܓUZfEqRzG K{4.+<60v>M48_^x0x1SՇ(379)[_e-^M*?."|H׭ɚ"w]oS_$fAaR`~>z0HG~ q[1&Y-Fʢ}Ԃ4o&f<YX$ ArJ5tWmtWWw{顣g_M|<|**a§c4DFGNj_V6jQoZWiN )0\, #V\hsgQ#@CkG&9bwO'ș>hMzqL>ex*KȷpŸM U9H,# ua[Gc/ ;O! U>2!'K"fSC b\wM{*h*[seIg:l~ |sSBT\Ό\7{}GI>3r3k}({m3%°zpDoQT2WN nuanutb@s \K㯃OJV?ذ@lDecC]H_`C؍Up-HP0=Ё]o9ꊅz>~aA*Q3l(!YF%G{+^Z+($E<NЁ2p7)jrD[>ED.q_TR` ԅKyqė;s_A]eU `0vK0#0i*o!PŒ(zY#ØV=)Ĥ&<^.F3Iц>O1jfBl1Hr'; lBťB(xV~pDS zU>h`oJgӵ~<6o b#?q6)A .nAŒT~3Xv 7ͰUl aK.Iئ՟cm'E'{ ;W|dMȧ0*hgDq#B+_b,7bJmNfzBX|2#+nQzsޮՌ0_xrnCcpsnۡiZWM)ұ\GYY6TWjc)cFfAWD{ 0|i7XqT78S!m&fqH3ڃ|덳^Y,Vy"|s*mz f$.(dXJ>=-eOؼRx4-c``hE`322PeKN2h4;;k!1?OWq081qJ8%?*2TZDE]\@ND]Bk\ U^#vӾ-s]ë G@ O.RB= }7^\y/bT=p #U"Qָ*#X9:BӢLqzPp5DV3;:̬B0x6p݊RЄޜ A;kasUoëGLq&KfP&awPD-aWWK֋^ZI|ō? 2I#0i9$Sq,_7|P +KnJ/"A[8GrQkeRN9۽ځb_ ̨|>Cګ6n V=AZk8gݏÞ쨳4B>oZ]2X *Ny5?$83ksiw XR֌ &y[)UkpMI/B_U5DM',tetG+2'mje>_+Lɰsw)Z"I&ZfUNw6y)PYe`SX}?R:ܚI+7& 8qogE+ K׬ɚZ1ހiÐVܔlK!][+ 2~#ql?d|Y,eש@'bCSdꕷC4~ek S|Wm~\1i2#k;3;@uza< Cj@5ov [lskF`z+Ԫ [i&$d!eLINkW5UB ¥ BǵCvMVk3=%{0cOXV66V>eKcKI{9q^q:CM;u(Z N{\Cv~4&r 3xm2t@f;3ng A A֎V܋i|.^يkYϺy<.9+ʁdaF?%>?"(ֱQAQ~za/!47?5XS?PHwU3˜G cԐEZH$HB_y#/2]]כ#؟b KlVܞ۞!^ i%ZYy=>lݮM7q־*g kY&Ăg0ٟE/oFsҖX8 6v Oxz?7#E5ע(xsP_EQɯ3 YP(|5.^ehȁɣGonXVhU/؈.0*{?0< EB P1. }3 h+3D@ JUo$$T)@h" 4a|@)VHs*\=.^IK)0?9`'wکX(eMh~gV9pQyH[_PZz"" w4lrߣ-iv33t%;.f؛k^w3ut R]hYrGp&uZkR#qA A*)1fpo3>+7Fń*<α }-s$qªr{M-u],jgվSU$2JeEśܱ`A0\0c^Wʳ4QIpŰ(ڦIuL^wn8&CďevǧY?ܷ$QV!TT?a8ʺn0UnE,ds.Dy=<*?v^&ZP 4+9TgzPtŋD J8Lޏ`eVŚ΢+ONHOAo)ʁI'_m{ǎ̺Hlg^ (7WܺR/R|]]b\\#t^ lvv4Ųxո|.^jru #~\ߎYF Q:ǹa$K~WnzC!AoWG[?8ڙR*OʻVPYW{=]7V;^K@ }s=ˬ!<Ơ[aKҏ/̹5IT$}Ie`rt%XK\ >14d/H%o7ZH޾x+:: i"WId2Y#epv!,58_,Oʫx&~`B$dړ~]I IW쭝6g& V1*IjUh@^Pz;RXN85N ѣĐ]Q 7 Q؏'8o2̟;4l):!WZFePO܌<+cX8ج6+{69Y| g_$$26En2]Sczۄ+VhTy 3;dx9$nڏ}3f6=9vtswmq'_î<1smf-ǐ2LĕoPՏ8|X%X!+>ceZA2 B'ѻ^ S2#X Uc3ZVO=b]d<",(JQ|EE(JGlǠHd\{ S?6AOJ:_U _i`wo 6gdW`s+/!Ґc}Wwo4T$9D_jPADŖYCd{0cʞ*xQ39"Gs 4r|?9 Mp^ S[@*t\6(j,py2T+'4׬˝{H|0sar9&9{ 0n~<|)?|h~1POĈ8aj8ql+іݞz'O}(D={UQ$4k6E~mAvZU0|l9C[@/c&^p1? !/<a^7P< Է2^>yV0!Kl0LVjOue=y"ŏ=44FIٮ18mvzݓzpZ1'`h!=YؑNA5 ]qG~ԵË &C"iѐx9WEL <z>VpKbd*č!I?1,mgB:vYA:-'A #aP ;İf|[o˦ S>Q0ff߇F%1".c |}huw2ؔΦhSYU{'QT<=r0d'a-D%xrW@ /~ GBHד9i$NNSs΢ߖ =W][\ OA:W?d*"O|Ւ^v}_ ~y.L:ێ )7m& e26S|$ՆH#+jƣZ8JǗ]JGӃ}:LJ@Ew )~mr*Or]?`Qز Ӿ HGo/#HoVbK0X7e(lB<L5B{1VKgJ )QՑ|"hNNxb{VԷ}Irsjr:9\ւ&V[5Axs$'9MoXZvs0yh>P:T|[^`*bỳwՂ=M .hr,JԢ$`>y#nqʐ|BHC_>y7 ww .lYf!lհREavdI98uنbJ}*?zOssAO;|~%84. L\^>faK]%4L% i12-pvI}MF4.Q3@o ՎŒ=;sh}",>f^6uW|eJ$3b[Tdzw5fLS ˽gIA:K3i|`;+mF)&/DoFf~OpĜ"~\ RDHCŅeΘ4 /~`(QdEZxsRRCa%xG/c@l`W~8ϫl_ypQsd ̈́*&:HShI:=x+g^edC,^d7+AP9jgUr"8- |C[E/`zУONZG6㈦ 2vp`LrЬFIt\G#n J[ƞ6Tg!C5~n d닾@=U:,\WGG3)|լ4Y<70 [!_o ďBosڂ[:LaD4Lo;>--wJ"Y_f VN&1y'f OB _y3s Bm@}v( p>>WGM[1q+nd) x/CC"=1\5]=iϿ,S}<MI ěCݚaP]_G-Wx[F^b6ܬd@EOIDKxOm<:>q:@'NiS*P`irw#磲Uyy@eicpudujT_ږV_%Ƒѿ3YAVP:!AH=?|}H d':tqnǕ_Eqȸ"W@D~|펯 (lvo vWx}&B}Ky4ߑ`םx1݊&,ki}hY9cX+!,$oU=hP>[/ZN^av4盥o:e=ɏ$Ā3ވj]1=춇a(U'⁚*&ۑ&ЊSA땁Tc.6‚a #mHQj&/6jj|eNMy beXu*n֥hFV72|3J2`gt`l =.}avhKjƩGؚ~f˘<*52ܰScWcH PvCO5SO(!>0b$4H}>n٫CU[&.W,zr!ӧms=ya&Z<-qJ>2:xlŗb$oeF'w,a[*m'_~6oٮÔKyraergoxƌ/%;pHx^U;{df* y*' \6CO\#_P I$*T$10#0+-¼Y a8'DM߭Yg->ZeY8 n"te<)Y=c3}2v5_<`A6ekƳ QAf:.Utv@Cr?S1ݰK@?cӁT+fe sw1JtGR9K *pTk?hwjZp>t** j2hfAce Vƛbsfj(Rykk +KWF=l6x F٘T9)̪Sd+465"&/ '#$-Cײ+qmk7sZphxR~7>ıpi~WzJO$W># 7njܐj(*NS)Qو"Co c4|b;~=c11;װw.k*2 H o"u>q:k7'vzZzs}d^A\m@̊V8eΧ}gc4GWDWiqBEIX.xw0Eڼ)^7^KO E ֍ם0X7hH8~|Pk'}߂=^S0&{׿<\yUµ$_zސ"m1ʞ\"ڱM'oYje)5A1lS#9S)6:gqYFh%xbC^A1A/\>g:)C`a~  pR}S;Zp 8m3G+KlWrkWZ޼:@dq;g2ժjf$o!h+:Ha12 p侮JLtuLi:hZ8sh[u5{ڷ5- C9KqQ/]76 s3=Q+-:Ͷ%L4HWU02x`#J L\"tP#`J 4X*s&Qׇ0#Wimd AMُbb2Ywע¦.5+uFIOz!*9ȏtȡbeNm( {=L3^»P|%t/%4@x'Wc:i%E"K&Z{}3*óT/;tݡ7^T" %xy`"6A_E8jvDu!ؼHǖe^)^jgfm $7z7e:nJLo &iNLjmPz1Go懜$Sҿn wj|bVK!FZ)D{'yɁ$h_NɉJLiiKL2 r|PypR gפ, X^6]OZm%}Y|l^4 lQvKl٫c@d,aeDjfBł$(Z{{1[U]FM;Q_OK٬vߨ &J SV]ގ߭ԅiRxry ,wATz4c>E䗉;=rj˅w7 hZ8^>Az%-Bgfʄ;)1 MIDcVoHb2i Ϝ$ԋ5+$ŝKe-F@Q=*C!̠K%ء!yg$CsI:TR-"Ѐ!pl;ׇAbL >B{;fHu_fOڏ'0* e(nG" q? Nj/\ { q>3:aӕQ\sꠋʀDݐ~YsjҘ UN"jE +-atʅCQ( P{5iv8|ڗYc̆M;qFțթ8X~9]HnOQ" =0#(N?FxV^{Vcbq?V!x^Xdnu1D`eИ!QWA)*nm&'_e;aA E_~:G,ѹd@cX4Cg4X ̯tc{'0c&Tx^-o5evP=Q3z'dצdvtfu,qOi\>8B f{JD.cd7պ8kX7!2涔I\2ug_K9\65 ;Wj`aGhXJnV=@v5urL3,@Q石EIဏ!42%]`Ld繉eGMaJji92(9w`'`ݪT&㸅҄R:n );<ޛ{J|$Km1GMGH lQn Nt[w@Z{桛H rYbq"^v~I+bu}ѫM~pÐa;y$ s?݃ d.юlB]&9@]7EO?p%ʄnmbC.xcW!Xoyp:ZdHgJ!t_|ṻMZ[o KhQEl1Z.*nngX$k$r h M6m2ߧ`8VSgw׿O3g}O0 Kx쿋SAe~8k&Ժ㝗R|U{DjB}ͣABPIX)W/we@\8O(eD6J,;sXשwd<5;x{p`ZH?} {ō␅,%ԑ^2݀ \!p,x6sUa;c ϊS-U ƀNxC79a:'8m }^)A6k"5ٵ b )@>p6bիGĽ8:wIف޼!$UDjXgiu]oF2M+Z 8T9i08TGᠱ4`U4;D"L_>1I] k| ..|79PshkŨ9௎`gxL2ShhXP&pGP_'[aʥ.s;>r߽tv &:<}-7_*+_=b"}ۿڅJ˕v zMl}+~sB˲o&ot|3B2{ZTn{Γ%qf+HlLܣ\qp;`1U 3 CNdvǬh7oOy 3$F78&s0?/3KsCI?"w]cu luJYyxHM3kBjmEu.*-/T%oW@\i+#T|<#c'X]Ѯi8cTІYx沄iS⠷F+8-GL Or|?1>E%I*LH!N 칩F-ws1kP+d0[ݶ5A@ܜ.z 9}| ^kw])ad0P(NÌoRT _}>2h*<"bsSA\b :S$ȃLsS(XMf6J߼Uc|wZBIHk#-w`FR _T=[̗1ј±nn{0DJ(4P217m6.o/ņ1F978cl]ECԨ )/SE-ǶwhsIK[%Xnz&ZrSi r56̀ǕU`ZEzwΎA+d]C:GRbodir(2+(7qL@kVȷԩ}Gǡ:̐=MN+l3:F{!,;M5lWe)].}aw;p٭䯔AW`(O[nלp Ԫ2A)E E}ʡf3nsʡfVH R(t$lsfa8/?ޮt%]\y0RoM`ߢ;ͣJYq+0>Z)N2昸#M/^2w+b`uex '!OitNvgPMaTLxaMb6a|< 0jA~X ~9&YaV_E[.JsM19 Nh.r(lww7`v7I@c!fv~85->$&[Qo/M7t ,!q0I='N(9`2ugl\@׏6@eU1ϣ5"jm;x[GT'a eC2G|gy$BUϚ鋟hрD '#4?uXkLAWR #A\ϫ9HCd%RLwԿ7@A(;4[,.0ԛÌRkeYW>VJF*-pSY }o\O4eGBYUJ9*N&2Nť,$ۜ @hh5q+C4rFZ: ,mn uOкc}M{W>t!;VUSr7nӁVu,BiͿ˿m~AQe[&J}U3RyѾڪxur)7}1&d zn/e?TRZfZO*-rYtИnV6fgS8M#/s*ƾh L ψ,'϶|KL9NFTSމB%/xV%¦OXZe0#c(,d϶TAO r* hӭʯl̕; 7>n9iqJ؞s)Ŕ5$!}(uxC= ܆*d)Sņx]N{VӍU9KCN&4c(CE+ +̷M:ؓN.^xcϟ;vp>P<K CJ䱃q=&wyRQw>_pQRT9!`9PvXMw%(""jW8:/aç#浾T{,JWKq@j{xr%)c%9|C$F+$& x: cY^`~Rq.xg: wVş;!W>9r/Jd0ڈn(xx{hؤ{,]GLdEXVsvg_Ur{D MCB'N pUP E*cM~i;A,UAР 2?<@Xm~CPnB͛vG`_^Ҕ ] Da,3iaI1s+ &T:7&R_/7ZCvFpJ(5$gQn(.|{tI !r)g@=]V^Mr-T\3V_g5?*b"וڛ !~$e|8|koR:ȑޜ[xIa۝-oRXIpomLЉgaE$LZLB'Tn95; u#v>}߫iqC!(-Sqpi0-1ѧ>@j룦v~97u  fJfR%%O& U"bqc磟 7Y O%\;_FzU tx'}_BPdhhFg;wZ(.Ce1~<2+/vQCL5ggj/$~c-<<|ùcJ&Y=҂Q8W}vR)9]IhabQmD U4'Dbqv1i D'` vw=b,H&xtZ$($^_w=UUva)1] d??Z9/w; a t+j/*t͗#okd-ƾP:^}|wQ]uh1AT\ (~ʱy ى,*TSw2æz-FBnB[}emE~Z_3zND `q&^Sg.;v "y;:B3K,Mx{976)?ˍU<>{PӽÍ9sTϤ7DP!%}6x` 46#n?2ExvB'#Pp] u37^^ t FmvbCf l zBtĩ~HLGxU͚Lt-ěv@_ʱ]n9$N;,e\d 8̣zWzׄm\"k ⬍LɤIu+)Z+hFu>ـ_P8]H)[TP-?}~7sOc5wv Aq WHzĊ3Hy `2 DAgI>p'2-[k zB}\3xkXW1.M/^NM-L]=k.*ntl<^GӾezL :w P|P ƺƓj[ZizXfF*RhG6de dtB͆0B_g*pD܆͜5O{ԷЦ)}j屁3ֽ*a9 mw۠APjOa"' qQV'IE7o&5 "!{H5i[71BT Jno@$b5.6`Sրrf8ǧsJc]*:05`ş%RfhIO hObpLH عh JcfLͥ'tz=Iqh(}rEU5Ox{4U?m9חJ/: X(O(OP2|$eYMY/րRuށP:cLz"X#8zfWNuvM lљ:!vRӡX-2 B|fiIҨ}< B O$P5/6~o>h#y [M*j'JZ}%~OŗLiۙ; P+OjIBPϥ32^5嵠Ϧ`wF#mps7=Z '*BgN.?XI#IsQ_:v^p_cRniO^hYg nş-M9bU`߲:E=O3Uq߅h ^ǡ/JmMf6LlZr|~j>:y\ [l S& @yHK&.s`C|ٹGj[EBae{u9%aٙ1=)+<ٞ@37JqoEtb4Mp yG\*͕z@ݴ'N\ޡFI* 2N T.9{ZHӢ@ ׹Ջ&zC:ysVd?hw-8$ I'q?bL{{4|9D1 ə#NP1伪pw8#T6K̒}mL"sY3 9~Oҟӄm-<8=pr]j&a' <0+l!i!UtLn1q+ut hW/ZAS.Ւ O:my<4.w;q$TB&9?3[i -K6vXzor!uڵn D^ǑEm{B5d oNh\/DMǒ QP$Ye Ó,h[ { jX\:f\CҰZcI9OEN]!?ݵoc^NVF3zeA# ͟N+ }n3fU0]wMybqT[nlb(DD"^j{(_]g(ϱzGw+;!фT`૖WvEA^l.=>OG* *X)#W95rhh [R\g%}C9v w0g[C([7U*J@d˲|0&/i4. xzYjKk;IvVfwtVb݅ i8.oT8CzM"mP?)]$͡ 3.6\Q)?ϋ'<) ~i8C)oZ a~LdBňZaH鈨h&?pE&y ^E[k}9Udn~HiWmGO.yZ }0%|"vU;z]Ģ>cz ,H9bn Eyas9cgOC[ Ș\F HZqkɧ+hmQ}(0)rTu_=$_d2BNCF#ݸO.rvLܒ hո V*8d3_Uv k!@DT N D$T@SwN/eެ@Fcۀ?;L{q%&ha'ۧp{Dyy?K ]&eaBqE-? cפּ:Hj^!DuEC!Hʼn@s;YI{%RCPLv$F!K;9uzJCtΕ7[cZyj?>qg{n~f0ԛԈQ#(\:ځ!&BvYve2'P o_zvaz`|T2İZ˒&hv!ݕ' jdf9PtZ:'1>,XOe.ǁX+CdGIXMF/*Kj ME0{OX>1}, 1>Le!rPo*\6>SϔcxՎ1y. ScO*hdkb.P*dЗwMFX4F'W}&.}bk}I3ɌҎ2H~}WΌ-瘪xu?+~+cDOϵ^e۫M&Gz%j h2 ¶#W*$~g#//##dTo~383J{^W&~d/~#}G?js7lnT MO6f]+r𼓗'=ۊO(^c➴~#xr>fxܪg[aa7*-:s{*}cEAtPj,`fmy{g+2ƪؤ]7]jKQH;`*yVtC~+}^07Ʈ%3TE峞>FyÇmwV8|sjC`ϱ9w$@-^F1Rə`~Wm/1%Žsb"אĎcȐ"%y["_ޒI3-n1"M(k1+ֶq[(E0 KQV%SZ Ъ EvN?LS91W‚\;{ ,ڲ"]7 {M*GIG= ڗl_+2~ݸ!m2H^z(ν͘t8BN(̀oѼ՗g58KCKEd"GxpcQ1Almã–ȓ\oyj}HVo1]!tAO|31C]&Rsi^;)ȿzw>wנ1)!ʆHvk}Yo7L2(v/M4kG0p<~t5K $V+Xi6TbyQHCjy&s3W5Bw1,^P~ ՘y`c~JCx3>4G7ƢwWP" euޥHףA]IJ2>ɿEhԌ#O!#S^l璖g`Vԥ;, 5 r` e鉽,, \hTcQ=)UrgYK&E]GC~YU; Is[, $L߃(rxݺf1ʼYJj|zOFnbB*RdOLLgˊ<=T_uT{O3P>!AӡzB%X/w-MDTuD,lJ.OqIkZZK̓]U {$$HDkYC,~ %@G򁌫wgh}lyDkZS2֚:աBklz٩k[o]qHNsj`GH+cqBx_$%8rga?Nc+=$%VS 3ȡT 59Y R#7ͩlȭ~ G} WlӋ a5Y; @%sgg4Τܶ**ʃ^b)ԬKUNXNM~Ɣ/,$,g!aTjQ٫8hfY)ePui,^'rc9AHoHc~.5<\Lޟy3e ꚻ7A<-Cr b˔3s[.Q59Sñr(]zBA6G4lkx ߨTVe):Qm۶۶m۶m۶m۶msb#*9UIX׻DD# #KOhڙVcTKkňTl&㣰EXи&RcyKLO@$}4ixӒɈ7 n|GzD"PFKKY))S/O? ;@  ({gFqjT0(H>8GBחyP/o~v57t8[Ǣ>..\Z<#*νuU]nªElŸ'r=<&Y5=S)xF A@PI}a*dYQӨ?eL"]ߚY:!Qq^ w>Cm" 16: tEo2P{fPǺK/jZt b{4..>o<'dj^9b(TFv֝6m&GXP}(KDz#;FV2xVs ks> 2xIr(>Ӝϔ[fW$y;^ҍ{~\hs>)q ( bTtIN)#h: G87$7IxPǷ,,*ן$M䵊}'ASyDMo4@MN^u"#KjBF"mVF_ujpIJӳJ%E;wr돷wJm궮l 'A~yN\WW^™o7A[z5  /pՠO?sEk8ʜ'ث/e-Å{,6+ I?h oX 9LCC짣yoj8$Ua~;ua轐Il^Gi;UGI?AOv^ -6nSPv>4mD:WǾ7s؈5/h?c 2#B/i^𴹃E|\Ȥ]{_^)*ay}JqYXr5ːc3"ZCm=HnzwyJ'?tU5DbtX(Xm}H\c9|#V`9`)ER7s֚hWn+n툒Q VQPA|? E ;,9w1`.y9Hb.&̆ byqt#k-mx?sbE6, 1"UA+꭮^ eBMg8Sk"xױu>yi|'m>*2k'N?WS``y؝ [щp¨@ ?\9i_eѤ fi A1oˮګmz𛴄_TY%1fNmR[ ?Bdo?EXI'z[(6DT;Zms+1˓b>,H@ǫxbx :!MU6Pb W=Vw[m|/, Te{;ғƎsjZqcܾ'u!\eJC{L#Ivwψ jR)omw Cs:t7ҩ9e!N[y"C`S`P L?֌;'{M_[`]>XJTo&>Ezdq 9O$omzޚs:e6&\ĴKNK ] ; ONN>S^lNnTW[P󋏈^H+9+{\g=ƴUE؈<͝d%R *:Kzu`EӣWHpL)]{IfV$>{OzpU1Dz;eMvaxR^}2[-> ~Eɿ,{d`@""J|u<~,M){:U"8|t8 wS~SS937vvv?H.".xV:+-]RM+Mf037Bz3b ćM[OKÍ;tҺdE{te@DHy3m=mO_xJFyd]=:@Kۑ|x̵[/[=g`)d'ʵ}O^BeQ ;5#>Į`MGYs {gs\gׄ:enSwB(޿Eb{82~#V1Fuߺg!]P4#2z.l-&?4|?Sxg!B xN mjs`v;\1d񟬮yx90@kl8İū|g%8g'ā^|I%A}`D ƄGp%CK_y:Â0+Q~[,7$6uR5Ӹ?ۃ&VAa\L Pb:*{ޏ{▎5;"'&x&HNS.n6.^73U$Qtjɡd;ZS X6){40QlS>) TZG5RO\AİdmFe9~E-o~?İuN}Ἃ)[Q,o;@ bZ1Sɘ6p lzN+cN&ӷ/g5$Jn$RsӤWg*8aFB2AKI0 Z 'lƛ,zb~H+`EuCOBrd[Ydhtyyf k! 3Q)v<-Dz,/SPg)+L81_qͷW>3V$nj]%WM#x*`h\\FG5zh!!aC/48Qޏː!ZXfQc5 0dodwELFaєۨhݧ ۭ(3LjP?s?}硨jN'm1KHcΙƮhEH3HAYJ.#ЯگYF7nKfjǮUAe-g"urS 7cG>G} J7llz4 .p H6AX/N_cTF͍ ipD+,1Y9H?}D1nM^pgn?6th;$'Q[<7}hHvWVi\'Ao0LJoa z.C#pmKuHy@D1^ݖr_Q~s$L&ӉE$*h0bzcRQٙ>o"BnMr1j_$%#vm9HRqt$:4FEf}+Uf@zp@b,; `A r02ZR]`KpT ǂ{B#gh:<%9ĵ!jD<~rUHnʁXT=ro)+zݏЄ|3E\Q =)Awk_D`Ah ֹKhJkzp`5p%2v 9Wp`,庅X|RFײ` ̈́2@&頷>'o]1G̠w?"hY?F`hǿ"ڕEYT%ۖi4_bS>9*<ӿAsg9O|"ZT"\ȉaM@~lv>AW=  Z#WSkLѽ:iu_dA6(9v#1H΀dnw `7$8?׹[M8$@z|l@rҝ$z1f@O2O@Av^ m]7(yH<>kmfHF+Ŗ76ɭfrPs;U>g%|Um*FeQGO $5hBˤPJ" 12|{MmV6b8v̆t bz#IӶP{ޓΘ_h-g=s N*%T̉MpݯXiVLΟowxj6MW2-,C Pt:F;oq(Ye)1xt# a㴴$#?"/P-Z\E ؤeGĝwn7OvmrmbU<(w2Jݲm_ESsf/",2Gooܗ]-[IYѩBV3;stuߒ'b̚Ak> I#An:9}KBʈCmH'@a+46(@$B[j2KH7>.ShBjـ G ]KZ)=r+ׄ|!Z3 t(g'aISE;#^k"U%sc)4ִ(H)udBJa!ϔx{&ڔy%V d% !pAJrDH+ysH!̺FιP!juv%уRgoLb-XIR&ܺ Cթ d#qKgyZnr\ 3À5jz+':: jFnHc|RmcSB[ۗ.$]6f/_?8chQH^t i,C썖̬_QH)35TwjDZvY<$?G "1y_Ƣ LaQREV&auɂ?Y_ JHFԣGLB18փ/b<1⠏p:rj~!9^>`I)gX7]=_URZ]:Lp˅ㆠxsյC~ýey;[$8E߸r3zLgb.+Q!b6uO4\آbEV5զBS%%7_F!I ;S6?E>o8[ Bey>4[G3=5J0pƌÉT~fSBY{{RI" ".-ۢXgR~[T N S:_/Y[Yy:6&\ңUGȝJ!)mPr3Ape $.%! s ~>I#pJA/x.8.2O}#zEgBdٖʻ^}lcLW~L gT'ŕ*&،|5[}<'WR4Fj{ K/^q_aR}^*MU!6?0dLXvfaݝT+.lO)9i|=z1N~@6`>tY{--Zh&Ԅ LxNq_6ĉLwNRkb c ΣśK&rmM6oQ(pd ir۱ zi'7:ؤFojfƶ5BLucAXj1DͣԟiUرqµ^%˭_ɽ,K3 ]D oDJ }NBӂ`s6&m ;V(/l߫DGi]~t WA> M;6̲?I›g~V,!B =TUh=#W:Ң0<%7U]Kw7tO.jt:wr} :;7'W=!lg;jd֩svDʖ-떰a&w5/ƦB,.Aׅt51]r}]Ƿ$o.ʺ[u?N袄 bk5 5Q6\s$b zZ.gBȇ =껦1O#5l SZ '!oړ=~eS{J*~C$g8o 瓡gK$tIuLZD֓idn XöF@ʻt'P&)WJՙstIkQȕd4ɺ}$]APMĵ/yPǁ/_+&Ҁr MoHߝF=^s_5xpu%{4$jje˚MEjUwg:8vszLkui"tK듼fϾC?)d tu h5Z?(,ߏ絙uG2C-+ckH&p6N,!aMh^RA/@*&HmHMP`/>FϪTIJ!vl^?e?=F9Z}01r=RM"93:1ͣ|bDQeqLdv/^9-OY胇cb-Yi8$E/ hK̂o Sٜ< 5Lp5[7_8U2&e QW֒buIev "^3#8m?o2D: t6Ase`V NeuWRK1n1KH-93mFL<gSz5GC5[z׉(}$ڗPeq)}t2x{ |+B%aVpa}WR)i#$To66磨kǹM''PU胈^?8+? #ڃ؎A-'%e"B=wY[k\PCױɗ4l= hYPΝ)EdÀRr>g|C\(l$?Du0J,ZHS`u2b:7n 5'Gk)QR@‘23IMUpZ}KYF*nۮV`IRG-(lSV )ˠ'tߩ~76:#$e}hdFGB {$Z&B=l汪W,6ABQS~zo$RFDqf1E'խ3rvQڬp3fإMυ 5 `A ЩwDP$v^/er\ Y/ :He@eeF8[q}_)9:""`* (ybI4AjyB'f7/XB]_{xS ZnVhR!um 3+끀ON\xqOxЬ2-;f;lҌ8s|:;. cTjxt&'ŏUF8pUT?3|,*iϓ Jиu5phj)D2MP8 (y {؏˷iMjj&h#n+DFA2By)7*\p^nh&={r9S"t鳁a117lX*unuP ^[xX2oL%WyFה{>%ũ }W7m TJéŕPWXl٨Ddk^|@\Ik`hbȽSpjF2^2mVE&Ne~190C)\CnN7)NITdPr Ϥ&p bEcc̯ٲ4l4 Gl=da=J+Ѯgr]ٽK$].Q]|e#G̅ 'b dMC&Vشjs~kh&(p=\\`}/cu W{␍t&4NGZȅТx۶f1E溅~AyuLxEc 2/=݈O qΤN=:=^I8_&3"G9xzl$)y/pIL)q0nV+E/gye+N e}^)ܜJB; #8sW9OJm$ZJM Yõ_0y ɓ"n^mb^l!.Xn6օ%>qס$uv\%MsC?4 \2N!Lb}4nbKwexroc t=iKص (>†R"-tE,<;x$4F>3x<>lpdTPG-dBDntd2ȇYM@csh<箵j雇B֢Pgn)3b1lniH6N\aa8D~*R/D}luӱBu%%`>a0p39U^EO# KԨA_-Y]2*|CN :8g%Vjm Q=3KSSԟmm5C p|,k{@?Ώ$e-c qGf>)Sh^}ԆkazZK$*(4G WN6^ˆ~U^F]Da n!بs vКn!7 =sZIo^ĺ`iSGÖ́0 &?vf'M:z]Z&J>>FE+NmṗO5kFtO )Y]f kЦ.wi]ˈ8\QPʚ< ":w-dnZ*яd DW%_&[ec/:tX4bjV@1l IQ4NJq0#Bp~]cd#A@lsVyiZ"ՔsV@SRyU_ [(psRFc@ՍOv捬W(ss$xZ˙gɇ4y~[woC78E=F1Z~ YZ{Y BzY /5,vU+G$lPւ'h+Ii4 8k>{BR5OG&W{LiLXvߺю6?{SJ5~zۚdz̵a:_Kbd?CH1&%D㺬M;?'ASvERrUBQddCjI!SH/!C1rPi^D鸴s17h `` \RâWS!149[#'Fv($$ DjYP+l57%p-zt* CX+36w>:t?!X,p>>-_35m/mvdu0*%/-@vṪQ蒷45Krū,b^#ׁG$jLo?]f[T,omnf #l` cʁ,3>SٱN˜,j{˨7)_X/-;`6#dZrBOWz6(aj'De֋>{Q ~c:&c3h~kɅf[qS(Z9.mIOg9vZc>?ŔKz.補=`@`-Wj#xnX5C@l6\\ _䭃tґkI(-Yie!`+<04Db{W>_|FH>Tr*7"tV:4HזX z(|>̗Wy^gۀ%բ/4}T&巍e>X'lj~!BcaQ7+|%K7,{;_7TmO=yTk-^&Bvi8?w B9}}-f+LKéRwOrs4e*Zk` -6Kc@7w`mWXLon0Rн"coA(ݛn?PnL0gŞǰs$ƺ!cetRWmb6\dͼ1EpK?mJ0yUMa-*v@q2DhXRIgD`"cIZm<%"=OK$9i]@&K>P<0V_b2u92Rh Blº >^ZJK5fL):(J;3t5$b/%3K \QdUVDԭ0{-fSsriakҥv5-s}j>b{`jK#Fr\7.`K|elޘ'=Q5H hؤZ4ŞS6 _\7c3JT#7%uHA(JJ޲WZݑpӨsV~J,PWS#$Jc>1lv8^3(%cJgϤz> 2%@_Ewc#ܧqD ĒGHQ` Am Kɮ &7HLa&J_s"4BڠӸ1Ki0dCŢ[zTcViz}aPO(rS{d--Bkk}F0/;ޕoG`HKԹ, x*x=s%oNObœ-9I!V{5y;ygu7I\Cv{S:R:.)s/qpoo*4ì5vT1˂GD.υ/~Th~9fQ~ X ע|O&DI:_ڀ=uNH|:qf {_C2OOzϱ86 su_8酲V (FV$IZo@F? <}*.S ?V)xZQ#YczX5R}[Yď(ߠ.(uM(dwvmz3BKN٨牲,6S|'T F栀;n15_q_h bx8 )UcJMދT5E#:@jMZƽ/CzğBRהʓ5gUZܾbaǥx}`JOP#s?JۍY%^ؕx^ȼ 2Pכk Ii u /Cuh3S;uЬ.]<'"7nUq~L6j'2:Ufq1*fv6 _}& 85 PCfʻ46F%l[u3dWQqφ卦4W ]JH!݆]_o?R.R #`xk{L^ dU{ ^;PQ+PS+4j.%zq`mxx㢾T6N%+ ,iNj\GKLtS08s{3d%s N }4\:W;=2٪&JKnLRlH q FWtJxOьZMss$Bc!2H{ҥՓ˟[Jt:Qk /A'bj䝆WC!mB~7>ɱ#^*f,v-cDV݄p=- kdڢh ՎjL?Gw+Uei`%~pDz/; y""1(hA~,ikrCVWX?Zv%\S_LNz8/rL.7O[$Ƃɶo}c\|}eASoqOn8BdV D%媰g̲Ʀ h-z+ȆRƚFS{>qհ=?Gu BTe7s Je1"ѺzLʊlżL$!Og3)+U/=YIJ@`^ڽl(ePc?ą}8E/ 2bʳ΍'%nfm-\NL\R(ӂ-Eh}ήz>h1P6jr>( %NK/&cɶφQQ( ۿ)xV!$I̠|1y =Jnkm%ԆDa2@/y٩Yq"A2IK>ɯNl}1R[=`Qjg%ݾ!gGu!>hKgͫOBI۰4.7_~c'hAx |CsЋk/De}2yJTJ¥Sĝ `])s7:W}Υp͢j/fr$EouFy+ht,JGn>}\"X%FOƦI)ՙtHzV\^dnQ9C=[M9:ĒPEƦromL ,n_!(-?CO?9_qLJMEXMC C7_ھ혛Uɱg WփOng :trcѣմdD:V?#>y_5YbbCS6-(ɯL5hh?yyNV<>2I @Ub [g݀A n q>졽5K#MԬԛju7Ah Gl3'^R°W g=)(,0B7Eƴ72#ܘl]Ugl㠗pԢol=@ +KcS0Ѽ_ VkE0 @ӧҨ (1zױLp rTUMSK[ <~<]вG;<ф {(HcGT Mf {:q΅zܫELPNǤ*'2BK3檱=~FALs ߬rRG50; ~Ud;w sZ6\%#[ؗG$8N@-0BQƥ(vk:{A1Lҗm^ Tb_*x3?R-%sV_dzyQN+{eamɡ*Kq~Q:7DGf{k}iuZ뿑 *Us+iLhݦKk5 )M+h(S}p#;] VL%~P j\M:>ZދGUv3׿# [Vlˍs;I* Tm9mcixA0!h!Ε3Js_M[+>U;f]H,[3x]$Z7.tʦdf OwTIDK8p+[6gwC-LƯ^ݍ.Cqqpz2!=$_G:CiR7 a*v-k7sdvp#nwCπ>a4|~zc$VK&;R|!Gdc$.UkNvR|9~AIjZQ;^  5R^zùݚܜ3i$g ϛdug3ڹɭJ0]F\#_1/~.h|:eat+ .l\e>j !,[b ݢ/Fn.̔;tjBo*$  e ? Z qء{X;54C&z@]W~kی Jư7˸<' Jcפ-V6_uQpA$%Q坉!- fYp~ t7`9 33ְkpBRLCX.HVvo i֡HLZH.MTpkoix,?5Nl422)w o(g34;9ţ0= aIlNyWy]>ڣUtud?9nssom+nӔﲌLL<iJSrFiOE~3\zT(Hi(v ƈP ꘴%Мptgk+U. &Qh[KbY3ERK)@% {D"]F#uKumHyn]tч9G%!\G3p[#97eNaϙ=dg~0B4(thĵRUmD#V=7+Du(6|YĠK'M#?)O15˰?E%^ SS.Eܹ#:sGDtQx?٠HzTnLXQ:+YLս6M|m Q4j&A~,}'ۚ ->5˗ D/>J ؟8ink2iP~g:BZՆ\Wnt'Ҳ Z[ߏ6bx0$lX_iS!!Km[(VbkDT Pt|g2&,%U nnoz)gD3k㼘|cHkpȾcn cU~nzuENtXpT(g7P}Qljvq Йض~p!׸M /.0Ɣ8m|@¡zEmò~|9FLR+qq9 5L/R("&Ⱥ>^~,sH~_O FYGW4ӓ`>*#L)WI R@B*8P^J&_fms"N]GSaXTW'JȲ5|t8Y1 ]n3W1qHCDөJ5ߙpߘfOƬ(P/>˷;e[[SWL^!sr۟TFe5EoCnX-k} !&GY2BUXh^:r8VOWE7P e7"<*11ogӞtӏ^5 -]FsH)^M KY^dlp wr 7+~Qq/z\҉ ]xNL+cA͘䙡'*-WseѼb IjXd{҆_*Cw-A8]ΦW>յ&@$v<`4 ^>s֊Ї`oiL2$;~i[a[' sQL-m7RjYr㤉C!_9 )vG~48 u@U4@WT(># GȲk6w};3}>:~+LGC$.`g*ч1VrjN}c`f|qJW@5/J}a1 FKmM ^v*Ƞ:/ h ( ^2(*vQw~PEb͢Nuy^P-UdZ!Hc{D)D6uqۢ-iu*4ꖷ%U ]F_f}jfNzTR ð3l Ý[E_4vzy󰙗/HV098 鞥Gs%QR$_GrG:]C&̔3u0|Q0p@Su$[Ih) l=TtEtٳI|1ٴ%F HPF37;EE+u6IqOҨmZ $\#H2)Юyp16gM/-RpjղA[myUukͲCM:讐;MB2Q;DLx<t*H45Z駛:&wԎ肯Nt0iZʇn5A ^tp 2pz؆cM?Cf k5 1Fu|ԅTn+J[hvv0$Ҕm0ϝ/Ku/i{:=/"8v `O](]j AѐdUsv^E% )2Tk)cT<{UVOjXuլ%nOAC JZ\IꖋCْ*曣mLWɽ7woWȨ%t*c^<>_962~% /5zhpn/1?ufg=D }`d%}NkPV!jd.uT.;Cd],p }Sy;eµLfM5}Pg!zO \zӨl *\k\q./Foܤ `u]u$&uE#2FV2 NE;ƈzFU`& hߐo|P1./]̉ %5h@NFN]QQxv(ȰKdA.0'LGG2څH9:7_LMk[AQ=RӍ_(]B* ']u7R-QS`S@:j`*Z hyǠZҡ}[plճ@Ggq.L@O9@FB=5BH5#M)_'DB%ZSA;FJd #tb{{ t{Y3v[ _Н4'Cl$ bpd@\1zx0.^Ct&+2@Eg̔VݟۄL4$_$2`}34Ƀ.N 8*8ٌ¬{uGzC2G f Nt'=i x') 9cz6H7 czHW.&Q\̴N3]|.\dˁ$X񞿳Ύ0l{oCuTm1Ype;$1bf,es9F`\WoA%^b`驦T1O#%aY3״_Kt)EXs];}%Y{%vsYw CdR?λ"/#5.d:/d.O=b|񐑲xXQ֚gͻN%i$ua&ߗ1 V܊s7ffեdQ[/''W[9DSH%+}|?j UDz~Eb>o@)#bz 9ۢ+ڹ[\QPWJā,anD$\Dp/kd}VDr*_3C< wMA83:!-ڕs(ۇ-VI)戨q=լ endstream endobj 418 0 obj << /Length1 1756 /Length2 101552 /Length3 0 /Length 101395 /Filter /FlateDecode >> stream xڤleK%j 2r׽y_7:Rḧ+VV*( 921pd,d,L-LUtt,Ф*69 Mfdio/?aGSC?#"er&63;+F:;r*vvvФ/j#@`ocCovp31uh7qw39͜ M@9:q BbdciOOJ?\:Q @^L@(+߻75_~b gg.z0kɌԙ߂Ff,ߖoerm9 N՟F+\۔D*jg"loktNЌ Kcg4_P*F?e - t ~zÈښEE䄨Crwx22p0h8lFFC*Z)1W=83{@)$ga̿+^fdwƿotWSBuU;AHXʟs?*fhkiD_$l.A;su mL1Wel`d71bailmg`}EQ;c{ &kϩw给LMMW썹:^jqh'YdC)Sx^"JKdt%J.B$2=Wp>Cufa,?ŝ $ b);!joJDK䏳&S,Л^KFƟ٦۵04wx9.Ko=3L2U dTK"׻]ѧcQ yffqgO>>DV'2[߼i.l'co̙(a+D^`9Hk_J鼮K'ZW/E\=NEy <ƢbsjBB m(H5cw,k5`쵨6JDC#ӥ̜6=lv'%2x#1i 6GՈ֝$~8ݱ|8k*8m7בՙRA =-;0褞0" sۈtM=1lDnE] ט>6 d3͓f 5X(Ӻxef{U+U""m>N[gFwe_`06UHTѾMȄ` J!rL^%֩~L~_)-ˣEOEjOr4[T)O4%q%a }QzNgV5~*\|x}v+OEOU(#.r7dzU5.'<#i833j3DHCه3V̉P"nFAt4Xa+K~B:uARB;=]=i8[΃DF uP;l}[-[X:ӢA46#sKX_t#d릫yJB,IݽHoT  .nO/c ņ[=΂OvX\MgЍ4cpM P{>cBO@cP_)_ҌΘ [軚c"V0{ikE3|#t넊4z;uH(˘Tn_]3UN!j.x2P 9|6䃃 ?'d~I5L46'=` Sat}|l` 8>L[_k&UqI qc([#\*@v:niZzNӢ  %[&0n?_VnOi2' 꾅Ae4< $4ܛc*q_KVv{aث&ԉwW kpdџ`'],Y ;E-k9MBK7"sGYp6ųOłk@ya}8Y30v8TO3)6D'DE߁)hl:vX"jGu&z?b6!f=FC4LV;=q*ė@*_gVY[[× CԨmDjgZ&WW1g]Yy6hjUSa9B$tBn*UbT }tS8ޓ|<{ 5qG8 xceum Hs{ˎWbU0) >jS}2M8m9;橡`ύnNݣ^[V+ s 7[QܙL!Eri#8?- Y{$dT76Dx(QDUt]6ʎcFRL`t]'64 U Fݲ֒~zia?&]NUJMx'+SZ91~%ݾ+[f֤ ;,SdѼږ_@?Xg[cǬ/ѣzS&q?\BcvDcsl!+S_Y2_!h[*f܌a F M<<4<*4CރGn҉#O=s%֫懄#Q>0(=OR02'455;%Tb4a=]j6A3 )͓*݅0oydB.` .Wg7{ßEӞ 3 ` HjK`!|)b;g~Y>&qZDGf)s/}0H Aw&S<:,us <e:d L5$Wq= VJ6'˰&v~a)n۬_E*)?>*ѱ3BAaQ0_Xv+J;S{aQ |ZB vT79{nzyoՕˈyˬso7/.޾K {i^_3/ H;w|Sr0cӼt͑\PG8 X 8; J|c-a@–(%uފC ! N9sc6xڶԸEŎD*yE/\ /2.·YG$ތ~--WB=h: !a9YsByl..SAR40ɜ"/!k`XR?&V6'>ãz9HaU 0 Ŵ/w]T"}Ҽ_U!e_&Mvy<@< <Mnqp-z.#o9X6:.k׹}M(=z yԬ 7% ܉:(*u9~iW!l9rG\%#[pޤ ԒP?rjoGp=˓EKjjEF rG}t ĕw0pIAw>ii;҄.1}uq}Q8?쥻ǿE!u;庾#{Wcˁhq! 5O!4 yY;L8Pa7j9Gi}!<>2t50ήK#No VT R?vfj|=&:4&Y5 +Mr$!.H3+T$ޕSfaF{V8xv+]';s ~JzcÐu$q:0P̦&Լhr )(ࡓ+|y(F$< ԋqطz[rGKet7U32THh/҃=>x֦݀{ ,hryЇy0} . z4)2t+.Y؝83x9Bc,TrȨ ~ӭڋa#r@j~E$|IJ97hN=$[Tm|L5-?oqz#+* D[.~21=슎Iٽ{*f?f+9J줂u:rIGذ30"@X-e0f6rw҅̎t-EI(sMzG`ych&A8- V/a8qD@MʬiɄg.MX(x;¿"Hx 0ŕc@U/6zYC \vl7QeO x&by I(:G' ecoiu!̎)/qP:q-݂ peF8zRT "{Q1#KMYNcxbLJ4s© zQQXFBpJ0Fmu58~h[ ~`Bd#IfM UC/sV٦aSBoMT {=ƽMk6wㅓ)4ljg򕁒H?=gX(-:zf{:{z&D>ӣb+eiy?}ll /69+.Sr\NW# x :{vݫ J~v%1f9]pýӮ\BhMRˇ" >Axf`?K :g?!js@mچ KwHp\hԇ&O0r4)MEnPM`Q`ɳҋlKfDlp1d>fUDH9[3:=fدn/t5 (CgS@A?*[ȿeҳȾ&c2O+VFQ<7>)92ltzC2Q*˛_O@!ϟF6?^##T Ωx91NCZQ51pj[jsSSJRu?1Ig4O?x`\+/w#-[jPGٺHčw*/or޴:#jlN&b)Q#&ϋHk3gdcOHf+^8dj@u(&m,/;!YU<bˊ3`)k 'c?za wF v] ^ Bz6=O5Q)c<9,!(6!TAL|Ҏ[o:&ƌ c.5 T FvUrv K#*]$W&+moU/@٫3]m[}~I2^TĨMXG5Dsfb/ۈӮgU=Rtc3>GLi/:#Zj\%> лk{P]bs%DPuh'YSqvZˉ.]`esbH.G 8#?1FʿZQ apI0 俐 i_"-sNicw{L'q\ҍ"cvA1crK+ejܴϐ2i} cxk̬,]l(|,cK̀G[ RL'`槆94ڶ'YG[q}^> ԩŸebҰw7gAi,fpȋ-o/OX}]\-WI帋2t 8t~*> b8Hg+E J# NuG3j'w0|2U->[|:YxVETw334$'|ua^MW$XJ8Ԩl[3 CmVEY4)Y[Œ}]!$Qb#QAŸHRjĞ+hv4k/3447xZ+m7hjmUIdphݟPdj0 +z>۱,/hGҔ=7ly}R\:=6inD]పOnqzĊn@s8Z}\^(scqn%;ƻ%OZ|[z>,ˮ`ӣa^ަ%zVccy& 6#t$~6s O"V_}(x)GGc4qY&qBTIWA}{HSՈ憎 c1rnߦn#ؙ(I'A&Kn.Ryas!'Ie-lXgs%=$J<<)jq(yP!aMzG%eD!pɂ NW >'亦sM4GD CQȎH1CL8}A`|}ɳ"ȕ,=S2?H{1z=77sZ+^ o;@k8ٷ3q']SxY1C/!J鬙O$Lz`Y؂+Yc6iVQm (T/Mz6:p(@hDf)E4$^@x 5*a #/Dž0e{6}Fz%lY;Tx~J>#Z@yh&IiwNknVCRZ!~?\ZwOih^}p_YƤEnrq\Ix郆sw"#5jwhCHCaxPk\ @Ʉd<~r'$CK07c1O1o'r%=ki59TG8jF gբMo ]rDɄ PeyGrwLװĥ̓T)n(_t4,ldO -{wHH+ :x3N1މ3ۻIO8j )v"V18pցw3@Sǒd=FXJ_̿+'x(l[Yτm1źwB[+TR!7̳,}2( | n @+ kO8`,dY6>_lﳬgڈHp(>oW?`g3<?54~-md\Hˆ"d3,Y4p-. f3P49GTU^|vJgl8c,ei)@!$B'T)dqĎA"ȃ.CVe\eOƊ[ ,,<./=xCW n 2}k.c?X\0?Rmy^cNR<鳌*tH7GWޟɻޭz)t?ov[o@1φ%0Ϗc.B cxO{.c[Y1yY2;6Z𠮩hNck-l!ۥ SȎX k_5L=4wl6=.ifp=^)HyBfr?d6c =mEɸb4˃O2Q9@β "oZ<6CO "e6m0NL~xBo-M&/fLn8QqylyS\FdPʦW1/cS _~og@㓪@Ӷ :[<w,ٛ'~+qankB^;XհB|, BMDvGą]/p\ֵkW"cX1^ 'eP|:xPҜ,TcP)kϗnח7 wbji4J!0XoO\$m6ڷQ _Fa䔅~G-~,Ѿ)J_US#gԌ99Uor2{mjen")UM'p\]gSދ9Vkt&rj%cy[Q}8k(fF#Sc Rӥgf8dnrjҒ WAj2z8{H1pcrcn(̈?N5/Z >uV&0c~HtLEW@~mɿǡH۔mQ:m_x`9l9Ih^Zm!ɭb3;LG+N#(z̻y|( ^ .,-zRwrd`b_'cf ҸZzN_n9N7Ovmd.vSO E6NN-?|/gH(Sx%H&3Ia9r4Z,haV{p)^@Szma(N#ןWl¦OV%Ȍ>t^d1?+,t$GBk=RAn{HT)v63R/ S~{DWNk.>Fvs?*GN$],?X05rrqCQw:i)sdJ9gH笇U@߫*$%eHA/U [Kcůe)s _~mȥmB%խ&@n}옹3mB\e4@DUl #ҩ1E&\4UEqh}ނA$+jQ3dY ެ@ȭђXGDTPoh+b e2JZ= !hgW#O[Q:hލ }4j􍨔t"7` ox;ѳ| @SAʬW%ba4桐@%=2N%kԫxzg%gPQN)e6^g!Qd5L2Œ6j{u"}j-UIQ]#F75bύ36K4dOH墅[ދy5s)ȭ\0QB:뾀= $שw1tXQCrb}PHt*g\ؠo%lR*wNA`nCS7o/Nq3 Z` W9Uwq>(ĎЭJ0LP?ϗCDѺ6u_@ 5I!jd*LghI' !Q-Nnۥ tJUR^^#틂ȩb`A[f %mlp(U~(2v\rXqHmWa>ĶYGFF.{`2hI;9n7tq=-CRU}ͳ y]gѮM|6Z@"RGa@38E|.}e2RQЙ)% QGA[{_d3]gnX`MwN:hKlG:'1C0A$>PZyM\1b"rXmHqrtLx`BᩅIltwjP族`E1 *-=r8dh[}ׇV=LkF4ϥ|LBaOPkq0SH.pyْc XY6 sDE2 KXX%=&V'8 rJtZ? 8p\cDC35ܘ]z2^6@@l-X_9awI% 7^'梜zPFZ9N bFZ끆aף=CӐ:ֲ&@ ~HPfsܟ6C&:l?6سpƾX6jWf/L֡AHuP`Z*jhF ְ=^ /e_=l}!>wZдTOg 9{6Y`^f.8528!n,˞C<>);XzQүoi"DP#jYFB(q{tGcU{q0匿0 Cgf &_b"-Ś270ƒ?_AIt;̓P{I14>T}^%>Y5̠zQ|-}048ƻ,q9~44[0y\EV Y0ګ‡dWG5 GC 1+6;r8E {Wn{8\*%VoPeXB0MGQT*`{~6f=k -C$L *XBLOs2\F^<8d 0V*+Z=+1P٣U6A$t-s_.kqB Aa^R9 'f5@1IUgyp,uTɴYnCS~;d-u>NȍkR(=]}N2Yʨ";&K%2f#§ 8J2]`Xl{zTlr:ݻFrfdC}gtnvgqvWЧyQ)ڸvU ̍1rSb < o稛h~t1%ЫN ly }$n NDNH% 2&v# Àl#< 3M. (%Yc!й(^h 7DV(05Vp0HSZ.sԘ( M&m"z+͊%1fUĿrEWL?A?n+Ar2^U7w6߇p m s(\j ?Y]bG ۦY%v5Х'r ,_K]o۱U&ћ 8>{TZ䰚j%°[ocYU-r٦kEZ/kuXFCEi>J=eK Z;%qvͻׂ6r0j.LtG}܎_!h KVX -[Eq{6A@ixE[_ /K%Ta'`wpE\P;dmКZ0y,´h԰H3 ϾLZ1A\:4XU0.X<0LDo-x],(E9Ldh |qGkGS>zf1 Lwjkuc۶m۶dc8VǶmvuuqVwzChZwfQzڔgoūx~k̴I'PdIMQ&R7]r `[.;5q#n&{oY$ydohu*sQs]/H(d?2ܖMIwic(n֊pXxt|mhCٚUURҘDNƗ ]_ӛxLƥQaP\\UH [bQS4-/~~:,@p}Ýfd5=$8n&HДժ6}4nzwDC|եo0̥Lwǟ `FБ8ACdV K&:TYJE#TR?!N#1 1KoY1(:;_0p%FtQ.B]mx'Ltw4_ / /gn2 ƨKYn8GwTTLzNGH$-ƫ #Hc>`FBkJxLqx$L =u,ZT ?uB+E^RX uUaa:;nk:&g =$sEA{k[ uZrmr`!p8a`mlƶp:ǨL/mݹV|YJir|7#[d Ch~T%37(BoI9YC;_~~Ύ;3grfҨ_w¸ u HUxFS-PN&"y3n.B]2$ Uq!Bښ4 <ų#"|UyAiŹ%  :+_>';K?v&O"`4h/z2H<=E]B ^CUx>i;'d BRa':1 W:"6bqۙn- PTq')`o0_=6:?qF-X ;Mys+NW5:Nԧ[ 8%+s7$Dx"Č=Ox~Cs@yMZgwGDhٮc(Y;x2g-aٙWQUz?p,5qe[3I+?G?B5@ͬb+(h53%Onӊ@n$Z>;1[ԢERXfנhZ!C0+ 66g쬶|DZ%~.E}WV)s +9R8dkWzP?d%B$u?rV c 1AWy7,g#{?Coq%I=:x8'*)tYg7d|HXb33GÐIv Ũ EvրY9# ^Ii0 Q9[]Ȯ1 $ʱ;]q]M gւ`~]ZTc!&qv7R^kY13J(aޛaF/EqU!6hKAumlMUF/p[mr I0F f })k{**dƢ }RDNcB`; pR,*WMЭ,/w:э?..Yv% 1"nB0{oH^z>Ωgi Im\9^o]!̙fycJ VIsDZ>ti9ePE"pQ/ ⡆:g_V)$7gîx%-фE),LAg_ M@P:t0-˻(Mk+2wdqF̍pI*Xdnj.3eym[nqTd߆m#^Q.oM.YRV#Mn (GI ϿiUe. ^>QrK jeOk.T @i촤~A-kq˫vnN,8U}G'aW29C.焦6"ӫSD:Qy~͡5/RLY7)T7EY{ee<()ZʺLl=|ˣ3\HP#s^޴ysOq>Ҡ-TRdM_7`.UZ)]~0z*G;t[ GH+qkZr3cF$M:;2*"@w9>3{1AȬjl.an qXzqcS. NB/~E@d?5LW=)dai Tjlۦ\p]f;پ&OHΜ6yXqV 7S^N1$FRvLP>]׬pP0@0Ph)Q|؊&IRzLwTl+_w]Ӻ7W gR(JIĪGp/.Uѝ,I W.}1r-A7wa^rTj7hVXuU-d" *{Cf)1W{7w"h;+`)G<ȅE(dIe*PDdZ-+ޅgwp1|sH95+H,m\sy}\OJ];%EGX ER+RTdY)Ci~)jY~GrTN|&V9f+, J'bI3#[ [֣Ba*!ngrR6t hwMfF^~ˣ*eaaZnn݉(4 TZ:`Ec?*'W0hǕh,g8_KxѰ$or%3u鲕{zEm4lq|R?IM]ZX j1h  *׽S* 5 7C\l9QZbp'2$cS;3#šA4#f@eݵ+ҧ&F'yR8܉NR !CBez'TĪ(WwY3'EJ#R@}7Is܇Jchּx㽋~SA@-yvL,3a7Gσ}<^IC yUgHߧ\<+VE =f4> {w$%Ub\ɑꜭӵ01Bӧ0v!lPAO\Zy%p;Z!cLl-ݪJ m#WFIk7OcwTHmCo\sʹzf jC8IKQ'$J@G-ݲЙ|=Uyo=0 ?^ͯrnY(NJ;F 7P./zicB=1] &x= Ӄsm벷'4"2j<8 |vka{%'nk%,)4vxQ_US) P"Π׀{eKNb)VljԚ%͖Qiڮl?IP28fb,pu-ע`'|;eBXywͥ@('uesĞpWE4V׼^K2Creiœ_>:*[\L.!|l DP*>VI$8= $(4{[uߟy/7 pz|s]Dz.-9!q<ѯWy ^mlq꧗;o]}4y;@g&9=C@#%M@y}6j~ T.>j]cfB+1P;Rxa0Jo㐈֚ >WLS1<)^ ՝%ŒWIj w# !ɕل73v DdЇWz? ;@]?ECzSvnP뀤:Cxq  Z1Dوk&rW1zgeީq g>#igy/>'~Yv||]^%fKڤЅ}b42pU"YYYV E_gȧsm0g9Ӎi8DmSy|1.V61`?7?ƣ3<7ڧ/ +1= &8(t&5Ta.[ I`] h ?E ΙTjh9u{žV :]U,Hjwkw!:z u8OT吏GO_IYXYX;Lo!ZԒV 2T?%z6xXz~YYJpZ)'ǝ  uo?J)gt:x0ր\@_(/|%-ga?8F)=дi%c}O 76/9Y8mްÔuaW ěfx"lO\8SHmЪ\!ݢs7tl3LE4IX_̜})RERtUOv hH^Y7ItDNgm;e-^jʂsԖw)D0kXhF4@Y\; se` k,I0Su?,Q~QK9I3 ;LS-6<` }s%ˏ$>wy+=wgٍ^7waYJe C#CCբÎnV9"` 2QF̓yI/Z;|x 9}<}tiUrZk *߱TDy]C󤡣Ҥ. zX_ZY.gyK9)DpD|e/mSڪNňJ4Мڦ%l+;&Kv0/C.Ve0fܝ4Yxp];5˃ ;Gr!E t-ZDsoJ|v/j o ?{m{7Dd@u 5`r&{xƥId%1D5p-p@J8 x0S ] ӂ,a(`+(>س0C6W8Ҝ:C֝ !mNU~vTf%@ħiR\Pո%:݆$tTfa4a3Di_Əe-\=٥fk7>*}#,Ac];QXKf\Jt~ķ CCi KޣئT1<;Xk聴k{w>dLf![ikK""E\U wK$p3Tu5EuPİzl7xggMgmW74?KHCl[@ʋ,O(^V{#8V2#uy\Tzt}IJ{vb&L|yhʄ:/o[\eܔ9")\_{xЌrNv;vHz-Ѝ3,?~sn K+A%H)A)#M2ɦ.kM}Q\/]طfMCEV]d!SP+@ORB,'+ޡᇁC~\LJĪPY1to)˦$V0$p>VUHo-cPC$@}&eo: KeVguGX!_՛h,7(m};o>>:/;4)pINfK(2Zmg啰\ӗC`;t$B8Ok`Γ#DK W] `"uW&N :[?2 X֜T0&MO2c|1tA"0s GO}mMTߋFfԩ6`uus /,Z9W&8Le|pTN{RMB4Mslm,EV6-)+Z{ }fg!ە°#&}Z !jcSaFnEvd4~D/BO.TGB ,= ^\T &T4iaEțSj- yT{ a[%8Lr9tJz,Wc"KEgg|mr$j_hs#",Ռ%UΆ r.up%f5~ ё55JVk 7zUի-=ޢ_ju ̅'zZۮ֎/"zT6tsM%M#O}J+AɦsGh= "_t/PW?3TgƏ0*~g$^>̽cf$ZW<^8*!$Ңv}0TҁuY $feDc,y u|{>#iugMʹ(u4p$5 #vHBI(76> [MИ`9ʼUTp&kJNP1".;0:5yJ%a$ qDrlgHhfWkH>a-k97)˃.nV$cQO|zѲӓWG;uejy&v}JLk}>,ZWK'gY5RNyYD)y9Q܏zYDT4OF !y3={jԝfZ8KG_&>4A3C^.xC?]8;m na0lA <`~(}6MF &܇4r&m ʳm4FhEXܳ2qc>`r_ΑU!3Zz[nB6Ӷ@tݚ [q2`%PӪ*]ɨ ^ǎo`dRc4  }m)Aa6a @'k3ݵIC Gb͝I:O+qf<# :HkAO?(HC==Ik7 ?z00BwTlͰ͸ۣW_J0vV̑DŒ%f6pnPiSqMZbc|3:3ս\oܒaj;$h2M1.Ɠj5ur 8~2e!LM|@^ C|KݮT|-ë e1xiχ](9_2bDCB'iɮcG-AeF:ls[L %x9Sn4gKI)3gMf3 Z 7 ]bհͷm*sUK}vj2SKBٮxO`hƺ Pu_@!ށK|U-%h%Z9oV#xwYq{M/?7hi Cn<ave Ɠ2iq)F|S}#BѾyaFF^h)†T[8d`Ywsѱ`M6 O4EXyxItk KMY驪&+ULUKCZҧ0a%0T zHemUcGVCؾ!VN|ČD?C`3I﹟5'V+6]DPZv_=D- RB&6. ;` "KvljBm ŻҒR&,yCw\f\2ItlX@Z~͙K_`YҮuǁ_ !oӎ-Q]!]v2Q*uގQ;1~lO_ T׿[7EoG xR$h*!"~PWÓDrNV A?fHx/C~5М#622W"5r3"N? G[Oc҇/צ/.Skb6D%[؈ p+V YKmFYжp"^6e ?UchƩ 7n¤ˁ6_aP]d{*]梮WS+>ᏗIwG!,O0<0U':0Ɲ'i  .Ӧy8hݺ~sC4<5xe/1 C| p+c.sūM rm (EϿf!+pB1˿@."^C ƵԱ6'jչՅ&m[HMeuEo*6D&˔&S7@ ݭA֠;Z̅'%LPH}Qjd; A4l>.k`s=%g8Q9ǬnΊBgL_բƑ۾\7Zf: Krլ f~T4m)R$y","=d }͞Φ~"ap Oe!q%èQBC#^r~=TGj qq9:&0#ny]WB8 }uh]_4=mF'VJ v,l짂n#c:C>`l>Iy1V)@";1 2f,{ Iiq?PO[`taqG:vl:M̬Ln#Zf8CEBj_N.P7Ns՚0%!ubd#¶*vh6*ׅσ~?RE芆iL63bKo#|vbiԸ5ngnD4*jǽ|3PVYs kFeэث*R{bFrgi٠5̬diz-VMv^+Kf*CTp>HD2G zcdl?S/tǿ*nj$S^͊gyĜzC͞;w}P d tmm0gcsrHFx`(5{AI&MD&^yQI[LTu)Xe({%ׅZ?Q6i()%oGE"zV0/&їٕ̉ԐW(+f$aO?c aε;|pn{=Erp8OY/NA߁~p M.o?#Эt/NM|DTN;L},"c{:Qfϕ>P'Wj%6;?(/58Ynq^ڟbՆ(Rߙ5>iTmSVCE4E=%sdU j9J؃EjI?b߾>{簳M3 7A]O܍Pٲ@cqŏfUb4N@2.+;$ƭ\% ^j Mcz Zaq_Rdy;2}-[. &q'\gVYRxXctcAc8XPd'H'g@MNq`;pI=7\%O#+=nΙW*> 0ܮU E]6'wEOvqm 2p\_Lc;x8=Tvw֋/#07~#K0OxOǹ5賛PQG':;D_yNoa|ydAi[6(@NW2̔F\^0΍cJy<$Ed*bo5*b`0‚ɸ 6{v$0`,کy_-n3U/񵫆eΰ5/sb($V`1a`9o`όO BxDؕF;e`K 0!-#P>@+uˢ(@ݶm۶m۶m۶m۶mlz=jRʊo+'-e'Qd~s6Z\-0&IJͽ/9z k׃t2rcc;A!=aJ(5{ܧm$۔V:M؃M(O K_QOag*;PW} YHѓwg%,"0xt%4f nU]ukm&RW䚛Qk{C>ևWr&E-vAdOȧXZ>T*D̨[f c{c{.@|I5X}*FǪx +$^Ɓg+w=㘕nn=\~A/RaF@:hMKM5ۛ'hI YD ]4*fЦ܂~ogYy+`Z2z$xQ<j:>qzA%'$O}lA5\2lg qB̜>OA/P#^GZLvme(Fp,]{N\bдj%86 w3uEspzm* =^:s׭fC2 Kg>&\{2܉gUa\hcp%s|fob͆ϏƹNҀ84u Jr 4UyLbsE%o(1N|T=NRt[w oLČ (!UQM%pTZ$&DDp?Dz[D,6xǑ^}KT׎/eE^̯o<:6u 0=mԌhC"B5EpZ18U" "Ta0ʀHα'Wr9>-LGk1k?ǎR?w Wt3>HI;l5+ +IO8'–jDC i+=֖MNh1Ha]^9E@÷H!dži3[B?8:HO Z:Nx"6/+4䄯/PԷNás1M( VӖJ n>:O !n0a5L=EewhR`?" /Y$3,2A~RFV1|>?,PA9o%GHUXKUCe_6Kv s74p@9%5smPT=V Ãc~4V\td'$AYqdO{5xÊ&ϏD4,@Ћ rƷF,M=&SBWI.". B5w>r#l f z'S hёAT, hoJYM˹nn$aY?7.GXgx:4gR0Sv~-&JDWVk#&+m-EŵhS*T&$}Ԇx0u0!1[y,^9>v'I:J,W6]y0!DCG ze=4]`/\QEX6T^9o>,&wK4b [Q fNM 0B$+Trb-HMj|Jk ;& 1H5SC?XDN'dy8~IdZfB/A_xU}"-gZCL F[uk8TMël *m}U>[b{gnߌE.="Ո%Dv_RmҷO5zm7 Y^y>KSǥ K 07UG$Ւ".Ͱ{c \L9}HinD 8L&*%֪[5Dk{?aV>IUjO`WS8"#[0iARShW)tfv-QMRXiQxX;enya$HslwA1" imhPyZW&BoFRiVAEJYI83 NB:3.[Ẹm6A,po7Php=`0@C[xQfoo-/3͘\=TIvƼn`v4j3 @L͍Tն4 1*\d jL`MIE֬ͬ# ua9HhQ?y ]2eL"  j8VPpX/M>~\ J$x]T}Z|R ($!R˒ǟQ W֙7t~*` n EM.GYX Uc-O1D̼) 'nɎJ?2 b[9|.üP JO4=K"c-e^\Jn B"ɛ-M11= K#f:9ۅhAY)F-;*։|.Zcqa[ LFtuFFW"'^ۥ*G\=VAlj ~T~!#KX3S(Jg`Jʜ.(CJS;)`Ǥ?Eft;Atlz5]O4eGUJ<l-"DW &nk_b$6e(y8+䟰UDWl⧏^] ;úpZ_}7*Fa+?MzZNGk:@}[Ob !o"G.z Ż]vn,@U,OQeö@FaJTQ2a#q /}_aPEa \w?f+n/ObS ό,&UD#R.uZv4-+3u ފ {!W,+H+hT*: /] U@<_ޒ:K`E֚mNLw⚡P1<10_f[z 5~q.pqT6rܝ/$Tt3,R&1ڨZDE'%=rʿ[/VJ۔ٲ=x'QM6T)z@J5&?hZrm~u nٝ<;(}LR~ϔL!0 Τ 5(O~[;þf Y6k}^"qP?m jWO*W `%4hO{u PZX˯˟1i˒&"-Y_{s?Ń/ a%s35jꁑ>GeT.nY?7;op4^jհz/i䋒}3taѽՋm;]I{4!Ч(րqZPw8XTlL^jg0VDM&esD8~LqB%өiSL.;`#WI#{q>ʛzpNKJۚxB_Ƹ';'#b:J:X}૑j$h>ԿBr NRfۃ IJmrB#r^ Z!_!y ixr‡ola藊ӥg2i MAqsNGT[dE_n!;va>obP1mrW džLL ~H}'5=Ťv'#d*甛u)*<dŞgn5N10E%i_hFݑuw.,EDf)kz?AAI1]qMLW?0a*Y|vI^J[aPPC@ V 3iIbHCkcwWn@}ӆ 8g 8ȇ*A-2VeE "֓K~0|=M@V&b=tHM]] NԕC a! }~%UWŖ-f #Y@ VЎxL<^GX(`{#K%] !ހ֒ #HvOߵ[K6?c=K.2 ]v9)iV4mfJ@0C%S Xyx[6[Se5 o/74&|< Cc1Xq 3?J}l9JF>oS-S7?z3e5 1¿6={bK) 3[Jdaw_|#eH$"(q^ c YY3%67F8MUəVk/ƥK3]~a6Ů*at9P N23)._c'GW(V,ꠚsA6E2l Jb]}RMF]MnR 1ܢV[$Mp Y5"! &f{t +[Bh쇷Q2,  -cjFeCoRډQN˩fIwXNs/)tiIt85iD;L߰n/W<+_cL;#KJkOXR%ZI Tc؇[ ̩#3o l]\,y:FnkXH*uHD1Dl?arﴻ@/(Iք T w,Ե#_1!Fu-9d۩^9[<mr1:$j D_>&PUgWX|KlI~.?"hcC[tLuN'ݶ @:qJE+@"R\<T7#M C>]HS'l%]0vS͚T! TtSL=bPZzp_/"xD`>RD]v~ܲ^x٢ {k%͘{{vjUMuc+%%k8Fo0 66\M;3/-펈p7}r1MuӺ$(:#%5dIg9oH}5-w#-XDˆ@5FBv Qɯ# Ĭ.J!zTO m'QwmO*$~~]ؿGWSPBOQ>ǺLIun6)tW%:WVgtslZZENt[zsu2*FW&|}Gmδj&+lgB)* wU+;k0BޫדU E9Kù2|{Ya#G-I\=1$7FUp8X~KJbAUS F7iG[mZP<~taNa4}dl܏.T oȒDHP JɋjaR(el (e7@[ 6MG̔,Bf\aTdFO!9kJuH>h?}նfg >QVb0- :aoуGH/Vz٘fL5avrO9_m/mm`p/=LqC~El#&~#9b -sO'g;ź6P%H'2"㋏BsxQRgl]2vbqs}rpǣpCp7EkU;pE@̞x75# N250`@~F~IveQ^ߺQYUI tq6 Hox cO"?)HgBWZ, Ʊͮ>۷㛏x=/`̶_ʤ2$d診&vp̰\/`" d*8AP42#:YN&D5.͚+CS51jEMȉ's` xkOllq=Ii/]otw={ԬhT~;\=.ytd;l=j#^#4uY˅;~i9eɚJrɀJ cX1e.Cgg!p#!@ v  v:Ƃq^Z(~W-i\'?s,.!ԙg/Wz<=1ȨoZrd+OoKƾW=+pQUL黴a::<q"?4Zd!qOSy\=!KH}?~CsуiSY G\Mi"Bp$,b_,y~mx9tC DRCG$4 ﱖ$ku${QGXwF[K~ 5U?p-uYQ|S>s?@.f,n j:g]9RlEX s9B|oR 5g T/L{B%2C\!NǏZZt|$/ӷ&w+կy$^NiN}Cz7m fCk rVդ7*+< sp_ߑu aRgH!}EK9)#]ΞMv]7ωl3oW^Ac靎YZݙ:O_n*)Xϖ15KɉF\` RnLF@jϮW#oj˄k,`;1&Vp{YAps4 c1}|gh JP|Ai](z!/BeܢO ~2=Kwo[CR֡q!N2㦙2 uI(epءGԯv֕MUO:f Ӕl+pktgȠ<vCa&Eq^o_#Rȕwϰ8d>mx#R-LahXDJmֿ&[ʖgP hOIO#/9x 8 ^Y%a-[43 SĶ@H XpGapx֡f㯆,b@Β3Jf4K>Y]kmU$$Z,zTԐOY<#QD/žF{M9f}||SM 6rh!DG>3MUb.{D&:@H`{q'80]6z8x]S.赅rf3KO?9g^C;}5' No쵁\f'GKE쁳~Y,V ]cV79o۹ yTtϙ( 8Q_|3ÿb7#I鉱ͻlՏׂ1pvB@ L{@$)I9%ap :Mgz/#I~bh7- FRlRHuƇ8mkc9>Đ8X,_eb&WC.}(Ѳ$EPqAbӈY\Tw~C1l9C<'y7.+ Τ 1͞r瑈GYJݤG뷗g7;d j h\p-v`Tsnm=g"ŋ9gkTgFTZ5 9(!ڛ?k}.@z -WB1Z?_3_`<.|S$l1BQà lQk {w]xEp :+%W@4  SkTC!t1Ut+r[V3@iz洍BMԳCq@MKmy<:pW0pk[=$PMeT&tIJ$sgE4)lo[QѸV3F0绚EQt{G+,FPV=M;6c*dhQ[ 'O&꛱1ERqYFggy}}%Q 90P> Ǘ/8l:;7:KBk,#_qY0ӱ6c^TXø9jLR=2K-Oe:1- lv@5u!Ũ2;[?=_.@]Gy̨>%m ^yzi2jTsc'|Ay#J)o /ⴸw榆,nMWz~hi7lnK{AvfQNt0u@Z_ͮ#{}uԚO2Օݵ2N% ç )62I(FǶE"xW׺!WwU (HAB˴Viʼ__{w5Mkqޓ5f8Z\#23|Z(=feu1 "t803.m ֩-5/np𦁦z`skd,@@Z&hK`T>d{Z9+)r 8ި ]U$i&Kד! cc&Ut +f0 5kʮPFNb`Ms]N€2k,6ox"1% ΋*-3];?}}ub%{sGǵ2g(oFG?i@s-%@~;̨f (S?HU]ݿNg2y-veNtFM.87Ζ.'^fԂ\!FAUJm +cNcMFHX`A$S:!>$A: {N>7b.#ӉpS)0ы҆{[XqA aȝ0H]F3ڪݸC/ 9[etZsqf28VgD >qqGd^DV0tI ["nAMͥ SG9uFv.?|ƐM3G%AGANE*qY. )KMEw?5Ij $ҙ;/c<{ S86uJbP*? Xh-bwY2YB{iQ)k9ըpIj-[؀i펾#l2L0}!+cB "5=wd'H:$!V# EohgUPH 7%{a]U`#Y,fecH:`R= rskK1c- _k8>)aL?%BKm1jߪ8B\ M`~t)72XL7̂ӻ?v:k77}x124UYmBgπVsfNs[\GSW  XAN:GRkn~-Ja~Y 3@#ABbm^o;wsAU;n&Npԓ³Ua ; M{Ap2B v`*|>)Y(K}IvV^_To{i_;rYEW0f ]y ֳP9i 4<{F_6  {[\Mѽ`\^ dPݝ+k>$XyvlHZ9fqTt2,=-If)CBE0J* cu;{F-Õ{fd/ ,~RZw 0%wo;S; _tbG31.~[`W{s+vTj::(,QU5s;]ǔdcp0GL|O1a}ȱujADDUY&^/4U~(|*ۺLĶuhS |Py'_31לrf^G|<"|z[Nj[h.H|m4{U:]!7$e=1=H ͇I:\SGJ^zU>?=WQSeiT.@Z!DiR1frۆQŒSW3⪺drFζXv@.?j(prkx0' 31>a R%䴼䞝d\9oF<t*ޚ*~rYZ[d\5eV7*?p06ȖbL$and}[ChE~4X5t>9 L$غ\|2OQ)ji&dyQY:m%]ڗڞH9ъR/^4VVGV[+8&32zyi+s<*qfڴ?:t~.b`wȾ`ct@ I=9ZڿdTLu\=bهGf.2TJt ǿ7I!6l| ?ExՅtK_R5@ a&-&~vhld9㳪Ƶ<"rNLu` [A9<hQ]bSs^zwT冮 э1#ɃJW+,%ax9@ Ec 7V#M^sȽ,Is>Ƅa Vm~ȸN=7% ]iJ(:AhwpH6Π4?l9d/"XS‰̶ !fɦlb|d^K]m\ǐ &,N.@BNaF[mfebPϠ[XJhP:Jև+)DDvI(i _NyIjC69EKz4WQc$[1zId% djbY'-VߺJ.ك "p n(#>m_1d,T㆐\pv)ozNVT ԳgRz}!Ơ\hm%908oB,fݻ|5I/"5trxtae-*͢.z-{cb hoái Iӟ)w+dxz[7=2rFT"D [|T$$.Vc@xɋ3")?^^COW\÷!n-vo|#'~w0N8k`uIпfE&[y3p_? QŞV !zR`-O}U#Jvl"L˴c<5qm518uNT ZCUo>#Ji(Zt,̷ NMije׈Yj4B"оZuj*|$6B+uIW\l YPr1Ef; Uݞd6z8yM! %yԅׄ (}JdC34-u$^wDܟDmQ1g~Ƌdl?S0)``*kO)`&eIJaTR}XL5SLQCHH|(ˢD'P'uM]&VlL]+:WQ".ӭ&}'TJFSdtsRAnm{~JM.KpFhʛpoBD> ^{U cw1][{ucG߾? K u^>VW+iz%Dd _PJl;)# mܾqx=(T=yIևA9l?"6@XO$Eo4'w`9PӓI-+ԐMX  ib;ë2U4gq{raܩ{TS h1kY&cEl^`} R \09gһtVhLA.V Srߑc>͵ԬV*&tC^=$T@ 9C.۶@n`F9AIpfu(hVs7|n֭4EYdnXሮJ=۝Ar[?-B[Buu~;> q%WI)*(pVvhY _"%Y1;.CF/-5776zdVU~TƉG:od:KE-c#.1$n}qZʞ*RR~Vb|6<2^y |F: 2D~(qh*gήe.g+yۿЌ0 I*rA;ny޺\C K_-ǾRZ\@drVXfG}YZFv,Qe&m>?CJUw(%.)s^;DD`gw>WʺEd΋+eKc0/X'Na=9*iTDѤ/|J,Y/sK# D8VTŋ,)ɔLۄnU.lF ΫCMd- u,o.kf/'ksy@t](@BlKr~-ƻo`;gdPmjBNO~NV!wezw`AnK.Q}!w孳BrqN 8x!T<[V0Aȿ7ɞ; \NJQ(,lO b.bm෣ lxrdq7}*Cܢ: 7웱옡U]Om%u\Eewk Xvl&u< eyY^ŲpO+c\qraa^.d4,"J۩3MS,aoM)Uu/ LQݾ5Tp:*'C3X$H6xŋk\pinc0"\?y9=8,1,o=DvE3Swm|bT}]զet'|X ->]~k03LQ_J3?LHEHrCDX8><OZ򘾳DWODJwW0RRui`W=@hϷhPT=3*&bI\񔹹l?*i @QSHs#G'(oƏGt(!n7"DwsY)Qِ#tf'Ӓ *{C $K |C#FdJ>7 {p?k= 4ArbͿ*= tQu`I7ɗۡ,naK;܇*o'#0;RG<߃b7I F) l1I}U*|j_7O1s΋{V @H>h-Um`蚥"75fJKxIif._+_ "(({h+oxLKOs2?=7֨M,0̔"ͥ&>EX:xWB,1+/qtsR7ZY.zX0٫qb-М)~01RAߎz`ZoE2{C>Djmye #ba$ipx^;aBDX[qL5ޥ,x7v'f$hpʼ6w81p}q JM N+"?&YίpM-"\L,gIk-%WrzAA@uߥ1s4*;RseviI8>Ca+ Ƞ菀`Dv#nY}BE!N-=tClŝ 8gh cAflK3͵tk4=ɛw?[lXH *CXTVƅ@7*H +wҿn&c9>_t)GCsoՖ=HAx2/u|j* {,J kCK33";)DDYçyL\s'oHJ7`0L<Շ'P>gǎkڏjE(-fbJ aЉG Q K +Z,XԀXΚ(ÿKzy3>JL4 )fY1 Xfޛ0n3]İQ{NHSI[C-E#d$V*_>Ng&\O48ɗ׭-.qGwjԓfAJ#V& tί w.pծ2\VOdmZD^!(B$ɣ%R<^U _LOf"":.,1OjI$3A Cт{ -wjUo 'l9nB 2a+=?8,5;e>SZat3@(G(n5PZFhME껮ln=6g؁|w o=B``4dm&ok_yEêo∐}QQ`/t 5rj9R蜃AY?45Iu8b')ɤm-6;fc֟ pBI4CEhVQR6 A-[oԼ6 6[m+-}C]Y݄ CS5^%Ek_RX+ԍP9"뻙jߓ[]?=LEy _nh8֝aL% mڂzMS^$d?LY81j2\9PqAhS {g2Ǫ5( 9vw_7*P g.kpvB{_Nj (X$Sh=]u-fpeʨЭ4)o;ξ;44KƴE*#T8z#pʻkC>rnk,|ءF%(!zbt3A+QvzhXiEi jk#"<3qnF!QF $Y洓,1:!O1?5!DoWN4rnǯb;e)q,"-qN2C>KYl.\I}%U"I>O!h{ 4SBViVy&؆։ZZo(NKåJGk_MCwjVj eI690^@B"%7LJYW۰˃ff\X ϬU>S>*ʶ Х4e~>[*X ޷E/B<L 9кN("i(b\?ꏛMdY_'I0}3 7݄?Lg) _c^k|[laguTDp"e2eAؕ\t߯)9:FX֪V~ԶMx+KxrTJiL铈FC&Cgęz&/\/ 1";̭B6bturћ>یx\| $u|PvҨvtvWͫ2S΁R&~P%1㦞bᤊhM=9J2R}4FTtZqX?99h,sZ dFL-k8k=IkvʙAkri9㼱OBam=,KjqxVǘ:/{zryGɔ lgqJ%!۳AmtR󈻧.k9!;8RܬNj*\y@}Q"DAsa̧&x0>RH1Z!3$~2|LɧIagᅧ̅xcn%sy^j3 ^3v( 5H Ac帍V:( sg [Z% t}̈ik,qVf`؊ɥ!ތ>h\њ?~v&9Axl\vI3Qh6"vͦ߀\ |Bc)t@LchVo1n5 z~P򠌾]˒\^f>ԅ]-1>0n̠R ~FPfF w}P|RYs! (Qu 9-@VX$IDR[)s4$dBGb(̷0֤o8n/ӻeƿ}#5ZVSfKQQbyq1hWL7R }>erֵ|φ -8{X's)7^abA3Isei~)* #v]zA2N & ))"8GIPlě>o{]qNsAc2t~շ}tW6PQRkz][@)> w ,,LuAJjt@(17Z؎Gjm ]x#c 2HL4{{/[/kVP Ͼxf[m,ҾDu@a#l0fʏ|#Av ɠ<փ,>al.SGG,qt[˛w1P*c.턐jmxRyΕQFqOlu2lEʛs/299 ?uz]yɠ8 תD> Fh k0ӹ (ڞ;Q;qiUg١3ˇٳl,~LW{h'"`ĩ3N#n(ՂIR(?) X=GL"ۯ@Q_{'>TE3ĮںA:Fj1}j@{M'C1cҩ} ]q5Sto(""ʷ2 Z$m\ux~6y\E95EUCSB~ac8 {G滈H?7qxⰶ{Mk9l^M/wV%Zg.TlwF.lPt^BWƺ;L)[-a={ M@V1lJr̸& ߋRԘx*nxia):2ak&w=[{[֑$rPn]hQ_;iNu Xߝpz$_QEʭEW/@BK?Ov_YcY#^}\'Lw"{r9w:jYj/YM{,+t> P`;sElvw|A"ו@޳i]!C|Tp!N[5iFE@ K }jd3#9Ol>"vI^q|{<=ߒ@R$_ɶ_\ V?W-c#K?Yk!3M_qy10a%"j2By;x4~Lf˄%W"183[mTsV/mЙGwͧ b~BCG~*@!v4pi. ,u[:wZȣ1%i1™-#*ā/=FJKVt';.Kز+_Fv=M =m$ ;eNs)[} <쏵-vqv`PGRDʨX]%[}Wys]^tby+* RNTKE5##v+g\f`.Ka;\OO墽j΃RX74/l(Pr#] ~YEPTHbU8|w}&8 ~rDDx!ۨe ;[CVIז ,@ik}/tyR 5E ֦ LTY(p\pG*J-籫kx#LֶakDDظwZ1~0#YkˑE8 d{ ';W>yQ>Sj4ԶDnCoh"ifg^2-KdIiNtu w°26^F)Ԋ#c c7$Fq]| nWZ|*\R4c3 6DFvS#6&d[67{P9fnׅ^Ѽ EZ1EpAxaY$x~mHE8מWH:֬䟋.Ct[;~36tޠ6`!&zi蟶A(r xWlI5ViTZ% ' m %)4C3+E$hq$C [G-'d(6b*BG駋u+THqN;jb:WT쵪A',k>T%uc-һ˱_PVkiсٳ52zyY^~xu9\ !lr!Eco=d*vrЌNTbZ0tAŤWu&py%p]\+fat42]m\Mݜ ⊺"9bA0ռ_М(5-@CMx6 օCi$D$,SySAѦ=?@=ܱ*ϙk7eԻ! 3Qz"~z?̑,l3v$pNFwXU@Pu P,v~R>KX>5 ~@Veh+wa 9ζ8 ZջIi>$ MspCm9?^x C!w)Kn/"[ { OՕrM#Ož+ &_`FxrbĄKpt0Jݦ) d)ځ4K$Ϯmj^NgU Y7KO1vg~Σ`mZj =ʰ5ZTRn $*ExU+A,Yj'Q 9T|ᇥ.9KiP;s#aYr=O9٫qXǚ25ZjT(sU!1o? `VU TcAsqy{Z1WDv8<0e߈k*(2ZrCH jα;瞺'0p2\E YDZ}JfώIC3oU)J:ê ?q<]\pZ3a5m?<2V)J{ro|җw6Jwiu OYJ\ lK||<},bb[]Ӥ-?u;ݞ0TI(|y K=KRCcrd?Z J}4&.F"f+V~'J|tUSoS U ~&NN⪬a٭_|:I=P'P[urcg_9u _Wpm\+[pbpgedI?%SϮǽ?_ ||3FugU盥.׵ֶ,__"R۳Ӟ-_PD?(AүZ>^r !>"A A$F&So?59w+ TIi ~  Ew 28~ʅq:m ԩQ `V2^8o$8@s*}LUdBCW&KUB#ۆMkJT7QX`F}i{3nd0~+&O!wޘ  1]#,-w[[4k!j e~ȪwϪGB.M-SQcsFI$U`ڪQ Z8! #%ZZz{{\DG%LQ<ь==Ro~ۆ[OlT,i-PAb ,$|-~ov*qz+ tǞk-y @xS&/zDQF]TkIK\2b ePf耫aǓ" f 廳,lv'$0W$#D*bZDgXM7&E$q /˱kПTM-ZZМv {{=a!FHsCšoMB$0T}H%OD5vmF KTeT]_LT }1ع2G'KǟOU֠y?uh4ЦP0((t #ȡP~B>@R&- cx8+y=8F[-P dL=Nm|X@ϗ&eM_:S1AQ$G.oT0 4OEƊ܎L;dwoY+ LIe 4*'S`qW* t]L3:9(-8 j|R&#U~IE5FMJV2ҼxɵqV@DphڎI5d[?ViO>wܘgxHƊ:R?$ MQAk4 =8xp/8ǩ FA4̾,t~ a̤]= )/]}*\ k ^CM8<n㓖B :' ys7ӥUJGsSWdFitm,Pb{'ȀkJ ax_KpyZ`$t]T;veLJ@Lzzء|V] ]/j5;rɰp"EXܦgV=m"u# $~8+m$`Rz,,[X y[Fd CnE/RJqfvk^&y9| -l#{MpwwS!AVnۙA{~w7 6˲gz B"$ABoI^3qkpdi>8BobD!߳NVh[v3enBm-Q<ʧ*`@ڑ[E{(3/at%߹3xV YrS^`re@W'T,6nyS%\ )*˭Xk36;ߝ7s2ǾiHb;wB^ѤkdU̓rĂu _#z&#ϒԗjF.c'&h=-fJŋ ŀ!NtPQAi ,6l3ajꀗ2kqZV"QhEWekMՑɏ#AK)t1G%褿.WȗǍ)=+RPTpá߬#DEm?ĝ#pnVx CpՁ9xCƖ[{gtV3`Ӹ@m6Tm$pg^Zn\t9yRS~j,VFE; zp}wķ䄶;1X.Fo݄/]~)cBg5Y-Ya9|ծ#!@h(6bb)E:2̡ӖPe#ĵq.sx?Jm'ˮF+ @24FNDru޳(<$vYUkss^ z#H /%Lx 5!\_hMc.໺_[ ;!4xA6M 1+0I_P Tv vLn;x6f԰#6i\3ZBrx= q guQA#3A`c= à ^m۶m]m۶m۶m۶L2w M}i=y #(q3Lc Y6%SSd;~>Ze? eAO\p8'jdz)JVa2(y8tB}R+=hc8HL?))<' ?$ĿJ*ɠ=1MrJ)`romƮ=~.dX߫n;|@o9ڂ] ‘~4'K2CtHYb FJow򁑙(C+iZl.#Kj"j69!^!h\4紭];FW˄bIu۬Eo=  wM ~_ XXdv4x_gMۨZi/;C~1m>W`Jo\Gge݀fPW5oE ߕf~#Υ4ԡ/A L@_)#άӼZn& Jƞtc M(xbliy#3Zϖ^XP7`KBm~P(aW,~rdEѩ"]]Ŧu. VS%Io9O"Lc ~o$20Uc<>J(";"zj?5&E6ݚ[zL}Hk^ԗG-# F;<ҟ(*|A Z8- vqӰ^ #/.~ :+oD٤Kd a?TqhP5v6m*ƾ''<{@`P΅8c<_QCNA6yTy2~oQx`Vw'(M93Ɲ:B  7ȧ 2aQxB9l~\i2;ؗ6| tďO'%`2<^!E$|J=WRRmqĿ9M?1p~Ap8|6e7tMķEe]#s*~oGNTO.b+D)7j™:|Y+fy`|S%T8;%1wr% [/313oLwt=.)!8qD>|tћ+LpnšNʄeH6_|3rvƟȵi|+'Q#hbU1"VT- ѿ0$؉<  \.&ƭS^JxjFϱ*ीn>J[{A C8~Z%4o-n<> ӹ:(mpƼD1:`Gg˭;l%i!P hٜUWm6C[# ; Y:J7R!+ZL:5u=\eu| [Vd4:ZsV+8Q>@XlØ; nJ]_mU%[?mr),%فAG^n1j̠Nf^$2䢧"<~^™3n Rfե1ұfʦ k Yx>z4#_T*]Jøާ$ƈQ9G6g =Be@$3 ăGTmhW.wSDQPZ<%@CyB9Q uOn݄~֨Thpt'6rW9ȸi %A%DXRM5 `]lUţҵ6Y\1u%Iwʫ̉zTJg&Sh)?= &w> AmT2NӼΠr/JYnshQ1YTEkuWڣG~zHO3#awp!rKۍyX|rDZcUA7lw:sXSǬL߯aΥb4^<`sTjӥNέNr 92,H~WJUU1J(+"_aXcC hBST_G@LGQx) c*PYI|+_쭔`+77>EJp%~gÙ.Ywzp~̴1Nݒl~הx .D;ڀ WYOʲ!Nj {=`K, oR}a>E ]hZgm (((FA)P5<ϯdl,i c$\%yID?ao'ŜM{\ `PY.i_9[o.'m疿ѵ.~!Rک,J\nzd0Z+6?G跒|1ɛnC4"aAk1`!7s؀շ*InE0Gڢ=uʦЀxJPVۖwPZ4}g_?BB'"^g)IWl]"Dr4E z{csco}?矽ˁXJź˟o;ك" YT('<IZ3\+AKOݘfkL) .h!< 6 8} ;G CȚ0Ѫ܂辟({zqՄk^@v~_χ5nrKd uD,q@ T9% Jf2c}c?Ȫ3w&M)sqyaqu<ˈNҩ/Ťj *Dy k؍s2l v*@>X0 yx/k2 QP`Q\XgD~@mCšuq]}JMڑl@/8i oN„k3xwL\85i kcV#4H٧9!_d\< -e6%q(^sfK%B@4~D" Ls43E-v.X9.Vq)2]J Ԅm}GhT06Hť p$1=._ cq"ywגUzaw5bXmCU©iam'On|؎b(#vc7W|S!rߚ`^~ǔN4P7v~ΐ jqp~i9h'd7v$aY<{x34-eS\]*s]T*׷uKqn t|A<5' 232KKS‰! nYxAEY ؚ۝ (~(OKdT漬Q\ ZSE暃hMnOD8n/Tz3khQ 2!@Ga]}Frh$utЪif?y!5nl$%Df&Oq eKh ]99sd XI u La\lgS4>3jzSBHtx(>Es- ݌YM8(R8 -Zktppxb^HGaM4#=l(xٶ`]Bҥ /9N+6I"MUA ];byHQ7S!|^W]@"dAX̤iTiN=h* ?~ ~>MrũIܠOy)C5)ISlF})k.g$U}02iC CVI<%פ(xGj 1@4¦tؐ/)t*k i\gB(yJ#n E0}wggɏH DhXOL$\!K|iԹ4I^HG^kj\ӟ*X#pپ}l%fspTkx"^R5;!/AY3fPc.öxoO;\ e@hG/R"tdi6a3;=] wܠm靌kMf^^ ? $DvZ]a<u/$`S4ycPdفIiѝ=[H-1pS3:>[#ELlQE !LT \?f@tSȨt߁v3[D}4&`~bXBX=H82m`YwA=LшZ$$8nkWbåWoTrX,JUD\)rn<)Nܯ49Z̠{|"DS d+^Kf 03,i'*,6Q]Yk& ~TkK<AIzp? < nDIuQw# zn>_M]Twv&VG&sT'Ünb6,de" 2+ZcL\AcFv!6W?ȁPBQ D {1o4oOLeZTW*QOn">PWw 9[ Ci%qWO6'[p OeD$lTMac4NuX8SĊx:20ɭ!=@htV%+&iwݍ4=#z| KJ{6? F+\Udq|=3H`$f␱.17<3yuCo֔ D0W)VDvXQsQ Xg?@? OA*o!\ 0oH\uƶ!.`-xͼa9"S2n'vp(``pA\N .G %:8,XM%>X F 925sB'N)cI$^#!XcKr蝵{!)WFoJMܿ z@{-is9K0ʩ؍te-\v|}GÃV>@ rfZF$]tĥXI\.'JTv@|@]g.ضC==RpO<؍* =TٗH.ϳ_ vrtf-+ >yf.I HՋiF:A{3`{$PFt'xUQ6o (5¨hJIi`|摰v@ d?I%~LiX\plIƈ¹q|@vj}]Wma:f%=- tfب^D6fEi4(C L/$0ԯl6l e%ab\GրȂuظ֟mc O3)j/Eccr'%ZJ PEx5e?i@u#iN(B=^&AڟmPg;#IY'0b.^eо][89^7_[Ʉy|p?A)`A[\Iy~ 1XۥG2w̤~|_ +p+_&28~)WDsB[ 2w8-}@nDFi2Ԅ `!/5%TTОWxϽ/:6B z լYp_`. JP3[LY97skʺÃb;츯q| O?e[ P[E#$m6JƯts|lQΉ5L-}|&DݶWʗ*?0yh!3 HV3\0lq&st@ y5Uq' m ۞!HE|STΙ`XZKl-Zx {Ghx'X!"twAs3k|rc~h`J=@mD`!j6 K:B",Ʒ] tUՖڔVxss $L'MΆ}, AQ8SCNX'S\6M 7 _{2'ZfpΤ/WˣZpltP^ hK\SvGEujZ$0;C?:ߤl(#]džLpj,,{\t;{ g.a(Y6f&<-^|+zEf8גy ǵ 7ؐH;يXu/` *(0R. b'hr(%^L_6McE׺1%.Z`>V <ŝ|5ZrHzqj~" -USaN c5ՇZ*ND$쮍ϻr-7[iFW4HQ3l6I"Js@P51 H'T5OLx$}#*9z$DOC_bAC( oYOURr%g b LduJT'"oH93Imda|X)pjUZ:rUֽ Nd:Wߤ%9E% ,wsa]vY`\ &6SdQ-'ڄ)vs^'N{*#)ö!Ns=4Z/7h;R@9Pu'&t(B5HIA &,A~||Ǜ8:Lg\j6Sҳǧd 䗯,eAfX,|Q?Y'#X!w3hA;-d~f[m ,&ŐV#,}pRs/:ǝC] ~Wsb Q5#iTk81Bأ ױH֌ =, ;mZ%'"6ťK{ݜȭLܸeO4և zSQ| nnNŠWԥa\ WJHed\_LÓL?oO]YEdqCSxDg(jPܐ"li!,>Ps -Miy|Y63UxI޲;5ŐЭZkx6"HĮ, (}X}^Z"Uxv a:tԧQԙk$nbuI/pcN!=/}fZ| 7|r fU _{4 X\/|>H\n 8_e+ R@1Wh/+,͊G"pmVTon~״' 5:Tlnbn6Vn)ֶ $%8K|$saFW.j SGkM5`k^D \LDP""ǫ |A!ؾǠn\jFݼ\ ~)]*$+4CCxCƆNRQ,X"(g7/0UOe|puxM0N6 a`ͥXZOx^T,0AmW&u;4.1n|sbAj0 RZ-Gfj%"U=PO {ޜm:C6D {Ҙjq$Wڸv@~rv{pfˀFq,`.8?R2#J &8% 6lWA~=8(V`uD/nQII"k{Q\+H$KliW yshZiEc5NW,ǁbjEVN*V+F>mLrA>?D|k)IojȬ? Pqow9 m+ Cwj!4([*?'Ɯf~3xi8oMT=N;r8P2rO[O;&c8QʱpE/&,r~U9}/$6$)nzK{^7q9wBh/yR5E*RGea)묐>IIˏŢyAvx37y0:iRlt'9 LJ@Ygf[5( iYeo`"ƍƛ x$$f3Y)f tR NYʠ_i_LxS}ş&E R6!hzX?4)9w+(u B6D.bBALS]w1+M8ia‘]v=xVoM3^vsWY@k{@?x Ew]&̾ڂR;Tp̌CbH |i{wͦ5W}:U˰W!Y단Ioìmn^n೏tꫫ3ZZ1U𬛤i@l͆ A&Nf!ek"&{ґKOd'?D,w>e1Aqdc yZ4Zs۽R@Hh)DpX*s^t4(_)[_9?Ō `$5pX 5\0"ERSoK$6":^#A$-La]dS\Yl2QeX(+F:ӈU,-=H$ aWC`7NXQHVml%;ݬ>J8qSu,>͹ِnq':"9oJ|%ykrFDl֌ DV: ,k.E,u[b9\fs2[2ߕx {{]3TvsƘG®ȇ a/Qj,}t WJ@E2W'W1 ޹D4]Am,~ gUcRKRE%ı`s\GrR$"CKY#Y&\#"R]HDWyٲ|~X)͌KW)sc&-YZ# W0- J ~l.Yϓ c?k.>t°QВId<#:a7rn_oV$-L;.{;RymD9l6ՃWr%@|備T}l:2 sE JN.]j‹zA?w0IB7QcxtS Ӂ8go]Î9? m702~oU'D {HDY1qVZe&ՠ{ʼS_iBXfp,`܄/'1>3KǒM%ٍ3|\&#C6H:J{\E4*mPc2xk9dFIyưf | !hQ!U˜(̳-j=Y~*O]I^O3Jgߡ϶ M ގP˲tw:;IkD (ʧ;c+Tb|W7X}rJd[@i+Ha7dBIhǪS|JpXf5 XOD]rJ`R)x"/<0δo')>4esKv-InL[/|.@wUg^ڨ_̣kĶ>O4jf 4ssSxU4}"֎axyތSH9.6$ckUHQn;$P؆ɚ Bך5?BUͻ$8>F%xH=lwNxEyPvϧAǗ$@Sy %żdȕmN8k#VPkR}1"ޏM~H3moѪO~jQS{2[,(Ju+:r~,2LjK:n9N2Tb{KHPߙȮEF| 9:^C*Ύ7zVAJIhQ^FlҭX ^}MУ ib R ;B!\҃Fw9Yx?/5 UANGVDԀƂ .7&`' P-&ڳR0WhPkM7IcTH&*]kj>Gpuax#TĠ@LT- ÿÈ"#YXUKx f0[.Pp<+=@BlRdwpZƺb׈LjC,LR/<0tjI^$E&z^c4S}M ތ"C;Rl rx'IHuȪ5=Q"? ~ƖLwsg}Ԕ}l1zgo-N:IY*n|^=#- UqԫG9G\.f G,^ ?v`MlÄ}u{8ȌNCJLܛ83vKڲb\¾)JZ9"ꪵDfi˛0d_Y y+Qܚ#"_DdFiKw2ކ g~ d`tcR#\F,i)U1Gnd o c"⏚eߖ+LLbkMv@~/ƜVcXQ7_LZ9DҚԿƋjȊq <੸ڧN!',5wu2u- ˼_YuW 3il~&7cv4ӬZ6j2Naڑ?ĚÝ $9e9:8g-k1 ,y$ձB{L -ܕ;Y}|(5N."N|x#ԭ^%ʍ' Rl: * x:Kx/0q}I_֘`}>߇/8BɾAM,Q:u+6ר+zQ#(B ?ׯ;b.񵐘c-9QfC/]fcL҆U٢ps5  3NBsm.OwOFڭkA?ח?Kʑ)CJZ/6^'EW9\]\z3'M0g6hE `d-:7yԭ>u [v"b-k2*IY+mL?yXt7L,RYt`vᗌrz'9 љKI;ot@ȶ$PT^cSm]XǎohDPЂq)PyG9 hױ"(}[sԬ4|NĎjjpA4q+E~Wr-zfӟNǯU1eY}/G<2\tdGRj4c-xm5` 'mPxb6<$!j[ Jn6~K6>H.d P Ͷ<C]АQ^s_g}yuEBlu3{jqf܄+AD$ uyQ8\3̺f"&Ksy ^`F8<[5#p1j3UʟB<񗺖#X*p3n0QNkVj^H20q\@7$>G;t7|&~7:o-/>K/**ЂnUǜ7x~&>(ూixY@zBgt5S_n~y|4o(*F`C>= dScU+ $!gV-|r,x˴>1}~su~Ƽkhѓw;ϱngX᧫\Ǔ6Hz?j)wRFHg9%Pإ*xx1 8DNf#yh !6{6Ytx6zW?kl%vڵve*AF?a46ILVJ(oEj~^5/ʙmۣˀ؛@Z"=@ h4syj9>*QS2%eqt(i7b Ud2 pTlLQqAeWAEK&0s;g,xE[oD_ܢҲxFEiM xm0ࡀ?ߒH/--d:s.< zh3+fGb|.5eJ{Œ.2!|#c?ʰX&2j1>z:Nݫ_)wEcŁD n\ V`O) ٝhVt.2ql)9AfʯOk&3BcWO*xY t!gHxpI2(BD@3P?rKz"T)SeHAx)Q,H JX#UG}'aBeVmtyPӄz\?@P] .a`7HVmW0ΆZ}2qUo#BS.~^2=  vdnS+>-O{v5E]xF׿q#QA8WDmC S~2oP+jry:Ҳ9R6~2B(EAdr >xeh'8Ec,uMXm$GDמlùۙ9r*QUH} ڮU19&ߣ*P:_bj/Pxȓhѧ%HJTo Y4d &Ea ؟FZ;JZE'v BZTG%;Cw>L4thDȭ~=x70/JGU13 /ۜ[aSms٤EP5|Wi뜮8\@sfOnY`"[&3fSm&pb%l`p~:%SljXxNIwN6Tpg]6D0\˿{/+!ʫ6fWYwRJ(ŋ)b Stnǻօ[RkX,"'?^=ټ?si]T_P'[F[f<֨[Ld>prx_n$Mb|p*h6[6q2=`0Ve/qF~}FrBF f.FK]򭁡ys1&b!dC,Yf#TDaQ{Yr\ dvcWu}C@(NlLZ%!\bt w gɣ^;h0:8g͋#W#1 3]`+޸CGfK.2yCCgTn0}ŕهV1lU<&CA566G.;K!JpimadiVpKqT &>7Q9u_ާdssaJ5Khj'DRBG7$޵<5IVzTQ3^GKدsV1G\2|υh_U`ZEOln+n(azٳTioYCN!S0XBuX 6OvjGOEePzqsU'ݙAKۘv/i%MBD4x׀#\ 03 uKealw4cJR;'92j@ڿ0F5;H&g0mbP\u~0#2rnKU:e8$.-jPTDŽLkR3)!5}_;KW0S0B3oԈrU1X\Eߦ/~;eŗA;q赦B3c#R[m$hg]pȒGr9ͳq_XDO#1 YޕֈVY)?Y7p .3C:  Vu!O÷%"əO1pJTفK~EPtriXEm [s 2h/HHLs6hxb/B>[UE& c,%kRW+vj7NEFzz滑0Ղ+eWw!ms!Э""4] PBxLY:2xԧg|c|3 ؊n8 :UmxI>#DwG.]lx% W%/=zOELjw6 S[J8p>˺Rd ?w߯§Ww6px5+$6ut_J[,P;2UA?__+\YU`W+я*]/0Sf|: ̅"J@)]Git{Azv3g2_>uco&yZJPT .Cd6l*O˯A, \/T@sgAϟ"#xZ@gQ; OMA.xuP ИoOr)wURc7WjVhYP$ؗ1ujقY=iJPS S61ė< 7S \:mj#.""W0E18tUdžF ?`PXiEƜ  %8iºMAϪ;k:)[WW R/YNG-(V2f N _nҩĘd#+ b;=KaU/;}",3 MG&R=8zY @B {x=z8&Nto.6q^xVu ,d(?.3=wDI@ /aeB/\+9`۴&ufCQ1)&,3&8yL L=cA\6pbi)D03*(P(映bcV E`cAmQ8i+s9mQR7?uM chf+ׄ|Z3 toV36ze%| Zpr[JBB nĐF{8D81KnE6 Cjʿm,(ؽ #w9)yߊ%r89JmYo-.Mw.5rDpib 3ͻ p^s~V'28LlRIgް ҈<|{lk؇OK؜R|];Z᜙6VmTORN}Lh*F}6sRT6iSc]9 8[-X"ꞌhݮ9 ~B PQa ɏ.-dWL|wd4£}+lpЊ cЌQ>‡qɶE<-{8&ioyquw5W@=ᔊT d< at2&V.6<1ܳtKs>̈,4l0ˍ{cz6JBÉ{yfy=f堖 Rg{tC,6uj_ӜoEׄk|f`L37SR_?rpQT"̧U]~vPQ|3"v@, <HpBP\l[(hrCXM>KiIsҠ ⓋK]nJ{pnaԉIejiDrw$ s3 <JĻEXhg埢c8-ZSQ8d4OM8.6Q dBgkSFY`0sA.8iCK_3zjm/fKhjK.6?*+̆NmL\FFp~#d*n?G5'q0 aL_9/W#;h$M"t/2۹\aqg@)x+Pʕp),[u[ ^'"mO'h T+< %HƥK6nKijuT<[ģQq,A+~/?>W]E1C)Ds:';*vsR;j@PvHf8C͞w`+Tb-u9~Fey?ٌ1#oPnJqS!!JhdBjoUIUpC:MBI,c$.(,Gt\)[CR{D`NrP){{BZt #B,,  L22KkndUM6){Sm[1?}_X;(ߺ> f~+aȀ]¢ʀ;mRyxYޑ)\@ Ѣ0cC+X{vw7-sλ`W! C#e˷fE3l.e 4ynUh9pHp P.^}Ec.,u1)%,x Ja-bl7B ر!OבeKPg0[% .B2hXp/RJ<VM76j'j%5Gzo%iwR!H㙲PtmĝIl <{DAD*$a#1]7Q]ǚ@9L@ /gT{)G;umg]sLV1յ9{J΀B4;V)t5l`+oN'"4$(Ĉ3&O A矵uH.d\V*-p|!K8bVEhl6{k%Rs?_6dW yYWSkYvcO(ϴv^bb^A|2ZgUr$(W Y`;hĆxvQ>G&KVjp=;3WpU`1ʢ.|b4FF)eCȅYJ<7*XhsV~5HGX+d*A" .$~Ug)qK!2ŝl`h6xV2lw\95z*K  o͓tI|lnڳCӗ$,:0c;8ū/5`bVjxI((z=eȃ Xy3H8 )[@_pv_1(<2s@Lv>K^ŻNI rWc µϯ3ATckCUXP_7pFO}kNr KM-v{iK{BTnGw$)3F[+4J0JDa;*xqg0?z$@Cp d*EF`Μ7da:FSekB}scPTJ旈.NK7;Ҽ7U Bc]Y﯂0Ucg@%ϿW^hp~?&Rё2-c# bOE uϛd)^Lי*n@oIBjE)8Zpgb"U8Y)벶P`Qi'pܫ)05HGM*[[搬^mHpXmF=(0LHᔆq@x憦ŏyEɚ*hvK+R蟦l9iu?f!${c]ɥқHsM&j蠒~sDt8Bx7R(q!2yzWErllE5UBI-A<֗,KA3]I}JƜPvj:Ayb,#!<mnT_{~C놴r/ /Bpc(ouao$ˊS- 1WA/7b|ήA)1-8c̋Ssr[zO#]t/OImta}H+erg P|Z%졸c#Y!UjU8}ھ GyF`IO!BClɆ6 w.#JW}3xoc_b#'׉JVa(i~O0{_,{~ن({Ab1gY;7֕_2LUw?yҪ+SrXΤDH/Vq4ܤ=kiHӨNse]jQG_iyxIcx{ǔ„P\1H|i2(I4;tU,q6EH3D '@K1a7酓}j"ٽ#tw']G=a#*^Ʊ! peUc Cx°%H*=)c%1# X}9dQᛨC tb‰΂gBPnT CЬ:Wx 'cB|ރeR4#J1)>&KVf:A<ks-^ i٢!(G Xg|*"Pe-Q?Qr_b + W}iy+^02= Ptc!ilfX]dBmk|GOJv@sƕW)l#Lz>K"6eIW d0ᣌr,XpY)|K:8D]GM濺f"<}ð/q7|GI|$vxChjrom~5RPUSʟ m(;y0ߚARq,_RX-$tO+B{[ ޭ{9m*׍m1Tgaq%Bӥ/԰ X)%^қDkAt2bIs{]Yc ӡ|2BbsĨ"Zz?7bo{Qܞ|1{sq)j$Bw4lRʱ~ "P&TyфXTQ˩0WVٮxPW#nCgF .hFv$QCX)OP`#QXSkhdkՈյ/$0A$W;̷)S&$-,)zDdI޳^1Hk6@nj{خ,؈F˿JJx\ D\"iDrWϿ>No[5=Oy43&KϖӘI:9MK ?9ĈqFSҵ@N=2r,LFT#OD(f̢di{Q:0 hvЁGl\3?$( Z0¾#%8rh'\$u=SЊO9j$y Z7v4nܾ r8Yec"}0 2Qv - 6ٍ"NCC q' -j2AM0ye [ jTʵT'HV%ޘFLC!i3/\~f^qbi Bkz7pR P_r\q,x .vhJ!ȱP&4i7Ytz/PT_ L}Y@!ةBmFa¿ځнŠˤktʹ#|GHU6H_!iWog W'#@sIMYu}ϭtYD3LC!mZżž>ױ$/-ZTV_ZP_`Tr(܋Ʀ h17I?gaѰZsW5/vJO2)Mڀ]Ju5D;YЏ=@*I ϗ۔$Dwat{] y &8 Y@2_ŵ2VtNeב%a"Fw6<[ùPB\; K)g}>L}=j<} \ߚ!I<$+LHR?Z2Btj^%!@o얔޺ޅM/8d FEiWnK!oZ0q.h70M`@a?r8~r_5ql/?3u4kX,]!SzIKfp=TRXPv9J|@fwArɆQ0= T1muPF'd|l!Ԇ'j(x ۮŔoKxPzLc<1,o:m_(\]#|KgUN3ΞQ.]F {%3@fJIrӟs܀ra͏ƂkTѐM,g>tJ 6Y|B*~t _xg wې[k՗G nD*2;!#5SZ*l~$?<89L&A:OZoFZtGֵPgrg9|6,B3d.}0Bpmr/M.;O*_LY soݥ3yw'u^0 }rEd]unᕰhI56kQcԭ}FtXf1bRQQy](}@/;l*fbCJV)+eA #y8W?Xk/SgTv?"Dg rjex gœVaJ~4..n ŠJoVy*`,uoF㸭ޛՒ4oGϠYhr.8mf_t+sp!\UqvȎuκt Vg:-!^1p{ I[6!^vKIog'"] P`lgLM߼sϡ |\wև@y] ⽿K%HUeB]|^6h/Q%^Yu%UmhM޶r8x NR)6ZcEƸS 0+cVfEtn:F-.ّUfM 5$ @(9қC%'3؋i)-ErϤ &Am$4uu+bd[$cBB_RWM^ c« KL: .-vT8(kIn gjR|؝Un VRe-* O S\{Ҵ;iaeG_g; o:D_ ܮ3,b.J37.UER 3X )@Q ab4kH8:qzO7NJT*2XAe1)DZ`@Ɗ@Gƞرʮ}v@d_#՜w+57]rDn Ż]P׳;-6 £̨tW tW-47 EE!Ȑy/\.5+=DiVR{q:dRj9o75.Yَcؐjמuxigc%fwwZ# g{9Si |{QWY)W<{S^Z([fome>G/Elt dC6m#!2ӗ[%־x2~BͥK܏^J?U68i#@E*=# W,DžY~36Y >;Ƣ{qZ2l&OאC3=ClS 毗._%mz^H*VF k!iZvE3(dP"C4.-PK딦 dZwʊrѩ*+;Ƃ)hcxy韀u@Cþ/nʵ1ݡrdwH &*ICL &6T!.{ X|!ر@WnQ%f@PL*"*{g}LpZV`ZvCӝ,=w7zw-.ouF.:j[L7U9s: 1LF(aF_$ˡ@g4uŽ;4iF+>)^s^/؇ z˜ ,X^<Ԡo!2܌c50LBzR=QNߣسG+/[{GtGO+s,C̿=;lff fJ^xgCjZրFc Msҏ;)%ta+)7΢^. ?aTiAAv5t!H%~:`rYq#@`@jlva'sMrhlBHvCzfP߹: tܣԸPCD6ےo(GjJv d EW[4cQ+]0"ueANEc ]=\:F4tDڪeO2+3^#yls7e ZICe1؍Ey `6Vhx-'lo'a|;o詌fbPh_xյx8Xr -b5hzUQ2 \z#De^+W ֐F jg&)<ϟg%N.΀oL̷AШ8 II+vmH"Z<ސ ڥ1d.Z3)waƏ؅s5rhbR?~m'>y? vƷ1ѻE;x"֡gIBXz D$FЫ<, CUԝup)>2+1]?8X8^1׿y)g@WJZhf*+:F087JY!FH\nU]Z;407Tۂ71U˔ . %mKu4KgV'عWui>?R39WJylxEs龦DZpNX KF΃7-_HFQl-b=,6VV,5OgΗ|_P}06g\kWKd˱נhwFoQDl[5+i@V4X'PJG&lZӰ*ZKٵË+2CzhaRC<)hy3paQ4x-#MbkmrAApTMp{BI J+t ѠSCZL6,.؞n`4# 8nfTShLootSQ0h !C4pm˻"36(ۉ# )Gsb)+km:}j> stream xt'߲-ܶ1m۶m6mmۜm?߽EEkee殊]dD ʴv&bvδt \ [ CGg [I+# '`hbfa C`9;Hs]jdag G hb`lgko 򯨋;us k {{@ښFL[cG`mfaks41(ۙ:832u2qWhSؚ8X\ -˭Mpp6+&F&z^[cؿht0p617_N1;G3\R3ɔY F2_l ?r AFsg.WT 6X;(g$fnb`lmN&; Ɵ vNt?\*FV&NN\&sk'ch߆ *&ّg-khbc``;Hhgefaw;@B6FvF'8::*-֦cbnblgl\;<)J.69jpjAdLA,soN+]L&=]dP:.v܃PEï jpXOf%p9tʠO[ RO؉1/c/s{zZ KNT/aP)-fTvs(C"d xLNћ%Yp-{3"PFZ5_xaD[ }ye3:|˘QX WsA M+AD5>ʫ hQ؄`y ujټ<:nb|# Cu6ٰ5n=xq=0Rk3k5纳s|q`y|}+HŴE(&]H@{Zck?8 LKGm.\ ' ;dT컅]d@XMʈ/g]ˆ 7XTErrE)x[MjmeV4PzSѮ3@E=6 k(!e7HIa*vT85NVP#O|hoFxU?:t`ټ=WYgbQNUU%sVbr |Cp6*qY$kHQP\i|o8xYL/ /hU;[z4굗P$A(Hs.W]r{r⺇f'"s*9?>>ݤJ{po#ǀP騙Y#J .ѵ "/B6ġf'O'g!]1H+{l8<AԱ EG_Iˑ+Ԍ6'UѳH EB}X^a`Tku,ߛ۸+Xqҙ_IX2}c Bԅ2-TUYszv"EG[Mv;K %Yw*!7˱ɗ<*p)FELT-M9u¬ğpWw%I3޽ASp9uqX`=.׻.hڢ?Dݽo)uݏݠ)wh.8PԐtCn:[$.1avuP^YכDjT'i\pkKvH E~;s=&7 *.~x`0W@׎a0sk7°EvUq1KbzR:hJYWojM6 oM^D+&[hB9Jqs6}Jk&weH dG@2@ئdvXT=`ګMQYl:Ls,O%gϟ\x?_/N 2eVDHGY;U(Z$+V_o؍9ҽ!7(!YYVf3yAaDkuGT{TD8&DxӾNj0VIڂI.9o`EUnQ]-Y[]b7hd7FR\sQX0TA-\.#ܥq2,^]R)Ps<4*%L0X[Gej8*׾ @LxÞiԐ = 4LCH|| IU9&vKY6Uy r,z[#_Bm玠"`z>2 'nrfԹ5XrXq;OR_8OE~ K̟RpN;+l0d ħkŕXAi%JzEƏf.xN\1[jp.#uiou ljQ |cF# /;Csʬ;p'q? "w3iw_4vupY- u{ yљ3)W e m4p!a2c,w;/pCKU`p}iߌaA-%S#tlnj I\}Hմ~#μ2mIu؛yrt!7Y{8+QvtDy '(XܲOfBiwLٖtdglCYqNT2 ,姐F5)>nF}ƍwMgD?%~r^u`*J ߞAeգYț/eteၼ{~BT&?|OLCVƟc)8CոO#cotmfGdn2$uuAl.<5fI:>PsOsrpݠyL%C߮#{ M (ora!ʘ΍(z7:,KfVfm^aMoOmgc1LCvL 0hBgf-,&IlNᤶMBl/{֔jOS YjjW;D}%.֖C}z?FNai1ttaRFt2z Xx3o(W |au 1`>xR9YKc ȳY,zJo9X`VMFCkG|3.֨ɭw*ޝu.M!l ]0.ϕѧA1u뉚Ac{65|4|R\_"eŸ')@WuoA lEz j H6E9" ǎNdv\I|_fp~(u Cfe[&A .,iѿo"@`9gT^1qf@QPc$?w_|)49攟߿gv!No0Ʀ܀qe 3Tq"!k;R}0R%S 3OӔh8`#(_nmmwM;^JDi%1a0=eP?[U!EGfJ!;[J*BaibVV5˅Y`~1"`E&R@, aߏ @( 7# 98I' @_ B]l{.5A_TSw .֡yƗbwPZ+os7c<y5BS/9w[oL]2$k!l_0pΚuNɆLJZmU/#Wߑ~iTHMc%37qT vVH`ǀ$-buL%*-uCmqup6*,ױv/>RbL^S@ k_*V p$8qX5@`52DhhecK5k>`i %8ȿQێB8<~dEʟڀ5nCoVF؋lU],n*[Bq{o;@ZOpL6K@U7^vhl"UD`qYsՓF;"YQy識-4 JHPudWa04B^]:Dۋd+ ~B|ȴ; "LwwT8i1bՇ"J-Mi {z{ f0M4$je/tC`c XqHx/q#M@N#{lFv@NS|K&fiHi5fL>?:I'Yy \oP@v٭Kr'..AAbc)6*: 84͂ZV97#& 5M2J{3 jmW cBN/:YCtHn" T3CXq:'{js{5&`ȟ sg.̗f ku ҜĿIρ,.UPb#%Nyraon%sb!p/,QTyW镬iw?u@:i<Njbci{hlQ.RDLZzP0NcxTxWi)VhdFKn ܹ~rc`[c gjIX^-KMOnK1 Č/ ّ J v8H#)YZAq.HdGJP*8 Y>Oj0TS ( J5bE?:hT;٪Ovt%eq/2AMYĒ5>KUN9N2Ik= \Zl;aڳk28W Dө |XJabuZb{I`[h~q|Akd 憹< !x膜d'/@HdOD[N2SU/#XBg{fh{L^ʘj/Q2m.Рp6mw0CwQP@&jHޫmF)"ֻ\@92x=&u0äؖ! _qLVEj22`)p~ 58'bq&02 &#;ZP!^mb_]{R̉' Nw0*RGw R/=:ɎFag9|A>}R} 0>sPь 4~'髠p[+%Lc 1Z?SyWS9)7rxm` Ʀ $| Y|e 70aA$6516[y#[/9cfimmMDL ]#Ž;sCW0a鲼M箿QMmna-H>/5ډ(*t/$-=r2y{@cB}sї0YE$aآ-**l 't(uC1 ݞ/S? f 8`Ң\.}|rQ3fK46+QowM}Y%k dG .qȾ;/Xe F Ж֙ I+Sx&1o9 8SiѰGOx{2S!,/邕F6p}lx !Ɉ U.ڭrGEIG.{cCG<Bzas5Kc=`왪8[%9v1k]h *mdPP4^ ?\3-ۙ< HguF恝?5x9b4SiI׬$|5$|3%YrZUУ} Ůjn>Kp)n*+kJe{ {+emnB5@~m9Jyc;b:VC%gjt ?hyQ&&NAiX uD0{61uKpfU hiN9Lh(}y37JAv)JrYlG}^(|oy3`\lHwD囵 [լW~VM%* 1C}a+;h V(㢶KHrl*K цbĨa{A$`;ʼn3Ogd") j*bWi^9V- \UI51cM D˪ZAIjO2XWҚVlg] ^= zl.`9E+ ADjNf=NbB 1A*H 8)Pɕr.5FYnE2kI5Pb(ko25/hvh 7suS5o?߬c)<-dv} Y_$&¬i(H[11 86 ! ^~r@ֽџP8eשn{YQy7]${ H ʼ+緐)Vd/͏-m羪U8lb$2Uv9 nVIX<>}eݔKK*]벫P:gsvXrhpaug,"K.A60-ŔəW{fUylA3G"ٛv/I dJs$JM f=usÌ=76#4V/1#4Gja}nQ60y&r tok $yȯQXEk ;{ LD(B]`$T\h'`?sV7?Èi4 cѾk _\ +; ,O AQ&o@,,j#J{Οz14 |܉5nSTumJbcz5C33W *Ŕ4DNIxDbgjN2(JtUR2}Gv}>vo BغWO#|*3M:@vЛZO=ڃn%M^bf#]VczB-CJD ]3揧\d_#lZlU駤] K53b jaaba5> 1K|APt.lrv?17b} 0s|g9KSk"DNNt!0efj48v1@"~fѲe_H77~FW2E֘e^N_~ ?޷8<'NJkWRݏ,E#85\9T:zT 3͞!x_΋;JmÁi QܞA.՚J)`ڂ58evxmLFLRgMjB/8WսDœhFpXRSK8 3k:hZ]Gs4iZ!QimQTU,kZhTzޠ1!ˁ`҈jzoM=`oq !Ha[i6pc5TX6h~n#_am6d. .,LHwc%X2 ;l'TQv';Tua1[gRdO('ɤ<2X6?"jɞA\ҟK gJ"?aVp~~TI)Ja,ر%5a/A5цi ^Ð0 vzjJ>b155q9/'JlLn:>3&::$9_+I<ݩ"ZML2&NwY 8wwc.Ԅ*pAN͠HhX<TO+N1mǢyZN^L'hBuC5חfCU$j Eqxm%F`f4!umuBtR=nm sG؛ElnO`PQAiX8S삈da_>f"g/t G)!mPN'k\?,sb@4,BR\ēxʠVrURe Eg\ 5Ё ,-NP% E0M@_W`!:wὶ?5Edž;P8׷ܡlv4O4>^:UqQT(]y<8m^{utB'/\\X] L bz n֩[OO i:TQĶg;1,*ZщW A ~Gh@hRRK`B_Rl4A00f7‡a:^_ſDXis"(xZ8eM@ի|P_"bYʀdV38,|@=MML? iB#w& , LӓZd{sbFP§aǶÒrqtـ ] ;pԴ6(ܥ\Y}TҌ>>|' 8 |lv|EwC}AP:/;AԕR*U,TwD2=uA[i9O./`jgE(:ܜ3!"ldh8y]v} -ڼ^*oSOq lz<Tlޡx;Б[)}qCJ$i.u}kh|Ƒ?Ͷu.q CoNMA991kQͷx<8dHl/-'C';f?U(ǡan ס!݇w&'iA[\E {'|ij*@-`Q#LWi.,>cDp"]h1ѣY!-lg|Na٠ [,4e,ʫ/- ;r-"~.cyTnv|Ez3Nnދ+ V^YL zi+PI*iF"Bי^ImLPT|O=ر o\U'#zcKOEi]6.rPtQOU&"%H"ȫ~9no>}$IH!okadWAݹo=ʍuˆE@1C /u68 (Q@e !+);-ߖ?b.|721w5ik$ 2癐˸OOQ"{Ɏ?n('ƼE\]1:eCGsmobRU(#hT( ۗ"x,Ő:-IH\|6 cy>RKA+ B+!B+þVn3ޑs*-I(Ao'0)^BGh̭@Z3 4rB;l'Z?3H@n1؊z^0DFoH՗Q 5҉˜ ^s3RJmNL(~:js)E+@؎"s/T~Gm*F2M:0 \aE]WN%˲VqxN#㓭,D +Df`mmy iq'mb}2!\HHr+E|([@no]ia=ޭ"#ou>[BT)[kj7*zszJE>tf>P$38MsOӜ&ߐGG/8Sכnݫ`YC5[Qc[*2LzKlę`LϚ6Dr Ya~F3|NL-8Z0°A~Nu\Hƒ:z[fY8Ӄ{~O[ߣ [0-`!u̔I-0^%ZսYx-$%%y -h:iv+(UtIJׂܐyh@}{pϨgZ+As3;3L3-i<[(zvZ b:~f=İI(U>ē;%R9-{Q7?h)JDWapFRU;=>NMNDj4B0-$ z@5{!>jX^D? +Чz??ub3{ܕ=6UՕ:LS:sbPh2zHu"-ߵN_O5YVW^(W1~r}j%qhհ q4EIw`0g"Yq{K4ݐrߛfj_x.,[ѣC-">89:zl۶=m۶m۶m۶m6ws;Mۧ9_(\|Vid\t<acZ1y0k$LO8Rźv; ֲՆ/ISvJʵM0D _rLɠ>+ԛK}oΧBi{Gc[spK;\ґyb.bG򚝕<'1lNN'XsKlu\36Cyøq!B;l1 gx_OO)\sGsepd[U_GI#nxYn+׈i]lkho4 ގt@= tA2% +ec$8Ih͓(m ~\}+)I*)-xx 彊';`ooZ^j H).L`@ Z(-\鯤+r_&Wde +}C.:_dK )^tl\O 8@6ĂHg%ɜS`h=;kvUu?{ex,o(PEJ+s%̻Gޚ*&wgw: 7QtK#8@Y*tS!E۹nq Zr}BiQ =PpY4!&A<aHH3=Hs#9V8W'NhK13\9_=3Xg=Ѷ0_NXD4g7'V߂B=DNx˘D2--_ެrОMƩ4!) ,zSt_hNMbBSɌ uu qGg:7SwiD:2ȡ+yqΟc_`5jբۗZ%Y%qGz'~vb]Xֳo_&!x lƄg;Akf,w}2E_ !q,ImBU 4@-')>曄O]oR3J*&Xof1XG{x9>$ݾ~7;(򕪆F(^,pl6SF>?4a(FiA9@aFiD%'%v IːMcy{-ʗ>ǓIҝ7,i$O֋?ܐ4sP]dc/8Ζ֥)[ZVWS}T>IeZ@N:U&8zt q :F^_zXsoE*OvBj&ry8XY2W`xW$7*)s!ܒp0m.Et82#. )j$dL4#Ŭ#[ dnNo`ͺoF!]l955 ?o>_4ls&8'=;+w3Q:uO.[6/.MO݅Z ߮otOpvݹT9a-=JJ5[:`5]cl\2+6xr7F1"6s졎=o'e"F1oUu]y`GFah|de4%7NW0V[.B_>IL>/W|ȴ94TL$BGktGH9w'c5qג<1Q*]Ar܁%N{ooiըQi& dPtfcY ,!aCZOY>XXm]EVI*h~ Q/#؉EgOhױ{ ]PG}9C3e(rstFyGK_^ӱ}Q׼3 `b葺T{^))˥tC- emTCXYq`rVjJ!$#%eA|˟:+sqS-ūqg4|]^{4Ř2 zhӹ %"t콉[Ve CkM$v,{z ڕrJ搭70;poR z; M\Lx&$uJ[L g.@Ji ,㠑a ?X5!jO+{T}D+rwrBY摜PJxDc"·@6!:l7iǯ@lcALGX~ٖ=vUoV{BؗF:br/QfЮ9&\^E(qԦNJAo] `! >X8p%\i\ߔ'*MwoeHv¿=/Ȅ=4-0DU4 +,ݜ%)aO|wp(l^T2X,CsyCR|q0X}7UZH+mv:)9 ovNlQUm<_(iR{+tP[2hrłA }{gDh>Đn>^+3:~XQST%s5fɗQ҆ɈjȮIn_ 8}g hݲ̖E)z * y=&,! \Qq$V"8g^Lz3 5`=9 usRFȀf(D^)н>tKMї ~\4S:#JԱ<{V4؉]IЛ%z68n];y%vA4(] ׹sRqгrnyórxP"uλ ARyyҳl+z]Cmlxbu)dYR;k \ n^tb#a6,ǐr$ڹ0J6SF`CM }k_;%hV9gmk(Ɖyqk鿔_M{= ߈ɹMHBG<9vt_սM0 E4ȶK!R *<)ۑ(*I[ BnJS9TBEJTƬˀT`/W1.ʝf93'Iylme7 gZ>|l|n5o)}smU9;&h+5$rKPFCpm͌&7T\"ƞ;]nuh%7濠YgfFy)+w ieDesTp]낰XC0t7phR #Ff3QH olXib]B6=toPxxe x==ۺ W|e((\7&c$_@'8Dب` N3$7;d5srT%ǥhRi_Ŧ:pۛs/¸`:0PLxeb\ P,R8?7wH4p~%Cd} G_/`;vO2gĢ y$!f޴H 6y!D[mD̢JSQ-";J~3߰HnD-:+WNC4M;b0t z.^:J+sXH!n{JRRE{n"u>S)]!{oKzSf> IjBW.Uװ* LK}VE; 5 'HIvrnQ2CdV2d1i&ܿkF޶^&} P ,D^x Q7 vڝ,N6xђ᳏= p`̯&q2􉥞X۠T~JM E> wux .TԈ y"a4`of3)vZ1~ ",Vie)jzOy*oFkc5؃7SYZT'ԺJLEt g,M,u)1$wFNT kuڴ 2((:HBF6xz"U =0BA @vd%;yoJ'+"aخ3ctw^O` LT Gol*{[1RԒܞ{ :' eM8O:⽴x`"0}Xm{Ľ?O1IJZM >"jkBcÚ U(O܍QP?ϋh;4dW iAR~9fQb2$R_,"b1vQ?X}beN'm{w]<DΒ Pm  U#6kJ,gZxXX[fmItabI>J[ iBﱋ4Ppj툗gG$B<b*~"I hQdHTœp|~rLWejQh4G 7[;Lm[tlꭈYLl7@܆{^82W  v uPHSSX[*DG9ؓ?FHD &j. c+Y&xuASwF֕zj;ITjM[$2ZH!#O L epE6<+\SYH;Q퓰OЎ1xMߤQdBXsGI{]8Oa/p8cì*,Cۇ;݌1ȃ~,?8"+ CTQGNLGUm3'NfOZthjs@ƛ{y[#=l0iyć,_*؁C P?d^L>PZ/^('`#lo< 9Y%m~_P#.4uť*ҭ&#N3λP+F*w9`NɣFuع|H!,g(F НZ@.A!j-@J o)>0r dh&Ȥ?\'P✞)oTfIikC(zX筭\1:r,Dbf42YG][gm ww4m=* ͪ9i֓SԗfHڷ cսh"ػi\9ߘFc񶾝Iǘƹ@VY -90}]X,őƊemT`Ke?Px;3`v=ID$ڐ;:0q}^iUH^tY[z%~C2^'E -z%'ʵ>Q #L9#'$azUf|i9j%9`"[ %$|tP.U{*T0@/m7Ff ]O8q>C1IQga3f [6.S`s(:tc DZ|ēА;>>79ubRҕQ u],w.~2[_gmYR0|_)7?:w5R<{rt*,tp#ՈKI9v,>=_+%"j-Yd{P+P:#ļ3 4 ߼@k/c)Δݬ}^6eHY%-Pu0Y88_o ѷ&16д(&[v}OL!іnܱBNMXpDB}_X|$+ʋx^FęP*c6HNI?ʐk(f-¶(wFO]Uoe:ROq`Ekr^?ȲqVz/Q|![@?H|.Kt/-S{\L9NuM [\~ z"mW"Fpy F&o¥-UnAd-MI.(ijeihʁx`5HΔ`UgAE6V=%wU^ bջsִ k [7dZw/ ڕÝ=,1L$+UɁ90if2͞5m*J7 ԷOZ#d(Ģcזo59Zp}{y$.L[dL>Az ^6Q!3R2w>3*玖)qQ7j14>gҵ4 0 j,ۉgEdK.`6"[Aq'cS8͗دKjA[t csPw[|vɏf]f`wKWޙe'.Ht]ra$h-3$ gY!x\Ѻ>NT hu<Fd1bVB]E\Hw[o pdXS p8n2cΧe&i&t3V^aW̔GIT4(C4cQ"71}&em 1o1+iZ1:L)8pCtJ3艧輝쒒8T@(M ߴNDS YPa#<m{E'AGQWx7@ߋj^t&$1=2ÖixLbl,9 beTu$/[h"Ә1(armw9"]|Syҗox$|ӥ[f3􃳎LΊ|D9KLeV^ w'vc퟿.gӏȃJi41":)7&)}~Ĭλ àMzTMivS9R\gXig* >N=(p_$UL "6k')K?o,Tp1{G߬pv16(t^[fîK<a[ݥnABwOw1AunZPC!w-lmk wcTw!DhNjcɫD0 QSOt(ZѤ<~7f:f(#%7Ǭ"j)O>]eS(A~ΜI٘rd9oGm,аV[Dΰf4`x$00t ҋ?|T-ib963wj-%~Aj=;h+~PU!S*tC4v/>m14FLl9.sC~hp`+ 1KZ2iehzDẄduBcF2jJ܀=[:nɮA.H8K~EKt0oT1M^OC.#Nuc r*i"CάҵKN1L mnftnvܱ繐jMѿ|x˵U77+7c)! ƕu&~ت3Ui'S#tu"NBxR>ԩe{p"%2 ?#@ HO=%Ch>д*M,qqCqc-xzyT ݯ*lŃχ0~Ay߸F>SRݧ܆n?mN&Oql &OJ;+xj0+ )\,{G!_Y|؛lpM(ajӊa (7W8GبVLB\0vKz*nqV PtQc"Zr9#+_c"kȔ´sE=#cmMvƧz#ꬬXvXXxˆApXn'Yo[$0zxl%+P-a/B5ԣ KL - EW)V]4iG=wmX22Xadx3U7v鲃Cb:3^uFah *\; py\G%HG%?"lyYqΖ)ORl- 5.uOh)ݴ*e}0o5F`g4yu@%7 AG~O|q>tD*nE6BWöK ]dܑ%:N Q׾ [=f}mS(VV=l{ `ꮔuUv@fcnދ ׺O zHf;t ҿ%_s4I%gߪ2/(NE^SJ-jv"j7'Pa?kh$OWv7 XUe=XڕX.8VdJ@|UiㅢŤz F-H_ pl%rIh"cL4T&]tL6OLL=v]̡MX?'PGAmƮ2 t-9ym'Y] sդ_цUS5;氹 ōSM-L5ͪ鸈+8a5m /7;,k82lSCu#ݦ>x Mw; ,7mԫ~n9˲7|޶2k.WQxVLDjD#-,iV}D6wמ}LܳK%.VU)1t&tQ$;ާ! d{_m+T,~qf`[v俇W n9+gA?k)#8톌@(>[H6 1Z% iC۷0<Lw!=6rnÄO~lakd~^V)՗k+`c01!Y!umtH,??2[>kPX 3ŖgR\=MXvo\]-꤄']dQa`5 q8^ߵmt 1 j ;I)Q LV^4jrGkIpBſLĽ յZ)d.wH08.k}Bn_,BbւcɍMôCuTk|lx 敟JsWJ-S( G*9A|xҤ[ceK^T3PqKU 2dT@@07!ƈ4@~ߓ u;'V6YH~Uwv<7 p0?BI ~'K)Z`9>YC=5b} B='tNP_73;O+ fF"@D,~S }XZͬ,f'l'ͨ&W?ݩ[/b3#$'N+j LwY¹9jfQՔx,AUrAӊ0~ua71`-iV3WjhAF)*P NPN%#֍g89G%PP6+hʜD0+fbEtPngWعZn7[608eX7<25y"sseOdz-#vCT NM'?L{ܨ\sJ2ޢJL~Zk%]U9jvՊ ?V;1R29 7]07^aYYl^qCf}t"\\OhMa]5SrݤY-r|ėJ77κgxP|`ⲎTe?eY $^2KP*4>Db2=^Lb4j?󢔊M1B A@9IrOP!k?\iY;+b9Ru%-nez1F٤wg_K.A.>'!d1ga$2$u{2+-tƛK6kYL?b@Saib-  Tz?0}P<2th$eOiCUk516+JLNX&Iʩ|œ*x:Zg8AΓ``ɘx!tM27Ym~Qјd< TŋcZaqDKZ0;OWfE{6\fcQ K*+2x*˨ hRTu3pQ*/ke=t:sڋ*nuNjpbX=1)Ϙ6 Fh+=׈epgd @udp'JH Ԛ*t97D _#R4;ƨxh8(Uc4!5ٲ"@Zj,vs*kzYGbsYs8zᕕYFO | Vh݈!7cd,BGKLƓJe)"3(xE+󣰡rP!C  kRk~԰@+6Mߙb)}H݃sLjnUvZ|%Pq͝wAvms2|g*f="X$8PQTӦ5Q(]1e!4)1*͢yN4&hEoWE.;G~R-ybJ}krqQš 4 &I3_zGH17UmOX2s}ls˖FN"|q\F=ݥs!\Vf!*0VXW@^%,k_(^FPIl栺gV{x^Hx+B6;~kBZ;d@Kk}` yU?+Yg?Y_^w}gf227f] 6PbHXNp:c*1i,o,Kh\Zu5OB(FV.$vp@Az#Vކ"mdk\ dwh?88~,ml5Q9V6r],F-X%/6 DW9Lp/;S,%m0%+@3\m~SZXHP>X 13$Ab&8-򊛬 .'(\6 RO apyQ{o vQTmxbPgZ,]!Uӊ\UKl%Ր^8 HYTGoƒ/pZӮ`poOF+E,1T=lBl/c.ï: DЖP|wj~ կ;cyfԗbrp&?HW&A5^X\Q<'"@_/^*J}F= d{I La>ʹ=o75,ޕCW*F܍)&ndsj-T!NmIN%M =al?֠ jhLhc3փ".Eښsq`@*A撩r*S{v4^AG r6'-MT٪ Gö;6K h+R Kqb/z蛻wKg]*9/ee)P|ڶJvLeBZu|m~i#sS&]7Z @RrXyX.g݈]IN<ؤGF҉J:--l Ni}[ 'ADY3:-Qmǖm۶m۶mۮ]m۶m۶|EHVfJvw/1xqHMH 5!vXC)`杢|,' QR`>:aGQ$r@4ҫd')%`{Cm/Z0||>F?5 E $"v35oƕ2pGqyQuz |1fZ2^δ1lE~ pYRs6M</?{ 0;*GVa\U9n] 1m}BO!q5OK"L`{5fdwOPi,ͤy"i$ݺ=)͵9h;|;6"ux 6 cl&u TW9bk|gb8+x[K|جGAɫw_;vc|ZӬHTKǟ簞q<ێ! @Zgea񇬶Ҫu5/kImtSbܳ烏fWI*Jս=@#rZGզȿ.÷Ԑzhtq==k$zDL3%TfHU!"H աVD~l(Ra)ݩF%[fV?t'l8j:C+yDW!3b(S>=VT-lռ2 f%ʍ6:3&zQE ~R֚-?\xZ'FiQ/ ՟[ջVp Soi V28Jz!i^: N FeZ˝/گI8"6-_Opl=.<6M |~L'+n-g>I'iohLW:!_0ЪIB$o/9׫=SڬL'a5o]NzlQȚC| ""žzƇGnĝ#7QOhWD/l-u&Qjxa׭["8f=^)_9D 6}z|zAjy.5Z l fIm@M_4lj?{Cz`K>(0KDGnmUۡW'{[ BkA~dGpH.HԵؿVj٘ҖЧ_6 ^$M%D?^n] }DxLyers2m3^Ͻ, 4TFN ~hOb`%>8N z GMT.9sh/s 7L/ }rU IDHK9y+j X\q&XKBײ觢uxZB9"WZ+Ascktudl5c8 hv_h_4)孨cІ.f;d!^VLr]/e^~eGOljH@@y:)؞&Uz%X<;p=ţbKxq6J_$8)&) ǫn`Ģ ]Ŕt.n] u Q3Βlb;c>qp!_,J;d=qLN̚V'>ގ@цƀ7h70AA굥c'9l"zJ7!}hv虀*Zy?v&*oĖbCn$`*絎 ~bnm'IdR[o|PMBh^8gh L4'RIwykknJF>(PBY}b1[2f&T9|3\VWIV- eZ:b3ja^s4wn-a$ ϵSi5\w縠jW$b>|5Z6 4=,)mdOH2OQO1[͎-(Zez )\Bz  :d|D63"94k ,spp=6U\5^Yܸe>uH,pb[{MC7_{ԯ_˔BSAWXY>N h2\] 3=p]`OfUiH\Si J12᫢kޣttZdei-Qpvcԕd;wy6_=sa Lo=BDQf Z+ЮL@Dٯ5Wv59/)j;%*,9gTK|Fau)E}eq-+vTva//=9/ d31AJHp|G̃ N!DWĿT%?}%qT# 'H^mb*wKuduh@ ?R$Zϕ-ĈV)إ] pIʹ7ӧ#AMQD³/ssEE B* SڃQ_8+R93@]J,A~jK~oOd-Y ]}Y[O`b9\B>$ѻ>*^L|{dNaʽx8*LH39EMWwO~B)q @)m@e94E/!-%ܣN\C'\Rn a^q{*(MW^ß}TϻqEQvAaB8~=uwls%Fwp=lŬ"1`Pf`KU)+(>f!Q2۞kU?$V }6oj[b %o85hf cPb=bn6ZTm I鉖Z쬷΃0:%Ľ e|H<5LN37I\3oe28;q$ѪÌf@('98T(-ϜtvJD]4c~$܈i Υ45uРM¾98&AwGNJP,2EP Hȓ ߩ^*n:]/2ns@xЂfzezlQL;,$BQi>n2cMH$pbUZ!Muúpk751B-@vu<0ƽ Do^A<=3??ގ _dqrpHXDEk|U%CJiamMr%p;ky2P2H @ukx6΁n:+Uـ?I!f=*O#`{t楤PW٭i,(E9鐦iPd\ cbZ_o4S:)@2Bd,%mSqFԒYQAG\i(cC9?}RzbCv6|'Ȭ1_1JOAbEm +lc4Ho[XĞqA)Yqە8Lral"maz{Pt?79zB$ge,j =(ۋ9+1x0ɐ)F -5l#bpn-pU?]?1Dy8:? %S>= %]Hߚ`*FG;LŊd>s8x2&͵$_cYHBwFEL[NO2gH/>4bL#_)Wە,-EJ^>0I7+7o6[b 3/$ OXX< U`6@VhNYDZlYcprkC*=\i`T}zQRo2~" 7%T7N跲sUy>'@6(ژ{r73f8VF{*$)*}OLqoaNN(aYN9-WWEN!ZtI6,"`ϕ;9Q?*fp'[E'3!s[+@s}F L)c|q-yQjwL>/H ALӁg4^},pO xP_Lc?6;«&Dj`bm+2<8.\BjπEgV,{lDE0DkL:Niew?!9S5tDX8uHրg[T "ܬT|" kn%y`˂wYݡ{Q`z7y y[T (?ط́䍇[s# C2lYEko3%gy$&֭@XtάDfF.lp,ƛ `ҿu*[ܝ,u2IaE:]&nKPF2%=*GOSH$!C.=q3p!@H&4 |Uu?ڻhۅq5,k=j+"H&:b%u kV ]|ԂI?"kD!X|AKhnBc"sxr; ߷O4> whQN=F¼JgQ|zRP0ʒ6?{r)!:Br>;O7g^+Wy"lE!NmڳZ/j4CXkJ&"qHNN801 QUDJ8[NȵK8 cRirNȇ3)0>Wx)sa 9L}^ Eǻmz]t1,K{$2w Q9&>ZLl~㏁@ZDlSh@¬ӴnWGI Xhf6jdoѯ Gzh 1E40"=Z ĪƠ9tbp =Ys搃֍ q}Zo}acl88gb ?ۆvӕ:usS=]qqqzE8iMJD,ZWyEYh`֖(nI}&00/8վ%45x(CDg0kD}wj<*!-*WN2xmE( fC&THlCi=T;8g둖EO{AH᥎U.;Dg ѝ~ .fד9iueء=NRlSc^(w7j7~q`٦kZ1QSD=Cd+k>EyEowD2BجP 2v_RI$=#[; ŶԱ>U٬8f)%-VՂ.p󁵪>L(mN! >)ZEP&dV-@say퍴=N{kr|+83( v#Y>vEϰ,T-A:#!ckO-2\Wqjٟ;o 5""ӀiEp|- <)sXx~ ԓU都3+ߥS0JJr/ 'o4_e,uIAJft&i$#(ݧ P߶\-=.p'G 1D= (|ǝdh;hi3yrQb BP8ʲfT Myl{PǸbۉH`."U]hy ni0vOm<-s}ڏ0i-<ˉ4jRaG_"5|YhʬG)-oiĸPH GŞo6 eGz#2ndދ9F r?78ulyTy.GQͯTB6HKc|UQ:J!CشY,+Pc<6 I78jI#q8V9ᚬ 5 / M1u~Rm =8\ #/3}v>@UwsT{H~x3"\-ᧁrEW[sJ %ogyq -?嶳*k\Iןjr\8]%V'c: /` ZSc6L`ĒR%rׄ8LqZ뷆|.NB(RQws%h4>/6\xj־j/;߆mwՖnT* ]dK LWjF7׉%a?]".jl)K՜MX4:̺e"ĔOs{B&;+kWT\P}'Gb\Ֆo: iaYm$<95tD\M˴L̖\U゠b:n"{LX.]֮CX֔o#v0_uB~-8i4'"/zalMMnUgOsIPy7?̉)Eō ArW>Hs"|Жi~qӒmyܭd0:xIՎOṊ!տML.LRK=?zL7}OE7!['.o#SD̼P O+qhUdl =QS31`P!{t<5y+ }~KwDAaTN)>: 4.T$s!?Fh =M:!+Yr޺lAkU"&)6(ff$ho/V{ɼbeT-dWؕg;h¯ ~>&h)EQ#n_NL[:yE޸ڒ;CT`cJvWFMŒoyNNZl$Flj(p֬i 9jPlq ?9ڀЦ=`]=9"=#.& RG+[ k$'Cz{.XV>*e rEb N[ʛFύ*[C  | h ɫ*aױ1OpTS/MO2|SM5{xg4M;Xh۲D%M-_+ _R;-+DݫatIqK74Ic˺ӋڂK/BHs& r)]I HCυ3H g3?tLd%0M@tR}[p֊tM1"@LH丩D_]ODGתکS>83ؐiJN f t|6F֣j(dS48 z1 Yl_;ͼgW ׌Ǡ󓿋KgrDzTqza $M﹭6pcK836d v^)4|?cM*eY:ّ'Zx8ԹÜu3.>|[6li3ȕ P'<<3Paoy>4|e4I)g6&FJLFjd[QmXGcw*as*ԵX.l𧕸+k\"d:r ?> |o3_};[2xV!SR ңLEmue{3wIä>P&_) SՖ8 B]xvT|}Y,e, i Hf$΢Ho0:K SgO~ʤjF8HPTKqG-FTDs6Zpp>WpJښ4o6$2ΕQxfJO74k79;͢Vpc1W`AtɈXu.1 QS#>(| eXy#-8l嬚tPDi偲DBRSD:=r«6 6Kd2z*aҜ F| Xp1jvETa/ /$/C\&Vo4;wRi*-&݇s p\ č#M`&4[(&:CU^05JDlXFI3 srt<HHņR𡷕UdMZwb7*9Tk2gZ,gU)]4>0 W>~!e s aa" i(2ʋfpY.pTV [5(AdX'UQ.ğLиqyy5̍'T݀ALvC@Ϧҵ|$KY.8yUkCv>I K7 N@>(`i<:V&dǛ]d"K܏DhLp8!DarePx: O6"̾8[~S֨JȕO yo*Wd]ilGГq[E‰.;"aSB}; B> jod `U~G 'iFwYthg=ء׵dQf R],cP6qMr+`C$>#OQK/v(]3` Z j,8<2ȴIl6oW8g2OVaMx e}'EԷO]zrHZS-{Ćx(";k{ĩ1*PXgp=`| z0'rlU/X,tz|x`Sfr٠ &#}R.kp/y3v.:.>+Cnt-+ \CGDcGvW&hbr)ǣ{B"o۞;'ߚ/6<9--IVqE"A/lv3ĵ76;8. 7VNPdOQ|$=0+JXm7.@D bUQɬi#`% =M*e(aǾ-~|0~m݆̭YEL(\ZP~u+`z<-lIZ&rOw?cO`G$% ̬؋4̞9*Nw07BnI.v|Xy4`fl地ذϝڵ aG~oZΥM )U [DVm oYa?W9t ױz(e!Fפ+a("lC%3{/-=mB(A?$(nDc#"zi6nxB}>vԸ^h1%9 80FҐBvq(-uei5nAC{ ϑ8 _n_ׁ5 4qR>:ESnZ3z~qp44BBS9c(h-7K͏$ 5XsXAT2%V`҃@{Gttpspa6 `7hzl^vYg/1cG#T+سMrCw9{z!jH_AIUNMɣL0BOFx]>@3c$|>%pӒseOrk.oIvˡ7 A*iGl88WsCH}]v-:0ZDT"Bvli;fԩIQ{ƼͶ@^]+|G 4V'k]ul˙n˘2QtlY1.}V^y$F.bR+W[a1VWmrYZG*bRQ+9jΨ"1#ӰV5EƣCDXuC>cKygD\zgc )XWF)'D_uEAano=wjY՟eN-@wyLDirF/1`<KٵHkqlX3[^5r?[@I @lA9ȣ MےI ?:ڿB7 ?2\stwOȘhDK*t>}HR$AEqHn/@G9u  _- MIg説vOz@6]!! pԱ`vY+T$,f~e`#l"Y8:[$$9= F%8UƇBv<eY}$d rzLLt7n'?l!Ksv~hL&œ:aRj^iG?i×dɒjwR~}N8csLXp=}O6oZNb$HA>F0߼%@4H J5`*@ڣ1r#]IӖ02D&ϖ_ۺ'&FQ|(7S=Ȼln oA`mai[Xwlӽh@=>wSU.&m9i|GL%"1-#,oFph7Kt]6;>~Cx1RwU a{ @J@;PƶQx:Nfb P3eLOo5B}\%Xm 5pYw0UWFwE{O ֹ?ƂjrCT8^ʁ`!aGFaR.EY|ĭ~p;]vuUl֕;TTw0N9(-]B7/NH_=Su,ktVQo3A300jw3mfTXt[~1z?,L/`?oŵ'튾$`hg7 Aް6b܃f"rfF3RKM؅3 7zB\_@F /+Ei2.>.(w?bz!O@[ǬcCe9@ZTB3T4YQ` 5lYGi8[MH*6V"CZn\Tޓs6`;x"V6?~ ? {AWCs_as~9<@ _n>Ot 9]'4t-rN's&i C6ٗw ٕRgtࣅvΩX%BW:i!eL_W/բy&"Y&uYQ.9N{U7=SzIeЌeI{Q70 MR\b%쀁Mߙv8&rRvu !gB&9!%_A['j;}ڥTL^#5nij'5f&}|'j{m|8E48FQ̅}F% -[T~6MnЖ :%ut6,¶2/# pw8rcۋ.[V%R(2W+V_gTRXwϊ2[Q?)@ $@ r3;EEv~TrϚwbK2ɴWͫMe2Y~f}F,M(Nre 63t.3S d*}0Z(TmFEծe\2> +I~yW_h ֚=7nm臦^T $M Ō<Ю㣂̛ԛ>h?&x2:DeUsVO&DFpשgJO%|'+;VjiWgKk HɀY#J;[%TuOە(EcVVŶ۶mUl۶m۶m|z$9+aHydJ=`ÿhw@7Y`%܅Yv>60^ UR7tNZ\/⳵E'6P&M>h3i%KbMqX Ҩ(Tg TC>|4<2B(}W8lkZ>Ȭ#Þmy}#@GKs{r $* Y ӄ :x3y3b>ab=[1(BTC/}P"GY\/ǂHL7#h /J emm#'[vz& xJkab =οggxI4nx4R<{y׊/k*P|,ٚ^+lPkgbWKz5FEdU}<7‘9Y·iޕk M0sݏ {Ӹ`0GNIoY,A~Y'un,ƪg&okKd1OI76c;n5̓ , kanFXl ~YebP擮EƄĔ47 1liA-Vk R-,˧|5}C:DVa%:?`r X~"Xj[$LjӘEjd 1殸ˊzVWe#N:ef I(x&$U8Gp<<"T;o"b I/G!3f2!B;6-ak랗BLJZF,Su@1EP҇琊-ժQy ^V12xzJwn\"qɶ@ Ѿސ.Yߣ{nܨCy|$ U8P%L1'9\-x/VU"VZ%TO1)GCiU0ŶIaew?PcMW뗣ȌF$sP>\I nW;p}l:0>^WjS-hÃQMչr55oi&]AUMJEP%u(ϜJ ]2AiT_S 1)\"afę{nsJC4ɦax)&Y0bI#ާ(gu4j?\qY913h2@qV>%^<g,=PvJ.S .j)+OEK͖?KϬB#oT^ɗ,ɫAM}.Ef  t卐_ P'EJ. 1om5Ae%ߣV- K>\NsLW, ߨ(29+xXNR6N1;I6,~M負K]pˮ{cϟav.T0Ϝ{ `:pslW`h-Kk O,~lJPHI=('*I^Cוb֣T=.6y_Mׁy.%ü<>YƆYՁ9_+WsB`;BuDrݾNn-f4Y}\2nBGXIe ١P].N!LJh+6EG|2`={0USRG=>j&&)ϑWJi 8)]'' IܽxѼ]$~ؼKw&5W?Km {9d/Δoo5kj Qp(U ]%jÚ..ztksƁViAz!\7nlUs`cuդ,Q[46vr}{bEpz,L:ieŒ`tqnQ В׸ ۥj})ŁοCw'4'rp]|3& ^]9e@aU"?OIx1Ef;0Ne6N?"!֓\ib%rUD.?Tb 8O/mo?#H'QEF<N\$:40?gΗ4vZ3v`QXL+LXpVIY0ysX,Ivċ i)݊W zF^e% x~y"ŏ$ZA+[fwrT7T2a|:2?,{Ҹ&ܶH;HRS?B,jW@Ke7;u\~ߴ0{S$,lGqdDJ]wE6Zt;h ;?N+Σ?0B? _Co1,"eB#<(D@S*W\hݴVn)jrZ?ô3˰ac&O}ogj6 Cj,כ6l_], slt}!7'zc9 EqnmnCξ/0"8pi6\֚SR)۳t|٘bc mJ;VE D`>h~F6.}.6PlЯR-hI%&}^ybR(>GLX+WpA#%mX'q%J8'MT|#a[zxD#P\k%DNSq1&'uE 1Eb]). 򜣣TIs [{X6'%GE[oP |v{Vx鹨u:uPg5It,%.?H4t1 D׊8l.32W l xsgStg̡]5+ )g }Yuz𽽯*L6'eڻ/Rb@A"} B_,zA+3`U R{FKa@@s,E6&>&Idx6nCJ(bkɥz6»efB>m@f`?̭[\קqPAs Ofȣ|ovB> &o 2GmDŽRjc1E dM\*8&?CL,ts.^>V 1SStm{[ٳ~ە+R Uuaz$̈́vq/Y??̏8 j%Xb/ mg5@DEk'Ghy%0~cRKOq{lE(p]VS/ ?n7>DO __@uvp7ap~йC8ɇ}y^1ڹE_qYx  yi1GFV t)K{hgh lVC.=:E wmk:Od3wjmQ| Y}2~$/FnT? g3&PdV8Sk_bISKQQ|j{G[?E?NE++BTi^ʵ!œÉYEW4&| X`棄™$\fr&tư0GU?Tp{A!i`%i;`5Ib=4`Vr(2Ň YRݿ=+ǙWh&;1F[zjGWq,cKK;\;Qn oQ'+\j'"jGf,فmHvu ͋bt}/e];R8E.cqlCɥwN+pf |7&nEZ!]t bed4$8s=KȮeFr-"]9WsxW"AJaᕆ4^fD51 9ݯ{'&їyV?w ~%e~l E {;4eYK @.> [r{yGX`(y&^%5Wt=ÙD@{̫C\Ź#86e3ƀ^ũzBBN>/T[xAoW)er}Z-gP 4ԤOB+ ~<ڳ#siǛ2ʞ7ވme8s)SUR ](ʡ?z_K5ɽZrr纵A!} :+rFL r7MԌJ̒bs 4فX/տL~hT9里zbHr93u6&^ hX]2AVd?Π|m eA'r KK  Rg4F;e.nC%g EJV̫Vɞe>YixmJ ֦D88;l  &~cg\2iWImE΍=U dؙ} b'J-rF(jZOK[w D'G 7S`hz6/RJFEi;ʰź P'c#q*GoydLWlPh}J&vn"ݞC"RxFX'h"6=9 d kkIZ7@6k *mskG|tnzx&aE-+I{n/G:'!SekDbۙ(5-v)8)sрqǫvO&{ܩS)jEQ;FK7LaF{P4n{M|J(=,14~<7J.vz^<{wv@t+B{XRxˣ%H_c#uR]0I%/Jҋ$}ϴp0 o錭~W=Q~{ ۡ+WG/W "o6C"[{fd=$I0(,8_GWe_u)JID\MCe)nȧ窵 A;uAV]#KEnj5Zcɋ'q;R`@'yQ>:)LӘ3s`Xʎ6ƮVo/73s kt]O$q@_Ɠв}A&7_6.`w O> X7mX1&ZP}y ٬DqC_=+^#`Va.ٯ2ѳQeSe!r=`}ۧLsJgxpZKeHgJ5>U dPvY 1}є|t#~KN * [ 0GQ79`-! |eװC]{/B($xshJgɘ87I!ԕ/W)XM Kg:qi4z:@OR>7!ULj^rr}ƑvG)bJub'1 0z=xZ bk5#@HK5YU# }3fK xIjȋrؼ>p\9{eP>S8|=s/q,ڍRQ<8 ?E@c)G2U3Fr9]PC0VS"u* a><nS81o!W3A ^`& { NC'l/{U1[s K61g m-=o@jҁ#(tYuݧ6Vq{K)t4d6+g[gnݲO@"v(ZkFTkp)ZԁiA[3y!Q UHP\ jq ]tXwz1*+TGddgWum5&Ue6xvv\BHb&ҭô ]b}6`2y!u5W-dcC="ːP~h<0,u?0lK C7tx[겛--).1xK3gėEU&GsF5m_i@5PgΤ3WuMy>Clgu]j 9x]' k]βQ?7rSzԤ; žj ~2z8Y@ھ=#$|=\BMB55vHF$!6t |OXmDKo[i>,$#;KC/Tr |Iwh`cq}o(0ՉpocuJC̑ ebhiFa\wo"E]r'd[i:4V r1e$~\3moxzg/4Nd`φms["Q+bST`*HU] Ra? |#QO`Gj.wߏG՝ir_x_ca0LK(~r `*%.&.| Z 7sz*2nBEToKD Rf1p2eK0!? d@֏[j9}>bOʉ(V \ %VT msSleNQ3pfk ɿU,'q_[IPSrʜ1(ioy[NI; 9nZN: ۹vlnfq:.u&?qMfe9j8^7˸Gbji\, [Uij ( @Єm8 w OVtm].E"Tj-IAF=Z"5ћA=ک\J) ^9INVU9;ޝUQ˳a!M!#_~?c6_(@T̡͋ ,yLE&T+AfAua jpF YA8X._){Mc*BhfT{2"{*&?' D}U3{og@!$fἕ.5ny9U"iV W B|Et؉ XcT' ,od&#fCFrY$eɟ[J!rn)q3$ԕ&G/x-(YS ȲR& 5?v0v.t<5 QJ۸g<4Q$k(Yf`qIh*g Mդ5K4c͗8ekt1n[L-kusg 3.& N{ QHF 2Y*^;kq#%Rkf>]r+d]Y'ʎK8[[ Q4BJwS`=?ʓ&“ `0u{R"eep/IfA[M5krw'ds_OaxM2i@.#fGn5kpLX&mQMSKb\>ӂRm3. R-gG QdLe9%]R/x[ٯ) (xwBF6Z6dNTخ:Wy܍5Wce3 RZkpo_"!Oδz3V u 7.Qnx oa_LCo1'C:QQRfNw{n7"c\[σ)9u>rcblcU[~$^+nǽGDpphmz#geYKkl7)òAV@i~$| MXEN)o* OӎR#E endstream endobj 422 0 obj << /Length1 1448 /Length2 6480 /Length3 0 /Length 7466 /Filter /FlateDecode >> stream xڍwT6Ҥ* "HғХ^BKH"WIkHҔ* H)"H|AϹk}zʻg3{ +c]TDr*`XY`h'z"V(B 1:yԀT:(XX@‘y P@QDrp'fgn?z$ E¬!. Ѕ[àh`G@;/ GIrpah{EAm%4!пJ%bP p[; `N0k `v誨P?`?n_/@0kk3 sœ-Eu^qBPp? sXaSeLՇFh/ t]#: \lP4:?yj9wO_utx-\ll˰y\BU`TDAA0 zX7D@jL 8`) b^D(F>z YVP; ѿcP?2H~20oee4*_FYY'A"aqC`*.pu|1wn 3&C](L7 1?3h~eg鷝CaN!0}ƌ3 . 5] [U8ȸa( P0cm } G_6̔Y;bLfпy-C1C<\6'( O"L1 Sov.p4` G]7:͵(]_mS[ " OdcĤFT_ PԚ$Z,ġ&J֝geXo;؈gМݣ0f9VhС)z=y{SAq͎*vD&TV=G!-Fn [}7.e٦\+#])jg| NuiQr^΋>f}"^΂[ c!Լ-ϙ^O/u?;xPkUt?C/ȭ40tb;I+{|W`N/[+/ɖUgЅd3'ew;W>U2#Pӕe-z=ssߎ^-v ++Y:ޠ L [4 Y '(8Bmf(7Ǖ%}vznnUTە[7gA|,K9޺o[wj=6R .y6l'I Z'/5zhte-'Or\!GL_Zln< \n(f`,8m6jm+sMgDFYN~KJޙZ>(J ڼM%|޲FOloHn8zu(?I8``{I:Q&3nyB<U琤e޺BIB?%t[r"[^R>f-CL߳mO% Aq]xGosg15_"@je{eggHpF^YZK?׃Jriz?xYq%MRP%_:_Xi||emBS#n`:~ - 3A$? ޸yNWڛsUVZcܜneEU0 AZoA}cq^~ZTQ 9=,|u{S=~hCqtU/E߀eE +JFz/Gym+Xm߭u¦,GeMC'i3W2vce5IBVkŎAM#CObOX[-7l >b/>=E;+*HޏBX3nlꇀQ„cM@ QOzl{q^_~Ja@#TOe3{u Ɍ3 1*ҖWig5+ؒ'*}KׇaQJd)nTql+ẐKOIT[ d=JrL<7{|lpQPۖcYrO%`-H >C?#$4ׄkf6:"峭 笉-8k믗d e Zx^c{K);>S 蛅6^_:&UZWMj/?[^^"\$eR׫^ye}RN$+;uZJ_iR٤z7a%S&-ҷAnQ:2#H.C&5G@=r+ӶcO=9h%fj2s6]622 E5:)/r KւKڒW^ +no,ɖc#b6R&>(f PDI>- T9%;5<䎭o{ި=p(yIx'7yButg4opb91L̅׃6bLi~ÔM4rJŷ4?Ttn"딙?賴\nwczR"RT^bT(u.t(tVQZ6x>h/Ad9C+m8y$_\ AHp*i7F.|zXW;b PMr@DI% RrE,^Q9c\!?^9z^gbpdK xb獯wJlp8Vf4E㎥Q=xnoRk?PH7|_geXWP9 Z'Z xn-WvatgS w"f:.շ3(-~is!cd2]ꗓ͆x=G~\2f4oQĚT4;SnKP!*Ƌ2hzk4x&m_D=Sp<`?&u78Ppg2)kIQ$c*TZ=b&q۫}ηGba< WBov.W6v%KU]B:c=Ϩgg!U8ʖDm>dmh;d9tmlXїy!Ά<5eP(+쨯]&iJT+;%{IYGmxwR~Fٛ*YZ8<)Loda7S^7q'ʭ#+Z*5tfP~qU%nG+WV#QWcMI|hJP0|Y%%\8WGùwB^|YQ$J1~Qxҩ;k݀MZAƲPRķ)Peyqf1ݺ=.}FN~\]gbf H??D@9qޚKa%ԓOd%շI͒(wpo}L-[0f[jwt RH]&*/7E{" \I↚*_%&D|+Լi6?i9suy)HP@Y ,3݋ vͅn* }%ϊ͐N_Җ*Ag[|4̤Ei=&U)D⭟^x6:.bHӾjx"נ}kntۭ-K͙3+ݚ K>z~<qb'#kCOd;xv 0{jV3İ2^*"Xmۯ>?S=MyqZ*+'|(J3:0}ֽ|-aKŸbds#ת(%fɻNf;4YjkZR%cp/b[w-^1H^I)fdr=/@|zL"۱6畻sb["/d_'c9(RC'+im!1(|#aT!_|YS[fJbTvBA} +{J8!KB`yjD#XnBQ)Rfye~lzTE$KaMہETjubW9C|v_5N";.*e6Z ΖYA?rj R ̿t\Ǝ6gsusO}T9Mqi)}9 3. &ى/6mVc˚g$VPާ9GR~/6^ΰXIRfN g\$H3pDȄuS#!%ߣd[U~{FLV <hz1qL1 M] QS҃9EbG*+rLJu)mn ޼"wZ "&+$fS>kMgb xHU;]0ҋjUC0HzJmQ}bw&Á/У=8G,n(`ӎSlP16WO1(ZnEȩqJܠ5h%~Sk2WZv\ "^|#K™fA2{uMU>5ܟ]GV*yЊDtO3t@c]E|GE04J?Qz$K}{0[Xv+$Oi/ذ9i Y+t8%&$SsjoմϞ fͰJ(C90flЧBscCJ #ӖTJҷ Y[|H[l8)4ނH[oD3s.;㛶[U\˛7Hqb)FwV#IT|Y=Xb8~r(F5>cxˊA;DܽhrwT6y<(!ʕ8fPX뙪'U:R[P]Î8vSE>=8%5؀;KSA*½Tja 1牥ޘlY:^+i‹<2cאS=7o"$/fXFGfW%#UFIa_՜gzl )1.ɽ7?; b~2#*Gi[yKn_=:QNg~d(Rr{_R720si[Z2O 8|wTɷ۹01t\BYD WDut;ǀM*_Pwg[\GwWcInU.Kg™[dZe7Sf)(.緌B _.HH*vn#صbb8z^t["IqIJ:vhJ&[p y endstream endobj 424 0 obj << /Length1 1563 /Length2 9956 /Length3 0 /Length 11010 /Filter /FlateDecode >> stream xڍTk6Lt(0 5twH %!݊t C#H#) H JLJ7[3v{kߌtZR0s< Ȩrx8qm]!8- *2p<ة %W{ sqe dnU qa9zmm\`` p[ 0 v8 NSdžie p><@ %#<! 9wؿS8 j+B!C%y B$Į&J;7qMw,޳V+|ʌeTJu9_s{MI>7 F7qfFȾ I}~ʮ-sc F{`ԦV%2 b=F'(cy$= ;5+ѱįq{Z81<+ܱ^e ԨGwRȧ x4f㱽]`̱Ý^i* ZU68I<x#NNZlERBf%rae{f/iM_;|>HHǡnNs<_&~N]`tphЙYi wq{t쪶@HWi RQ(E]Ůևڋn gU{vQVHU]Ӫ~(b,c<3zwTO/y uM 3xۗ}nE'0M?]clXq{Z>7& DK@A%$SIYvk^Wq bF5K$DCKŌA ˲:#[7)c '#)7l+GqTȫ \/g ²!BZ|NW\.]p5s•)|%JoHJ.$.oxjg#]#{S/'$Fq|ŗvKsSy-.'L WVڽhw˙~㥜XuuUUf{d9)mIS1዗Hsx"i peWw:2Hj_׌yRLY0-;55m+6U}!eEŵL]zt *s_H2P&gj9)vY:*{#d Zqh=#uqs뾭W``~UDbN7ꏺ¢TffN6 ?WLcsqwSx-&Oof-+xY;_9̂b`|:ۥId=v5C{Ͻ5i!RH!ۜ԰d펠X؞P3OZLWb(upp9r]y}uiZTJ( J;c fR-J<σx!*P>w,b] ̃-76jWSDw@T7IRtۺv>z]nzɰrrsFwWf0s8~ueڷ2jq JhIpn"2YR"ϚfѡXQHB_ ;ə7LQ̥}`So&ynT]h$Ձ{H?h?xsM{%t`aoO=U4%_V2LCy݉Jp&kC oҫeb'2^,2DDkVcG'it>gE,j1QY櫚i1jTkRz*mj^~C|rT<}Tu> ׸MYG.o.x\9}e:qdMo+.,Lm796ߠ)Õ;?iwxXNㄚBSPTrpS%qjsFשQ{+-N7_Tc̓ tr{o"֎Tx~1SH:@ QYӚJο::Kz'xNbFy[`q|?"⮘;Z;kd`5:6Τ"O_zGwVz<݂iWMk*gph@=m5ޥ Χ,pIvؔIzjFI+IO}/K¦MtܩOz|uX" 6 xC곋wS+2@3EDL#ofbx!0[ځڅQ[@YΙ05RM6|qÊ5$瞆@aW B$LW,un:T_IPh3 SPu8OrI\NPĿӮ tg6w,pOIi@bcJSmAłlIY3PRxcӟЅN,6u)5tve^pƈ`jQ>dKxMNrģc3WoMN(%ɯ7g=wzp tW&w8%Lw;JlDxe^?v@QpyJRU羆3ciknr:8) B"}Xg/SW +y]ct|?tow,  Rw.&&@ٔʌ;r 4bҳO0gM6a*6fP)L<5F+%!EJ$..2S\d$fv˾ {L ' XH~bξ[)H<膼WY}oD޺KT{C4I80S>Ѻn5\.Eٲ.cI]1zjԛUN+_uzTVΣz:7gu ܀iF^mGQ/biM/?E|;OXSjpů 4^x0 .c#ȗ&EqK|0PC2"=6$M"2=LV$Tټm7ocF]a\>n&׸F}< wGb;&36{Q2/ z.0OROS\q|-^ux.Of^=ha+Gnsaٲ~yӦ=\a QN-v4A&^溳ͮ +8+4c΁L; ވ׺ ʀt'cZ'1  2qsj闒 V^qu{A|HkSypB ,הu&*\L1/fE.w+1k8+okYq_G[Vk!dc#KF3R޽f EӑT1T2ֵ,squhZיp\̜% BE@ =vD< ZQd6,d8KkBH92[[ϰnݟI=p #Sop'"s}c>v:_v/5bxfP̋2oG='u'f(T>heS ;￘?96EV~|l66(NՁy(kDBNkj_:?rӷ߃`H:f&49^ 4*+Qxö#(S_5ꑲ8,5ps3BmDҩ[ͯjV/[ږB`1t[FOw9i]W +>{^ }nxҧOޛt8@`5tN&&|)8M{ Bi*.-JVfQk!EV%k÷/g?>]kgUoTb=A?ǣfQzt+sc3دTM~-*mg*oy}8ܖHG~~u/On2b̙L`ńĩ &Ҁ+DE9}zꌤنjKt^*d@WVimS>xd>\+[w"-gϾ%h˟_mSݞL$RS⊤autyp;wD^1SsbےHj5œC?Gh%$gȷq1;EXmV0[yem9f>jhӄB}op# HGdVpc^C:'ΎyZƌp>͸݁VL=:bQu|'(HL=W5M ^85F,bU%3!:љuC> up rWAŒ+wckR Kg 6N-0.mv/RHҊъ;A%N6eZdݥ w7! K:Oт%,^1Tc5/Hk ]w|DAdwMug|޲ab^׃1\v(a!NZ5!Qw E ØoE,eqFOo#3yX) 65* σɺ? qό 9mȷOcŠlq4Y zo%tUsjmԮ3Ov@;4"V…uO+4עw y(<&'D03_F2[4q8T[  ^4YT۵V/xFg 5@ZM̨5 O4jujyFaE/"Vt' 6?Ĺ18†dW8nf]76>uGjx{J6lY(:@&` =E“D.Qދډ 5n~]<<%f|q'Wաk$~۝LG;+@e$56*({sSiN攤^uslДݐW2 Fy'^heR i(Cv72,h:Ҙؗ1wdW 8~Ɵzw_$nZRG"a@߈3\KzKW<ņ` Oejd}bQ͈HN.җ^==hFygT4N[N?m"=p1zo؟r~~E,qRI,A Gl;h=[к){nܰ)T1"_!WXx>> 5 CgGj1>o;uZ sgNk^PԚnd6|XEN?F|Po")MxG ,.\fHSHׂE0_X|B39S"(}7dwNDщ)*֧P~&Oa/}A[-8bvt3m ^_'̯q],- mOGPƮw{F%F}'^Is|=;O ڮÆJ(\i0P+UkR6j6b . V5%>%M")]A+T:j&ԗfOъG"ܮqފ Շ2;~,L(lZSVF?׷Ik:1!,D$*FJYεYFCJXfOY=*bJTo"q>ߩ>)L"vBNDޜ_18iڷZh}Pr U&53 l,XreȾtiT9YR QMU7]DP;86CTO= ~^UI>Y"}}NK<]q˱@7l)?щ&J1sݻpαm>D )g{1Y׵'@*GH UNxx"ʧ7)fH)QFıl3Xbt~Rzί)Cg֘He cQӅtuɲ]~^ȨC7!{A]2;+#w^3NqCXc{pFXv96 g |Uy6}/ڨ !}m(ތ6M;/z'Oaҳ^$Qqa*_1ߤdjS&!ם8К(zwצP>v)/55ǚIg@@H-|fC4%|rQ_)Q5醕 6y΃2/F䅙$0e@il7eQuc")7hYL:S?717U,A5gXEm۞g71@ WEJ}ԞGc3NY9mwͱNxk.E7z4+zs5A'S7B߫xti9Iiն6\\!h~lFEk6Y2-,{&0bR1)ax$F!4ޡ]%;ƏOܶLx$IPn1z]LLy?oZK?$ьcz < p4?ވUMn1&K\wƭW&EKaZ̴g k(<m Ga#SQ?gWDj).o D:n cB@Pulrw}AvWr0Ւn,@9ej.#WjA(wAJQN^ΗLy̫m9n86TGI8K7i9b2zNbzCqhg9rM=xuqfr1ZZZTfiqh^ͧX'xS 3Lu5ss4EފcKT8 |94B/˨TڜEr`@R79tgywׯcHdV۲\0W@=_NdW LJgqQ& "O*GAu HF^ɧ D/q,D+Xӆix+Ƹ}0,e 4j ki̘LmZD b*QT=E7o\UۍI4Ǧm>_(rD5e}kR (JWVm$4-gECqoY7ĬQWdj9Wheը"s$ˏ y=szhpHKPa(4b2߇9sd$&GxQݵ49~Ȥ7j&-p̣"._i 4`_|ْbvvm:+h/{cԽYl4צ~(<֛'Nh*rs5m߯AO4_;*YLOx4]υy_K$s`4Wz 쨍bq9aI2s]ǑڴрA'X]j>O-_g_Lzv%z7WV$K'Bl,V1:'V u[ (uhqԑu:SfD,f9_}P/.ޒvR&?1ʶ$[vd` Hg;\4B+2Ue|o݇;zU6M<<㗃;̩#6w^ӭjc{By͑{v5+ВvQvIH.0?*)/iRpbe֭3u8G@QmhP%fi endstream endobj 426 0 obj << /Length1 1376 /Length2 6147 /Length3 0 /Length 7094 /Filter /FlateDecode >> stream xڍvTS.MJE)IBޫH!@E@PT(D@)ҥ(U)R叞s}o#{o5߷G[IjxhN"VjX*`)0X $dBBplR_v-,#bP!2@2DA JJrDc D hFBZhL(#%P& ())H j X @qp$Dh!aA`)(2@ R#p@Kxnh E4&Z{#О`($~@ Dy@@+c/ WHA߉?P @QKBp@(#/MA~Pwß¡@]  .@*C4KAyhH8 ]6 o=g(t0 ݂G dB B`^pP +(p < :cG1h Г< 'h#z `8; ';{'N?^9FpAVv6ZISKJ+%@DZ@\D39w<@%ҿ {" C\h"c@ , 4c,w=~~"Dm'5G  oJԀߗE=8_T -0? n@%!`و?D>1:(㷺P, !DzC0Bq ' =O<@8o,*Aap,`X,Qi@,_?C08v4%TFJ'M T/=LtDէo6Z4X/7&.|QMᑴV_ ?K^Ob(`^zܩRM(_Xy)oD{ZQ2&VɨP1~J$/NK9a8 b#I8/}h,l湵t@+ #/>KUZ!'|ilS`qVgE롈WjWV~n$*2ITܬĐɭso2myYj_>S:|||.}4콩 >)>=Ό+ z> z]7O2X>HDY[.(JUPxJ*aRQsBbg9ڥQGxwYZg 2߫+jQ~.REsR3r $vd$m&9x{`BO!֯^CyN%mَnNJ9Pڽ 8l`DiO9b p$ʜvkDr+R=ŭ5MFMnG^tk]yueCGW=l2-259] ^~|.ZyQ@h@ KmC{aC}t6㜡w)o>JedxP,tƷǘIڞO]؇  >S j/oYI۾?5mh"(M|oXVB0Hc!2~i#Sv?ܿ-iRud~^)uPpKb2w FxqS㳚(`\Jޭ]'<O羻ZTtUt4/ss:SN&?hA@r(R,V/ҽKֶ2R(s]и q(<#s#Mqf2lu:'ON[ +sʛ`| 1rGei&I3V"noxܮrՂI T'F#6="fidST^#T|MK5S@f?=on Jyc<(܏MfF]+L^^L_VjȫgT=h| gmH[ Me9|VDHYd&GL-+ N:$ Xٛ9~f zQ@/u|꠵pCqTn؀Hi/m$OʱԊY[+uw_/9ɾR-y"@y,swQ-F5ɦt:K~x^/!1֬X |ٛa QNB2RJ*)TjF<..g61.4/#,| o,jPX}>g;]RCsv6!2 TMИ0;z&*{H3[cc 8\aOH|R.)*rz䔕m> dYs^dv5ێu)KQOzQ##yZO׶Cs_w-vu;=ǧ M_-Owjb4;,ց?P۞임_8;z<_ԠWGaͬy3~gU3w= wғa oyIgi>ͻ`Tek|8!ŕ婂{n{uutЛg(v|FW7Xu&7󋨥=o]QRQ@wxIn jy )#iOS-͊^rWe_"/tϑԒX)IW+͉W3*XHGTP?ݎ=/EGs/lL0|=Q6rS0>'⫿%d%^tSux +]XWGj3hjOm=:%acG[$sS]/`BR")/G߻~[tg%ڝ&uXeh:/8ay$vOf7tFTFTZlwD1Ά뛱k[~m|BxwyL +@}m?Ed֙yq м~90gxwEKux/ -/k' xqC@+5)Ÿ:~)E1]|T+dla+Ua|뻉[d, ݴsl' ZV;ޑsA|CZ2Wh}r[+*H;I <{qIS0 -hKM] JheD>>³2n%w7ԫfzK;3% Nvfըߢםޕ2Ypna묝@Sɘ}UggmZAVfB5ݡz%߅Ϛy_ =.n\; 7x_ZZP=m@ c2>b^q U w}&u`{H7҇vbaL `@z R 𸖻#JW<ꪠ/:0":qV 7LZןie# t6izZ d$i'}PVBh>J [.HfƅBZfg<x%϶R&Nfnivˌ&^glpsD?^Gͮsz-<>]ЦGI?Zv-ȎmzUu =yMZ>Brj1xk`&äFi~qۖM@Nj r[ 6]J50cyOd mn?׻hS ñ%tHr<2`+wKgr$<8ī:S!jZ;5iB!>Ţ% ~Ps]7qT9}@]|.C׺~1 W+ {ȟbnI$<*jiƸnd{^M]w=P -(}R }` Stܻf؇HAqiRMӁKKF\Y ;x'K)ˎ6]?_ĨUc\AsP$, AXQ]!J qcJ~5؍AaJ SO%L)R1YR>fË#U=5{Q|\diOEJn7zu}!IXF˸;hU J ];wk1dYo8ͥ@֣EM:zNL^Ce)jcMcpkLE"oQCksJ~^ar{P9m-&2E?Z1mP#%Ay_EARAp"|eO |ZG/½,}ΒFwKM,>痛AK1SҐ9gwr=)t|V@$ C9x^ǫcʌ(hkֹӮpu&!Tp- VA}E:aO<]Q.*kGX˦d,fCىJ2P F|r+9I'F>_r`_n@nal52T"ӚZQɐ> 销)&=t(T 7)Yz_ 1}/L!1=}R}vA}[HK]ģvCPQd= ;Xte' JmRֳ[9j*{.w,ScrZKPbcY- AܔVȭl!R< ~:,9<;.sQ/~b1ƒU]ՙ-),_9lMGy^W+ߡxPuzg>w[ b< tGJY}{Ă4,Iw1`%Ibg]N[<.HeJ'RQ L<>6''x9^w *(h- |4qML K |o RMšh,d7{iE='s?Zo=$H`.\+[Jvz5U9wެ/,cIL+GZDKtu|t#!*Kulمg|ɾMw^A BSoѪ7> stream x[ko7_1,bE8nlk6X8V#K$sC6ϤU&ƨ3% 6Sإ-Fqvm,3cS:gVsM,* <+`Wg\YEȔ.3*T8|ƌL3 d$aX:a0*IQ^9RQ` RVyeP: q 1HtT 5X%OkIPqrkG4/Q\A5&Y5 ,(4Mg@/.CmHp N:4\Ѱ4<CduL<uW]-Z_I\#zԯCvz;8ڨ`9^uo Dۣ_ W06ːyD2!Z92C,v AvD}#A:f#8ZDZYYߙ<"SN`0#pkWE90:̊9o*L210BdCqo )@ xYH,S!!<-Rn#onr:Uf/02f<@dvi7Eו=3>z;ޣW_/L_Gj^Q|:>Ǘ?{_Ol:<ϳUfҺŗ;w%)5H_TN?qvGi=\gY#r]A<?W{x\gS\?&0g/F?p-^s'xz\.yda=ta\CM.:t]t]C]q(#/C7H<O@3BkV,މ_x~"ƫtNJȜ Q/b T&zM B* p5WCYP(.+d; IWΫq9?UQڻ&@}P}=aTfr܆v$nC ų,h2 VF ‡6YaW롮UUT_]4T}Y5TnuJ_MENiX(mtM .7􆃛z9yYٔEbcxHMNOqpV͜1+zb]2إ"fxEEbkD2DQU~m\֣f&mYJ}jy-Yߦ3i_Fyk,l4Y:[:r3nx헎3 Du|$BxUˮ[Nz̀/O5Ӄ̇x<^2ӓ*P9.#ޭ?uK]fTF?#VWO}l3:-쟂O/d (l I /x ub HO!|?L$5Z~ -wsvݧ*+l+D؝_l! uCLksw;"cۓ>bDٻ#m[[}&.۽'et{ӻ+̽- #/Śhz‚/Y \|4,92_ tétN{(AsM:J9}z*TOEU=[C }vFQc"ER|KMw*Wz7W|7>_eXV|n_iei/jXe;eRmX> ,9 mvn:`b dX1;Eq64y\`-aU01ú tFmO7T36Co7~/e7;J͐ƛ*O7h&1خݐn=G!# 1w=Dn]aXALsW;̽b0Kw̽BlKgyph1r=^og0٭N|.7OYu;SYY܎?n'1麇JgmQ DQ endstream endobj 473 0 obj << /Producer (pdfTeX-1.40.22) /Author()/Title()/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20211128133936Z) /ModDate (D:20211128133936Z) /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2021/Arch Linux) kpathsea version 6.3.3) >> endobj 432 0 obj << /Type /ObjStm /N 41 /First 361 /Length 1775 /Filter /FlateDecode >> stream xڕXn7}W   PM۠"vؖaү̐k.GTșCΜ3gV2>/(g-zߠU“2&:#+rPZ`0$gVVY)8emB1^٨/eA3'ଜhA.&x\aYC2= HWqlʛ Qw$g! |iQ,:S*8  >|Q J*ĘBJ y ศ_yy{7ԟp6f)H_U1X2Ӻ.?m㫍hEs+if#}\]ȓQWo؍l|bkjޓ71mkeZ& qK-Gv#z7S׻0 0O$>SwwO%L-Zo7WZZ_͐e<|r{ w5q\b&v{ʰpټƅF0{9 EWcfLhxTEv/!α(x-BY] vZOD$ӡ$Y&,Bk%\yf򜤠ԁUXjjNhiE}4;j)¼<sݗ" kC}3֮ 0H՟3z*fl2+>m%D-!\2ޢ9fVW %`$7 qAY1vZWgJ!I@rBH7/!xSj)fhaSҦOBߋHfc%OҺ(րm\~,d!MX,Y]aZ'[ʱBiAB(MVس=a)|F7ܒ֗[{uFB(EJ9 ^O4׉)M5EW[k .uirsWe3+ :aD!N%ȉ}K  :k`q<*fya'ệ$$%$$$ܺuFXT+(~rt"Q9qfT_aB$B \ƊΈ@/'Tx#4_D`f 6- $RNk*H&##IB-&}HK]Eķ#3|)0190,@^c+Y!'hyB pZۛ;LGG6􋝾wGzBW,t)1 S ].X,mӴ>Q̩;z)Ix'']?S0pIOYMbi9K+9?|imBÍ'4<t?_t?_H4c3!NI|MY؈l$~98{X)liD3KhK#7^26|S 4ӌ'y)~akcQ0,*c@#\ņ/?ѝ`\xץK/\F,OaD~]Hs (ٷ;n&V7C=ؠc [{Qs $4zz[ dnYUف\C*WukBmP.}̔R1ԝ })VPV;fگ!^m e߿< q{Y]|ǔ3ku=[res??8= 2e` endstream endobj 474 0 obj << /Type /XRef /Index [0 475] /Size 475 /W [1 3 1] /Root 472 0 R /Info 473 0 R /ID [ ] /Length 1060 /Filter /FlateDecode >> stream xշ\EJZywV{m˻*L@HA@$ (PEt )AI:3ӷRJy?TPeYQUh-e^V3`v)8:TX.L0"Uǹx>,iBIռjp2X+`%հ:X`#lͰ6 kSj;쀃pTϧzn+%'̇V{!w jYO a܁Z0I8 8S=g p.eW!7&܂n.v__rq3x/tm->i$a`X6Oc&,pG_]Bd,͂f!XPϹu`].X u`]. Âu dq@P (.h!" -AFs6@P%T U*AuSUT U*A ܍n7Fp#нp-yT_+̆d6i0a3;HDb.9/adJ "X K`,ZX`=lqXU?j;쀝 `%7TÃ=|.7}X28LQ8H`N>ȳYKcX h72dwdw-unخ];NvLgs endstream endobj startxref 440385 %%EOF andi-0.14/configure.ac000066400000000000000000000060311415070357400146450ustar00rootroot00000000000000AC_INIT([andi], [0.14]) AM_INIT_AUTOMAKE([-Wall foreign]) AC_CONFIG_MACRO_DIR([m4]) AC_PROG_CC AC_PROG_CXX AC_PROG_MAKE_SET AC_PROG_CPP AC_PROG_RANLIB m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) # Make sure, also the C++ programs are compiled with OpenMP AC_LANG(C++) AC_OPENMP # Execute all tests using C AC_LANG(C) AC_OPENMP AC_CHECK_LIB([m],[cos]) AC_CHECK_LIB([gslcblas],[cblas_dgemm], [], [have_gsl=no]) AC_CHECK_LIB([gsl],[gsl_ran_binomial], [], [have_gsl=no]) AS_IF([test "x$have_gsl" = "xno"],[ AC_MSG_ERROR([Missing the Gnu Scientific Library.]) ]) # The libdivsufsort header contains some Microsoft extension making # compilation fail on certain systems (i.e. OS X). Add the following # flag so the build runs smoothly. CPPFLAGS="$CPPFLAGS -fms-extensions" AC_CHECK_HEADERS([divsufsort.h],[have_libdivsufsort=yes],[have_libdivsufsort=no]) AC_CHECK_LIB(divsufsort, divsufsort, [], [have_libdivsufsort=no]) AS_IF([test "x$have_libdivsufsort" = "xno"],[ AC_MSG_ERROR([Missing libdivsufsort.]) ]) # The unit tests require GLIB2. So by default do not build the test. # If enabled, check for glib. AC_ARG_ENABLE([unit-tests], [AS_HELP_STRING([--enable-unit-tests],[build unit tests @<:@default: no@:>@])], [try_unit_tests=${enableval}],[try_unit_tests=no] ) AM_CONDITIONAL([BUILD_TESTS],[test "x${try_unit_tests}" = xyes]) # The user may set a seed for the unit tests, so that builds are reproducible. # A value of 0 makes the tests random. AC_ARG_WITH([seed], [AS_HELP_STRING([--with-seed=INT], [random seed for reproducible builds. @<:@default: 0@:>@])], [SEED=$withval], [SEED=0]) AC_SUBST([SEED]) AS_IF([test "x${try_unit_tests}" = xyes], [ have_glib=yes PKG_CHECK_MODULES([GLIB], [glib-2.0], [], [have_glib=no]) if test "x${have_glib}" = xno; then AC_MSG_ERROR([Missing Glib 2. Either install it or build without unit tests.]) fi AX_CXX_COMPILE_STDCXX_11([],[mandatory]) ]) # Check for various headers including those used by libdivsufsort. AC_CHECK_HEADERS([limits.h stdlib.h string.h unistd.h stdint.h inttypes.h err.h errno.h fcntl.h]) AC_C_INLINE AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_INT32_T AC_TYPE_UINT8_T AC_HEADER_STDBOOL # Until someone convinces me otherwise, I will deactivate the macros # AC_FUNC_MALLOC and AC_FUNC_REALLOC. They only check if `malloc(0)` retuns a # non-null pointer. This breaks the build on systems using uClibc, including # my laptop. # As requesting zero bytes is not useful, and implementation-defined behaviour, # it should be avoided in the first place. Thus I really don't need these checks. AC_CHECK_FUNCS([floor pow sqrt strdup strerror]) AC_CHECK_FUNCS([strndup strcasecmp]) AC_CHECK_FUNCS([strchr strrchr strchrnul]) AC_CHECK_FUNCS([strtoul strtod]) AC_CHECK_FUNCS([reallocarray]) AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes]) AM_CONDITIONAL([HAVE_STRCHRNUL], [test "x$ac_cv_func_strchrnul" = xyes]) AC_CONFIG_HEADERS([src/config.h:src/config.hin]) AC_CONFIG_FILES([ Makefile docs/andi.1 docs/Makefile libs/Makefile opt/Makefile src/Makefile test/Makefile ]) AC_OUTPUT andi-0.14/docs/000077500000000000000000000000001415070357400133075ustar00rootroot00000000000000andi-0.14/docs/Doxyfile000066400000000000000000002234061415070357400150240ustar00rootroot00000000000000# Doxyfile 1.7.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = "andi" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = . # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ../src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # style sheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES andi-0.14/docs/Makefile.am000066400000000000000000000015261415070357400153470ustar00rootroot00000000000000dist_man_MANS = andi.1 dist_noinst_DATA = Doxyfile # I intentionally do not list any of the manual files here. I neither want them # distributed nor installed. The reason is that building the manual requires # LaTeX with a whole bunch of packages installed. Plus, so many things can go # wrong, when building, so it's better to inspect the result. Thus, the manual # has to be build by hand and copied to the right place for distribution. .PHONY: code-docs code-docs: doxygen manual/version.tex: manual/version.tex.in $(top_srcdir)/configure.ac sed "s/VERSION/$(VERSION)/" manual/version.tex.in > manual/version.tex manual/andi-manual.pdf: manual/andi-manual.tex manual/version.tex @echo "error: manual rebuild of the manual required (no pun intended)." @exit 1 # maintainer-clean-local: # rm -f manual/*{aux,log,out,toc} manual/andi-manual.pdf andi-0.14/docs/andi.1.in000066400000000000000000000101701415070357400147100ustar00rootroot00000000000000.TH ANDI "1" "2020-01-09" "@VERSION@" "andi manual" .SH NAME andi \- estimates evolutionary distances .SH SYNOPSIS .B andi [\fIOPTIONS...\fR] \fIFILES\fR... .SH DESCRIPTION \fBandi\fR estimates the evolutionary distance between closely related genomes. For this \fBandi\fR reads the input sequences from \fIFASTA\fR files and computes the pairwise anchor distance. The idea behind this is explained in a paper by Haubold et al. (2015). .SH OUTPUT The output is a symmetrical distance matrix in \fIPHYLIP\fR format, with each entry representing divergence with a positive real number. A distance of zero means that two sequences are identical, whereas other values are estimates for the nucleotide substitution rate (Jukes-Cantor corrected). For technical reasons the comparison might fail and no estimate can be computed. In such cases \fInan\fR is printed. This either means that the input sequences were too short (<200bp) or too diverse (K>0.5) for our method to work properly. .SH OPTIONS .TP \fB\-b\fR \fIINT\fR, \fB\-\-bootstrap\fR=\fIINT\fR Compute multiple distance matrices, with \fIn-1\fR bootstrapped from the first. See the paper Klötzl & Haubold (2016) for a detailed explanation. .TP \fB--file-of-filenames\fR=\fIFILE\fR Usually, \fBandi\fR is called with the filenames as commandline arguments. With this option the filenames may also be read from a file itself, with one name per line. Use a single dash (\fB'-'\fR) to read from stdin. .TP \fB\-j\fR, \fB\-\-join\fR Use this mode if each of your \fIFASTA\fR files represents one assembly with numerous contigs. \fBandi\fR will then treat all of the contained sequences per file as a single genome. In this mode at least one filename must be provided via command line arguments. For the output the filename is used to identify each sequence. .TP \fB\-l\fR, \fB\-\-low-memory\fR In multithreaded mode, \fBandi\fR requires memory linear to the amount of threads. The low memory mode changes this to a constant demand independent from the used number of threads. Unfortunately, this comes at a significant runtime cost. .TP \fB\-m\fR \fIMODEL\fR, \fB\-\-model\fR=\fIMODEL\fR Set the nucleotide evolution model to one of 'Raw', 'JC', 'Kimura', or 'LogDet'. By default the Jukes-Cantor correction is used. .TP \fB\-p\fR \fIFLOAT\fR Significance of an anchor; default: 0.025. .TP \fB--progress\fR[=\fIWHEN\fR] Print a progress bar. \fIWHEN\fR can be 'auto' (default if omitted), 'always', or 'never'. .TP \fB\-t\fR \fIINT\fR, \fB\-\-threads\fR=\fIINT\fR The number of threads to be used; by default, all available processors are used. .br Multithreading is only available if \fBandi\fR was compiled with OpenMP support. .TP \fB\-\-truncate-names\fR By default \fBandi\fR outputs the full names of sequences, optionally padded with spaces, if they are shorter than ten characters. Names longer than ten characters may lead to problems with downstream tools. With this switch names will be truncated. .TP \fB\-v\fR, \fB\-\-verbose\fR Prints additional information, including the amount of found homology. Apply multiple times for extra verboseness. .TP \fB\-h\fR, \fB\-\-help\fR Prints the synopsis and an explanation of available options. .TP \fB\-\-version\fR Outputs version information and acknowledgments. .SH COPYRIGHT Copyright \(co 2014 - 2021 Fabian Klötzl License GPLv3+: GNU GPL version 3 or later. .br This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. The full license text is available at . .PP .SH ACKNOWLEDGMENTS 1) andi: Haubold, B. Klötzl, F. and Pfaffelhuber, P. (2015). andi: Fast and accurate estimation of evolutionary distances between closely related genomes, Bioinformatics 31.8. .br 2) Algorithms: Ohlebusch, E. (2013). Bioinformatics Algorithms. Sequence Analysis, Genome Rearrangements, and Phylogenetic Reconstruction. pp 118f. .br 3) SA construction: Mori, Y. (2005). libdivsufsort, unpublished. .br 4) Bootstrapping: Klötzl, F. and Haubold, B. (2016). Support Values for Genome Phylogenies, Life 6.1. .SH BUGS .SS Reporting Bugs Please report bugs to or at . andi-0.14/docs/manual/000077500000000000000000000000001415070357400145645ustar00rootroot00000000000000andi-0.14/docs/manual/andi-manual.tex000066400000000000000000000563361415070357400175110ustar00rootroot00000000000000\documentclass[a4paper, 10pt, english, DIV=12, BCOR=8mm]{scrbook} \usepackage[utf8x]{inputenc} \usepackage{babel} \usepackage{listings} \usepackage{xcolor} \usepackage{hyperref} \usepackage{siunitx} \usepackage[T1]{fontenc} \usepackage{isodate} \usepackage{graphicx} \usepackage{amsthm} \usepackage{acronym} \usepackage{amssymb} \usepackage{caption} \usepackage{subcaption} \usepackage{xspace} \usepackage{microtype} \bibliographystyle{alpha} \DeclareSIUnit\byte{B} \DeclareSIUnit\basepairs{bp} \DeclareSIUnit\bit{bit} \definecolor{oceangreen}{cmyk}{1,.0,.20,.78} \addtokomafont{sectioning}{\rmfamily\color{oceangreen}} \definecolor{bluekeywords}{rgb}{0.13,0.13,1} \definecolor{greencomments}{rgb}{0,0.5,0} \definecolor{turqusnumbers}{rgb}{0.17,0.57,0.69} \definecolor{redstrings}{rgb}{0.5,0,0} \definecolor{lightgray}{rgb}{0.9,0.9,0.9} \usepackage{libertine} \fontfamily{libertine} \selectfont %\usepackage[scaled]{berasans} \newcommand{\thymine}{\textsc{m}\oldstylenums{2}\xspace} \newcommand{\local}{\textsc{m}\oldstylenums{1}\xspace} \newcommand{\algo}[1]{\textsc{{#1}}} \newcommand{\andi}{\algo{andi}\xspace} \newcommand{\word}[1]{\textsf{\small#1}} \newcommand{\wchar}[1]{\textsf{\small#1}} \newcommand{\eco}{\textsc{eco}\oldstylenums{29}\xspace} \newcommand{\pneu}{\textsc{Pneu}\oldstylenums{3085}\xspace} \include{version} % Todos at the margin \newcommand{\todo}[1]{ \marginpar{\fbox{\begin{minipage}{0.9\marginparwidth} \scriptsize\sloppy\raggedright #1 \end{minipage}}} } \newtheorem{definition}{Definition} \lstset{backgroundcolor=\color{lightgray}} \lstdefinestyle{shell}{ language=bash, columns=flexible, xleftmargin=12pt, xrightmargin=12pt, breaklines=true, basicstyle=\small\ttfamily, morekeywords={make, tar, git, sudo, andi, time, man, head, cut, fneighbor, fretree, figtree, brew, aura, autoreconf, ls}, % literate={~} {$\sim$}{1} } \lstset{style=shell} \title{Documentation of \algo{andi}} \subtitle{Rapid Estimation of Evolutionary Distances between Genomes\\ {\small\url{https://github.com/EvolBioInf/andi}}} \author{Fabian Klötzl\\ \href{mailto:kloetzl@evolbio.mpg.de}{kloetzl@evolbio.mpg.de}} \date{Version \version, \isodate\today \\ \vspace*{2cm} \centering\includegraphics[width=0.8\textwidth]{andi_labels.pdf}} \begin{document} \maketitle \section*{Abstract} This is the documentation of the \andi program for estimating the evolutionary distance between closely related genomes. These distances can be used to rapidly infer phylogenies for big sets of genomes. Because \andi does not compute full alignments, it is so efficient that it scales well up to thousands of bacterial genomes. This is scientific software. Please cite our paper \cite{andi} if you use \andi in your publication. Also refer to the paper for the internals of \andi. Additionally, there is a Master's thesis with even more in depth analysis of \andi \cite{kloetzl}. \vspace*{1cm} \section*{License} This document is release under the Creative Commons Attribution Share-Alike license. This means, you are free to copy and redistribute this document. You may even remix, tweak and build upon this document, as long as you credit me for the work I've done and release your document under the identical terms. The full legal code is available online: {\small\url{https://creativecommons.org/licenses/by-sa/4.0/legalcode}}. \tableofcontents \chapter{Installation} %%%%% \section{Package Manager} The easiest way to install \andi is via a package manager. This also handles all dependencies for you. \noindent Debian and Ubuntu: \begin{lstlisting} ~ % sudo apt-get install andi \end{lstlisting} \noindent macOS with homebrew: \begin{lstlisting} ~ % brew tap brewsci/bio ~ % brew install andi \end{lstlisting} \noindent ArchLinux AUR package with aura: \begin{lstlisting} ~ % aura -A andi \end{lstlisting} \andi is intended to be run in a \algo{Unix} commandline such as \lstinline$bash$ or \lstinline$zsh$. All examples in this document are also intended for that environment. You can verify that \andi was installed correctly by executing \lstinline$andi -h$. This should give you a list of all available options (see Section~\ref{sec:options}). \section{Source Package} \label{sub:regular} To build \andi from source, download the latest \href{https://github.com/EvolBioInf/andi/releases}{release} from GitHub. Please note, that \andi requires the \algo{Gnu Scientific Library} and \algo{libdivsufsort}\footnote{\url{https://github.com/y-256/libdivsufsort}} for optimal performance \cite{divsufsort}. Once you have downloaded the package, unzip it and change into the newly created directory. \begin{lstlisting} ~ % tar -xzvf andi-0.14.tar.gz ~ % cd andi-0.14 \end{lstlisting} \noindent Now build and install \andi. \begin{lstlisting} ~/andi-0.14 % ./configure ~/andi-0.14 % make ~/andi-0.14 % sudo make install \end{lstlisting} \noindent This installs \andi for all users on your system. If you do not have root privileges, you will find a working copy of \andi in the \lstinline$src$ subdirectory. For the rest of this documentation, it is assumed, that \andi is in your \textdollar\lstinline!PATH!. Now \andi should be ready for use. Try invoking the help. \begin{lstlisting} ~/andi-0.14 % ~/andi Usage: andi [OPTIONS...] FILES... FILES... can be any sequence of FASTA files. Use '-' as file name to read from stdin. Options: -b, --bootstrap=INT Print additional bootstrap matrices --file-of-filenames=FILE Read additional filenames from FILE; one per line -j, --join Treat all sequences from one file as a single genome -l, --low-memory Use less memory at the cost of speed -m, --model=MODEL Pick an evolutionary model of 'Raw', 'JC', 'Kimura', 'LogDet'; default: JC -p FLOAT Significance of an anchor; default: 0.025 --progress=WHEN Print a progress bar 'always', 'never', or 'auto'; default: auto -t, --threads=INT Set the number of threads; by default, all processors are used --truncate-names Truncate names to ten characters -v, --verbose Prints additional information -h, --help Display this help and exit --version Output version information and acknowledgments \end{lstlisting} \noindent \andi also comes with a man page, which can be accessed via \lstinline$man andi$. % But once you are done with this documentation, you will require it scarcely. \section{Installing from Git Repository} To build \andi from the \algo{Git} repo, you will also need the \algo{autotools}. Refer to your OS documentation for installation instructions. Once done, execute the following steps. \begin{lstlisting} ~ % git clone git@github.com:EvolBioInf/andi.git ~ % cd andi ~/andi % autoreconf -fi -Im4 \end{lstlisting} \noindent Continue with the \algo{Gnu} trinity as described in Section~\ref{sub:regular}. \chapter{Usage} %%%%% The input sequences for \andi should be in \algo{Fasta} format. Any number of files can be passed. Each file may contain more than one sequence. \begin{lstlisting} ~ % andi S1.fasta S2.fasta 2 S1 0.0000 0.0979 S2 0.0979 0.0000 \end{lstlisting} If no file argument is given, \andi reads the input from \algo{stdin}. This makes it convenient to use in \algo{Unix} pipelines. \begin{lstlisting} ~ % cat S1.fasta S2.fasta | andi 2 S1 0.0000 0.0979 S2 0.0979 0.0000 \end{lstlisting} The output of \andi is a matrix in \algo{Phylip} style: On the first line the number of compared sequences is given, \lstinline!2! in our example. Then the matrix is printed, where each line is preceded by the name of the $i$th sequence. Note that the matrix is symmetric and the main diagonal contains only zeros. The numbers themselves are evolutionary distances, estimated from substitution rates. \section{Input} \label{sec:join} As mentioned before, \andi reads in \algo{Fasta} files. It recognizes only the four standard bases and is case insensitive (RegEx: \lstinline![acgtACGT]!). All other residue symbols are excluded from the analysis and \andi prints a warning, when this happens. If instead of distinct sequences, a \algo{Fasta} file contains contigs belonging to a single taxon, \andi will treat them as a unit when switched into \algo{join} mode. This can be achieved by using the \lstinline!-j! or \lstinline!--join! command line switch. \begin{lstlisting} ~ % andi --join E_coli.fasta Shigella.fasta [Output] \end{lstlisting} When the \algo{join} mode is active, the file names are used to label the individual sequences. Thus, in \algo{join} mode, each genome has to be in its own file, and furthermore, at least one filename has to be given via the command line. If not enough file names are provided, \andi will try to read sequences from the standard input stream. This behaviour can be explicitly triggered by passing a single dash (\lstinline$-$) as a file name, which is useful in pipelines. If \andi seems to take unusually long, or requires huge amounts of memory, then you might have forgotten the \algo{join} switch. This makes \andi compare each contig instead of each genome, resulting in many more comparisons! Since version 0.12 \andi produces a progressmeter on the standard error stream. \andi tries to be smart about when to show or hide the progress bar. You can manually change this behaviour using the \lstinline!--progress! option. Starting with version 0.11 \andi supports an extra way of input. Instead of passing file names directly to \andi via the commandline arguments, the file names may also be read from a file itself. Using this new \lstinline$--file-of-filenames$ argument can work around limitations imposed be the shell. The following three snippets have the same functionality. \begin{lstlisting} ~ % andi --join *.fasta [Output] \end{lstlisting} \begin{lstlisting} ~ % ls *.fasta > filenames.txt ~ % andi --join --file-of-filenames filenames.txt [Output] \end{lstlisting} \begin{lstlisting} ~ % ls *.fasta | andi --join --file-of-filenames - [Output] \end{lstlisting} \section{Output} The output of \andi is written to \lstinline$stdout$. This makes it easy to use on the command line and within shell scripts. As seen before, the matrix, computed by \algo{andi}, is given in \algo{Phylip} format \cite{phylip}. \begin{lstlisting} ~ % cat S1.fasta S2.fasta | andi 2 S1 0.0000 0.0979 S2 0.0979 0.0000 \end{lstlisting} If the computation completed successfully, \andi exits with the status code 0. Otherwise, the value of \lstinline$errno$ is used as the exit code. \andi can also produce warnings and error messages for the user's convenience. These messages are printed to \lstinline$stderr$ and thus do not interfere with the normal output. \section{Options} \label{sec:options} \andi takes a small number of commandline options, of which even fewer are of interest on a day-to-day basis. If \lstinline$andi -h$ displays a \lstinline$-t$ option, then \andi was compiled with multi-threading support (implemented using \algo{OpenMP}). By default, \andi uses all available processors. However, to restrict the number of threads, use \lstinline$-t$. \begin{lstlisting} ~ % time andi ../test/1M.1.fasta -t 1 2 S1 0.0000 0.0995 S2 0.0995 0.0000 ./andi ../test/1M.1.fasta 0,60s user 0,01s system 99% cpu 0,613 total ~ % time andi ../test/1M.1.fasta -t 2 2 S1 0.0000 0.0995 S2 0.0995 0.0000 ./andi ../test/1M.1.fasta -t 2 0,67s user 0,03s system 195% cpu 0,362 total \end{lstlisting} In the above examples the runtime dropped from \SI{0.613}{\second}, to \SI{0.362}{\second} using two threads. Giving \andi more threads than input genomes leads to no further speed improvement. \, The other important option is \lstinline$--join$ (see Section~\ref{sec:join}). By default, the distances computed by \andi are \emph{Jukes-Cantor} corrected \cite{jukescantor}. Other evolutionary models are also implemented (Kimura \cite{kimura}, LogDet \cite{logdet}, raw). The \lstinline$--model$ parameter can be used to switch between them. Since version 0.9.4 \andi includes a bootstrapping method. It can be activated via the \lstinline$--bootstrap$ or \lstinline$-b$ switch. This option takes a numeric argument representing the number of matrices to create. The output can then be piped into \algo{phylip}. For more information on computing support values from distance matrices see \cite{afra}. \begin{lstlisting} ~ % andi -b 2 ../test/1M.1.fasta 2 S1 0.0000 0.1067 S2 0.1067 0.0000 2 S1 0.0000 0.1071 S2 0.1071 0.0000 \end{lstlisting} The original \algo{phylip} only supports distance matrices with names no longer than ten characters. However, this sometimes leads to problems with long accession numbers. Starting with version 0.11 \andi prints the full name of a sequence, even if it is longer than ten characters. If your downstream tools have trouble with this, use \lstinline$--truncate-names$ to reimpose the limit. Also new in version 0.11 is the \lstinline$--file-of-filenames$ option. See Section~\ref{sec:join} for details. \section{Example: \algo{eco29}} Here follows a real-world example of how to use \algo{andi}. It makes heavy use of the commandline and tools like \algo{Phylip}. If you prefer \algo{R}, check out this excellent blog post by Kathryn Holt.\footnote{\url{http://holtlab.net/2015/05/08/r-code-to-infer-tree-from-andi-output/}} As a data set we use \algo{eco29}; 29 genomes of \textit{E. Coli} and \textit{Shigella}. You can download the data from here: {\small{\url{http://guanine.evolbio.mpg.de/andi/eco29.fasta.gz}}}. The genomes have an average length of 4.9~million nucleotides amounting to a total \SI{138}{\mega\byte}. \algo{eco29} comes a single \algo{fasta} file, where each sequence is a genome. To calculate their pairwise distances, enter \begin{lstlisting} ~ % andi eco29.fasta > eco29.mat andi: The input sequences contained characters other than acgtACGT. These were automatically stripped to ensure correct results. \end{lstlisting} \noindent The \algo{eco29} data set includes non-canonical nucleotides, such as \word{Y}, \word{N}, and \word{P}, which get stripped from the input sequences. The resulting matrix is stored in \lstinline$eco29.mat$; Here is a small excerpt: \begin{lstlisting} ~ % head -n 5 eco29.mat | cut -d ' ' -f 1-5 29 gi|563845 0.0000e+00 1.8388e-02 1.8439e-02 2.6398e-02 gi|342360 1.8388e-02 0.0000e+00 4.4029e-04 2.6166e-02 gi|300439 1.8439e-02 4.4029e-04 0.0000e+00 2.6123e-02 gi|261117 2.6398e-02 2.6166e-02 2.6123e-02 0.0000e+00 \end{lstlisting} \noindent From this we compute a tree via neighbor-joining using a \algo{Phylip} wrapper called \algo{Embassy}.\footnote{\url{http://emboss.sourceforge.net/embassy/\#PHYLIP}} \begin{lstlisting} ~ % fneighbor -datafile eco29.mat -outfile eco29.phylipdump \end{lstlisting} \noindent To make this tree easier to read, we can midpoint-root it. \begin{lstlisting} ~ % fretree -spp 29 -intreefile eco29.treefile -outtreefile eco29.tree <0.5$) or sprout a lot of indels that make comparison difficult. \subsection*{Little Homology} Very few anchors were found and thus only a tiny part of the sequences is considered homologous. Expect that the given distance is erroneous. \subsection*{Too long name} If you added the \lstinline$--truncate-names$ switch and an input name is longer than ten characters, you will receive this warning. \chapter{DevOps} %%%%% \andi is written in C/C++; mostly C99 with some parts in C++11. The sources are released on \algo{GitHub} as \emph{free software} under the \textsc{Gnu General Public License version~3} \cite{GPL}. Prebundled packages using \algo{autoconf} are also available, with the latest release being {\version} at the time of writing. If you are interested in the internals of \algo{andi}, consult the paper \cite{andi} or my Master's thesis \cite{kloetzl}. Both explain the used approach in detail. The latter emphasizes the used algorithms, data structures and their efficient implementation. \section{Dependencies} Here is a complete list of dependencies required for developing \algo{andi}. \begin{itemize} \item A C and a C++11 compiler, \item the \algo{autotools}, \item the \algo{Gnu Scientific Library}, \item \algo{Pdflatex} with various packages for the manual, \item \algo{Git}, \item \algo{glib2} for the unit tests, \item \algo{doxygen}, \item and \algo{libdivsufsort}. \end{itemize} \section{Code Documentation} \emph{Every} function in \andi is documented using \algo{doxygen} style comments. To create the documentation run \lstinline$make code-docs$ in the main directory. You will then find the documentation under \lstinline$./docs$. \section{Unit Tests} The unit tests are located in the \andi repository under the \lstinline$./test$ directory. Because they require \algo{glib2}, and a C++11 compiler, they are deactivated by default. To enable them, execute \begin{lstlisting} ~/andi % ./configure --enable-unit-tests \end{lstlisting} \noindent during the installation process. You can then verify the build via \begin{lstlisting} ~/andi % make check \end{lstlisting} \noindent The unit tests are also checked each time a commit is sent to the repository. This is done via \algo{TravisCI}.\footnote{\url{https://travis-ci.org/EvolBioInf/andi}} Thus, a warning is produced, when the builds fail, or the unit tests did not run successfully. Currently, the unit tests cover more than 75\% of the code. This is computed via the \algo{Travis} builds and a service called \algo{Coveralls}.\footnote{\url{https://coveralls.io/r/EvolBioInf/andi}} \section{Known Issues} These minor issues are known. I intend to fix them, when I have time. \begin{enumerate} \item This code will not work under Windows. At two places Unix-only code is used: filepath-separators are assumed to be \lstinline$/$ and file-descriptors are used for I/O. \item Unit tests for the bootstrapped matrices are missing. \item Cached intervals are sometimes not “as deep as they could be”. If that got fixed \lstinline$get_match_cache$ could bail out on \lstinline$ij.lcp < CACHE_LENGTH$. However the \lstinline$esa_init_cache$ code is the most fragile part and should be handled with care. \end{enumerate} \section{Creating a Release} A release should be a stable version of \andi with significant improvements over the last version. dotdot releases should be avoided. %\subsection{Preparing a new Release} Once \andi is matured, the new features implemented, and all tests were run, a new release can be created. First, increase the version number in \lstinline$configure.ac$. Commit that change in git, and tag this commit with \lstinline$vX.y$. Tags should be annotated and signed, if possible. This manual then needs manual rebuilding. Ensure that \andi is ready for packaging with \algo{autoconf}. \begin{lstlisting} ~ % make distcheck make dist-gzip am__post_remove_distdir='@:' make[1]: Entering directory `/home/kloetzl/Projects/andi' if test -d "andi-0.9.1-beta"; then find "andi-0.9.1-beta" -type d ! -perm -200 -exec chmod u+w {} ';' && rm -rf "andi-0.9.1-beta" || { sleep 5 && rm -rf "andi-0.9.1-beta"; }; else :; fi test -d "andi-0.9.1-beta" || mkdir "andi-0.9.1-beta" (cd src && make top_distdir=../andi-0.9.1-beta distdir=../andi-0.9.1-beta/src \ am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir) ... Loads of output ... ================================================= andi-0.9.1-beta archives ready for distribution: andi-0.9.1-beta.tar.gz ================================================= \end{lstlisting} If the command does not build successfully, no tarballs will be created. This may necessitate further study of \algo{autoconf} and \algo{automake}. Also verify that the recent changes did not create a performance regression. This includes testing both ends of the scale: \eco and \pneu. Both should be reasonable close to previous releases. Create another commit, where you set the version number to the next release (e.\,g., \lstinline$vX.z-beta$). This assures that there is only one commit and build with that specific version. \backmatter %\addcontentsline{toc}{chapter}{Bibliography} \bibliography{references} \end{document} andi-0.14/docs/manual/andi_labels.pdf000066400000000000000000000054211415070357400175160ustar00rootroot00000000000000%PDF-1.4 % 5 0 obj <>stream x+r 26S030VIr *T0T0Bf endstream endobj 7 0 obj <>>>/MediaBox[0 0 793 639]>> endobj 2 0 obj <> endobj 1 0 obj <>/Font<>>>/Subtype/Form/BBox[0 0 793 639]/Matrix [1 0 0 1 0 0]/Length 1617/FormType 1/Filter/FlateDecode>>stream xWKsGﯘcr0==ϣ- `CL֦I}im@I3_%FqOJ>qsx;< ZSPj%n/=~lrU*WyK)thk<rmgAh%,%1H"p$Al?(q*^j< '-Hc+c:&^X`a +FE8@ҢV ` :@cUyOJ'*^7XeNLNPHvc6 :迡:Hm;.oRZ@Eg EY),E>J f<Pr1Q/羚aŵk_VWm=)pJkP56 X_tg<͗0Sl:m<><^~R< ҉F %Ҥ-YW@ҋRl;.*.&Қ󪾑7wwbu; :I fy'Q6=Nm.Z}ܯh=6Ul$tA"=]J:_߶N~ 7_eZE}E]΢Qp7*lri r~yb -V5bO9\CnڀIZSL^xZ+:jB_iJvL WS[wzEciu~TS*zUEDlev?=E.HOBc#*ʹ4]7o~QzA?{ 꾬^qA>I&'a"^G7A$؜`$Xmxv񉮂wmr'~R;q`MQ endstream endobj 3 0 obj <> endobj 4 0 obj <> endobj 6 0 obj <> endobj 8 0 obj <> endobj 9 0 obj <> endobj xref 0 10 0000000000 65535 f 0000000334 00000 n 0000000246 00000 n 0000002161 00000 n 0000002192 00000 n 0000000015 00000 n 0000002223 00000 n 0000000130 00000 n 0000002274 00000 n 0000002319 00000 n trailer <<2fd9b203f0cc5c36c5491af452364469>]/Info 9 0 R/Size 10>> %iText-5.4.5 startxref 2472 %%EOF andi-0.14/docs/manual/references.bib000066400000000000000000000100731415070357400173640ustar00rootroot00000000000000@misc{divsufsort, author="Yuta Mori", year="2005", title="Short description of improved two-stage suffix sorting algorithm", note="\url{http://homepage3.nifty.com/wpage/software/itssort.txt}" } @article{andi, author = {Haubold, Bernhard and Klötzl, Fabian and Pfaffelhuber, Peter}, title = {andi: Fast and accurate estimation of evolutionary distances between closely related genomes}, volume = {31}, number = {8}, pages = {1169-1175}, year = {2015}, doi = {10.1093/bioinformatics/btu815}, URL = {http://bioinformatics.oxfordjournals.org/content/31/8/1169.abstract}, eprint = {http://bioinformatics.oxfordjournals.org/content/31/8/1169.full.pdf+html}, journal = {Bioinformatics} } @book{Felsenstein, author={Joseph Felsenstein}, title={Inferring Phylogenies}, year={2004}, publisher={Sinauer Associates, Inc.} } @misc{GPL, author={{Free~Software~Foundation}}, year={2007}, title={Gnu General Public License}, note={\url{https://gnu.org/licenses/gpl.html}} } @misc{phylip, author={Felsenstein, J.}, year={2005}, title={PHYLIP (Phylogeny Inference Package)}, version={version 3.6}, howpublished={Distributed by the author}, note={Department of Genome Sciences, University of Washington.} } @InProceedings{LLVM, Author = {Chris Lattner and Vikram Adve}, Title = {{LLVM}: A Compilation Framework for Lifelong Program Analysis and Transformation}, Booktitle = "Code Generation and Optimization", Month = {Mar}, Year = {2004}, pages = {75--88}, Publisher={International Symposium on Code Generation and Optimization} } @article{ms, author = {Hudson, Richard R.}, title = {Generating samples under a Wright–Fisher neutral model of genetic variation}, volume = {18}, number = {2}, pages = {337-338}, year = {2002}, doi = {10.1093/bioinformatics/18.2.337}, URL = {http://bioinformatics.oxfordjournals.org/content/18/2/337.abstract}, eprint = {http://bioinformatics.oxfordjournals.org/content/18/2/337.full.pdf+html}, journal = {Bioinformatics} } @article{valgrind, author = {Nethercote, Nicholas and Seward, Julian}, title = {Valgrind: A Framework for Heavyweight Dynamic Binary Instrumentation}, journal = {SIGPLAN Not.}, issue_date = {June 2007}, volume = {42}, number = {6}, month = jun, year = {2007}, issn = {0362-1340}, pages = {89--100}, numpages = {12}, url = {http://doi.acm.org/10.1145/1273442.1250746}, doi = {10.1145/1273442.1250746}, acmid = {1250746}, publisher = {ACM}, keywords = {Memcheck, Valgrind, dynamic binary analysis, dynamic binary instrumentation, shadow values} } @misc{figtree, title="FigTree", author={Andrew Rambaut}, year={accessed 2015}, note={\url{http://tree.bio.ed.ac.uk/software/figtree/}} } @article{jukescantor, author={Jukes, T. H. and Cantor, C. R.}, year={1969}, title={Evolution of protein molecules}, journal={Mammalian protein metabolism}, volume={3}, pages={21-132}, publisher={Academic Press} } @mastersthesis{kloetzl, author={Fabian Kl{\"o}tzl}, school={University of L\"ubeck}, year={2015}, title={Efficient Estimation of Evolutionary Distances} } @article{afra, AUTHOR = {Klötzl, Fabian and Haubold, Bernhard}, TITLE = {Support Values for Genome Phylogenies}, JOURNAL = {Life}, VOLUME = {6}, YEAR = {2016}, NUMBER = {1}, PAGES = {11}, URL = {http://www.mdpi.com/2075-1729/6/1/11}, ISSN = {2075-1729}, DOI = {10.3390/life6010011} } @article{logdet, AUTHOR = {Lockhart, P.J. and M.A. Steel and M.D. Hendy and D. Penny}, TITLE = {Recovering Evolutionary Trees under a More Realistic Model of Sequence Evolution}, JOURNAL = {Molecular Biology and Evolution}, VOLUME = {11}, YEAR = {1994}, NUMBER = {4}, PAGES = {605-612}, DOI = {10.1093/oxfordjournals.molbev.a040136} } @article{kimura, AUTHOR = {Kimura, M.}, TITLE = {A Simple Method for Estimating Evolutionary Rate of Base Substitutions Through Comparative Studies of Nucleotide Sequences}, JOURNAL = {Journal of Molecular Evolution}, VOLUME = {16}, YEAR = {1980}, NUMBER = {2}, PAGES = {111-120}, DOI = {10.1007/BF01731581} } andi-0.14/docs/manual/version.tex.in000066400000000000000000000000401415070357400173720ustar00rootroot00000000000000 \newcommand{\version}{VERSION} andi-0.14/libs/000077500000000000000000000000001415070357400133105ustar00rootroot00000000000000andi-0.14/libs/Makefile.am000066400000000000000000000002551415070357400153460ustar00rootroot00000000000000# (C) 2015, Fabian Klötzl ISC License noinst_LIBRARIES= libpfasta.a libpfasta_a_SOURCES= pfasta.c pfasta.h libpfasta_a_CPPFLAGS= -I$(top_srcdir)/opt andi-0.14/libs/pfasta.c000066400000000000000000000402471415070357400147410ustar00rootroot00000000000000/* * Copyright (c) 2015-2020, Fabian Klötzl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #include #include #include #include #include #include #include #include #include #include "pfasta.h" #define VERSION "v15" #ifdef __SSE2__ #include #endif #if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) #include #define PFASTA_THREADSAFE 1 #else #define thread_local #define PFASTA_THREADSAFE 0 #endif int pfasta_threadsafe() { return PFASTA_THREADSAFE ; } /** The following is the maximum length of an error string. It has to be * carefully chosen, so that all calls to PF_FAIL_STR succeed. For instance, * the line number can account for up to 20 characters. */ #define PF_ERROR_STRING_LENGTH 100 thread_local char errstr_buffer[PF_ERROR_STRING_LENGTH]; void *pfasta_reallocarray(void *ptr, size_t nmemb, size_t size); #define BUFFER_SIZE 16384 #define LIKELY(X) __builtin_expect((intptr_t)(X), 1) #define UNLIKELY(X) __builtin_expect((intptr_t)(X), 0) enum { NO_ERROR, E_EOF, E_ERROR, E_ERRNO, E_BUBBLE, E_STR, E_STR_CONST }; #define PF_FAIL_ERRNO(PP) \ do { \ (void)strerror_r(errno, errstr_buffer, PF_ERROR_STRING_LENGTH); \ (PP)->errstr = errstr_buffer; \ return_code = E_ERRNO; \ goto cleanup; \ } while (0) #define PF_FAIL_BUBBLE_CHECK(PP, CHECK) \ do { \ if (UNLIKELY(CHECK)) { \ return_code = CHECK; \ goto cleanup; \ } \ } while (0) #define PF_FAIL_BUBBLE(PP) \ do { \ if (UNLIKELY((PP)->errstr)) { \ return_code = E_BUBBLE; \ goto cleanup; \ } \ } while (0) #define PF_FAIL_STR_CONST(PP, STR) \ do { \ (PP)->errstr = (STR); \ return_code = E_STR_CONST; \ goto cleanup; \ } while (0) #define PF_FAIL_STR(PP, ...) \ do { \ (void)snprintf(errstr_buffer, PF_ERROR_STRING_LENGTH, __VA_ARGS__); \ (PP)->errstr = errstr_buffer; \ return_code = E_STR; \ goto cleanup; \ } while (0) int pfasta_read_name(struct pfasta_parser *pp, struct pfasta_record *pr); int pfasta_read_comment(struct pfasta_parser *pp, struct pfasta_record *pr); int pfasta_read_sequence(struct pfasta_parser *pp, struct pfasta_record *pr); static inline char *buffer_begin(struct pfasta_parser *pp); static inline char *buffer_end(struct pfasta_parser *pp); static inline int buffer_advance(struct pfasta_parser *pp, size_t steps); static inline int buffer_is_empty(const struct pfasta_parser *pp); static inline int buffer_is_eof(const struct pfasta_parser *pp); static inline int buffer_peek(struct pfasta_parser *pp); static inline int buffer_read(struct pfasta_parser *pp); typedef struct dynstr { char *str; size_t capacity, count; } dynstr; static inline char *dynstr_move(dynstr *ds); static inline int dynstr_init(dynstr *ds, struct pfasta_parser *pp); static inline size_t dynstr_len(const dynstr *ds); static inline void dynstr_free(dynstr *ds); static inline int dynstr_append(dynstr *ds, const char *str, size_t length, struct pfasta_parser *pp); static inline int my_isspace(int c) { // ascii whitespace return (c >= '\t' && c <= '\r') || (c == ' '); } const char *pfasta_version(void) { return VERSION; } int buffer_init(struct pfasta_parser *pp) { int return_code = 0; pp->buffer = malloc(BUFFER_SIZE); if (!pp->buffer) PF_FAIL_ERRNO(pp); int check = buffer_read(pp); PF_FAIL_BUBBLE_CHECK(pp, check); cleanup: return return_code; } int buffer_read(struct pfasta_parser *pp) { int return_code = NO_ERROR; ssize_t count = read(pp->file_descriptor, pp->buffer, BUFFER_SIZE); if (UNLIKELY(count < 0)) PF_FAIL_ERRNO(pp); if (UNLIKELY(count == 0)) { // EOF pp->fill_ptr = pp->buffer; pp->read_ptr = pp->buffer + 1; pp->errstr = "EOF (maybe error)"; // enable bubbling return E_EOF; } pp->read_ptr = pp->buffer; pp->fill_ptr = pp->buffer + count; cleanup: return return_code; } int buffer_peek(struct pfasta_parser *pp) { return LIKELY(pp->read_ptr < pp->fill_ptr) ? *(unsigned char *)pp->read_ptr : EOF; } char *buffer_begin(struct pfasta_parser *pp) { return pp->read_ptr; } char *buffer_end(struct pfasta_parser *pp) { return pp->fill_ptr; } inline int buffer_advance(struct pfasta_parser *pp, size_t steps) { int return_code = 0; pp->read_ptr += steps; if (UNLIKELY(pp->read_ptr >= pp->fill_ptr)) { assert(pp->read_ptr == pp->fill_ptr); int check = buffer_read(pp); // resets pointers PF_FAIL_BUBBLE_CHECK(pp, check); } cleanup: return return_code; } int buffer_is_empty(const struct pfasta_parser *pp) { return pp->read_ptr == pp->fill_ptr; } int buffer_is_eof(const struct pfasta_parser *pp) { return pp->read_ptr > pp->fill_ptr; } char *find_first_space(const char *begin, const char *end) { size_t offset = 0; size_t length = end - begin; #ifdef __SSE2__ typedef __m128i vec_type; static const size_t vec_size = sizeof(vec_type); const vec_type all_tab = _mm_set1_epi8('\t' - 1); const vec_type all_carriage = _mm_set1_epi8('\r' + 1); const vec_type all_space = _mm_set1_epi8(' '); size_t vec_offset = 0; size_t vec_length = (end - begin) / vec_size; for (; vec_offset < vec_length; vec_offset++) { vec_type chunk; memcpy(&chunk, begin + vec_offset * vec_size, vec_size); // isspace: \t <= char <= \r || char == space vec_type v1 = _mm_cmplt_epi8(all_tab, chunk); vec_type v2 = _mm_cmplt_epi8(chunk, all_carriage); vec_type v3 = _mm_cmpeq_epi8(chunk, all_space); unsigned int vmask = (_mm_movemask_epi8(v1) & _mm_movemask_epi8(v2)) | _mm_movemask_epi8(v3); if (UNLIKELY(vmask)) { offset += __builtin_ctz(vmask); offset += vec_offset * vec_size; return (char *)begin + offset; } } offset += vec_offset * vec_size; #endif for (; offset < length; offset++) { if (my_isspace(begin[offset])) break; } return (char *)begin + offset; } char *find_first_not_space(const char *begin, const char *end) { size_t offset = 0; size_t length = end - begin; for (; offset < length; offset++) { if (!my_isspace(begin[offset])) break; } return (char *)begin + offset; } size_t count_newlines(const char *begin, const char *end) { size_t offset = 0; size_t length = end - begin; size_t newlines = 0; for (; offset < length; offset++) { if (begin[offset] == '\n') newlines++; } return newlines; } static int copy_word(struct pfasta_parser *pp, dynstr *target) { int return_code = 0; int c; while (c = buffer_peek(pp), c != EOF && LIKELY(!my_isspace(c))) { char *end_of_word = find_first_space(buffer_begin(pp), buffer_end(pp)); size_t word_length = end_of_word - buffer_begin(pp); assert(word_length > 0); int check = dynstr_append(target, buffer_begin(pp), word_length, pp); PF_FAIL_BUBBLE_CHECK(pp, check); check = buffer_advance(pp, word_length); PF_FAIL_BUBBLE_CHECK(pp, check); } cleanup: return return_code; } static int skip_whitespace(struct pfasta_parser *pp) { int return_code = 0; while (my_isspace(buffer_peek(pp))) { char *split = find_first_not_space(buffer_begin(pp), buffer_end(pp)); // advance may clear the buffer. So count first … size_t newlines = count_newlines(buffer_begin(pp), split); int check = buffer_advance(pp, split - buffer_begin(pp)); PF_FAIL_BUBBLE_CHECK(pp, check); // … and then increase the counter. pp->line_number += newlines; } cleanup: return return_code; } struct pfasta_parser pfasta_init(int file_descriptor) { int return_code = 0; struct pfasta_parser pp = {0}; pp.line_number = 1; pp.file_descriptor = file_descriptor; int check = buffer_init(&pp); if (check && check != E_EOF) PF_FAIL_BUBBLE_CHECK(&pp, check); if (buffer_is_empty(&pp) || buffer_is_eof(&pp)) { PF_FAIL_STR(&pp, "File is empty."); } if (buffer_peek(&pp) != '>') { PF_FAIL_STR(&pp, "File must start with '>'."); } cleanup: // free buffer if necessary if (return_code) { pfasta_free(&pp); } pp.done = return_code || buffer_is_eof(&pp); return pp; } struct pfasta_record pfasta_read(struct pfasta_parser *pp) { int return_code = 0; struct pfasta_record pr = {0}; int check = pfasta_read_name(pp, &pr); PF_FAIL_BUBBLE_CHECK(pp, check); check = pfasta_read_comment(pp, &pr); PF_FAIL_BUBBLE_CHECK(pp, check); check = pfasta_read_sequence(pp, &pr); PF_FAIL_BUBBLE_CHECK(pp, check); cleanup: if (return_code) { pfasta_record_free(&pr); pfasta_free(pp); } pp->done = return_code || buffer_is_eof(pp); return pr; } int pfasta_read_name(struct pfasta_parser *pp, struct pfasta_record *pr) { int return_code = 0; dynstr name; dynstr_init(&name, pp); PF_FAIL_BUBBLE(pp); assert(!buffer_is_empty(pp)); if (buffer_peek(pp) != '>') { PF_FAIL_STR(pp, "Expected '>' but found '%c' on line %zu.", buffer_peek(pp), pp->line_number); } int check = buffer_advance(pp, 1); // skip > if (check == E_EOF) PF_FAIL_STR(pp, "Unexpected EOF in name on line %zu.", pp->line_number); PF_FAIL_BUBBLE(pp); check = copy_word(pp, &name); if (check == E_EOF) PF_FAIL_STR(pp, "Unexpected EOF in name on line %zu.", pp->line_number); PF_FAIL_BUBBLE(pp); if (dynstr_len(&name) == 0) PF_FAIL_STR(pp, "Empty name on line %zu.", pp->line_number); pr->name_length = dynstr_len(&name); pr->name = dynstr_move(&name); cleanup: if (return_code) { dynstr_free(&name); } return return_code; } int pfasta_read_comment(struct pfasta_parser *pp, struct pfasta_record *pr) { int return_code = 0; if (buffer_peek(pp) == '\n') { pr->comment_length = 0; pr->comment = NULL; return 0; } dynstr comment; dynstr_init(&comment, pp); PF_FAIL_BUBBLE(pp); assert(!buffer_is_empty(pp)); int check = buffer_advance(pp, 1); // skip first whitespace if (check == E_EOF) goto label_eof; PF_FAIL_BUBBLE(pp); assert(!buffer_is_empty(pp)); // get comment while (buffer_peek(pp) != '\n') { check = dynstr_append(&comment, buffer_begin(pp), 1, pp); PF_FAIL_BUBBLE_CHECK(pp, check); check = buffer_advance(pp, 1); if (check == E_EOF) goto label_eof; PF_FAIL_BUBBLE_CHECK(pp, check); } label_eof: if (buffer_is_eof(pp)) PF_FAIL_STR(pp, "Unexpected EOF in comment on line %zu.", pp->line_number); pr->comment_length = dynstr_len(&comment); pr->comment = dynstr_move(&comment); cleanup: if (return_code) { dynstr_free(&comment); } return return_code; } int pfasta_read_sequence(struct pfasta_parser *pp, struct pfasta_record *pr) { int return_code = 0; dynstr sequence; dynstr_init(&sequence, pp); PF_FAIL_BUBBLE(pp); assert(!buffer_is_empty(pp)); assert(!buffer_is_eof(pp)); assert(buffer_peek(pp) == '\n'); int check = skip_whitespace(pp); if (check == E_EOF) PF_FAIL_STR(pp, "Empty sequence on line %zu.", pp->line_number); PF_FAIL_BUBBLE_CHECK(pp, check); // Assume a line begins only with alpha, -, *, or more spaces char c; while (c = buffer_peek(pp), LIKELY(isalpha(c) || c == '-' || c == '*')) { int check = copy_word(pp, &sequence); if (UNLIKELY(check == E_EOF)) break; PF_FAIL_BUBBLE_CHECK(pp, check); // optimize for more common case ptrdiff_t length = buffer_end(pp) - buffer_begin(pp); if (LIKELY(length >= 2 && buffer_begin(pp)[0] == '\n' && buffer_begin(pp)[1] > ' ')) { pp->read_ptr++; // nasty hack pp->line_number += 1; } else { check = skip_whitespace(pp); if (UNLIKELY(check == E_EOF)) break; PF_FAIL_BUBBLE_CHECK(pp, check); } } if (dynstr_len(&sequence) == 0) PF_FAIL_STR(pp, "Empty sequence on line %zu.", pp->line_number); pr->sequence_length = dynstr_len(&sequence); pr->sequence = dynstr_move(&sequence); pp->errstr = NULL; // reset error cleanup: if (return_code) { dynstr_free(&sequence); } return return_code; } void pfasta_record_free(struct pfasta_record *pr) { if (!pr) return; free(pr->name); free(pr->comment); free(pr->sequence); pr->name = pr->comment = pr->sequence = NULL; } void pfasta_free(struct pfasta_parser *pp) { if (!pp) return; free(pp->buffer); pp->buffer = NULL; } /** @brief Creates a new string that can grow dynamically. * * @param ds - A reference to the dynstr container. * * @returns 0 iff successful. */ static inline int dynstr_init(dynstr *ds, struct pfasta_parser *pp) { int return_code = 0; *ds = (dynstr){NULL, 0, 0}; ds->str = malloc(61); if (!ds->str) PF_FAIL_ERRNO(pp); ds->str[0] = '\0'; ds->capacity = 61; ds->count = 0; cleanup: return return_code; } /** @brief A append more than one character to a string. * * @param ds - A reference to the dynstr container. * @param str - The new characters. * @param length - number of new characters to append * * @returns 0 iff successful. */ static inline int dynstr_append(dynstr *ds, const char *str, size_t length, struct pfasta_parser *pp) { int return_code = 0; size_t required = ds->count + length; if (UNLIKELY(required >= ds->capacity)) { char *neu = pfasta_reallocarray(ds->str, required / 2, 3); if (UNLIKELY(!neu)) { dynstr_free(ds); PF_FAIL_ERRNO(pp); } ds->str = neu; ds->capacity = (required / 2) * 3; } memcpy(ds->str + ds->count, str, length); ds->count = required; cleanup: return return_code; } /** @brief Frees a dynamic string. */ static inline void dynstr_free(dynstr *ds) { if (!ds) return; free(ds->str); *ds = (dynstr){NULL, 0, 0}; } /** @brief Returns the string as a standard `char*`. The internal reference is * then deleted. Hence the name *move* as in *move semantics*. * * @param ds - The dynamic string to move from. * * @returns a `char*` to a standard null-terminated string. */ static inline char *dynstr_move(dynstr *ds) { char *out = pfasta_reallocarray(ds->str, ds->count + 1, 1); if (!out) { out = ds->str; } out[ds->count] = '\0'; *ds = (dynstr){NULL, 0, 0}; return out; } /** @brief Returns the current length of the dynamic string. */ static inline size_t dynstr_len(const dynstr *ds) { return ds->count; } __attribute__((weak)) void *reallocarray(void *ptr, size_t nmemb, size_t size); /** * @brief Unsafe fallback in case reallocarray isn't provided by the stdlib. */ void *pfasta_reallocarray(void *ptr, size_t nmemb, size_t size) { if (reallocarray == NULL) { return realloc(ptr, nmemb * size); } else { return reallocarray(ptr, nmemb, size); } } andi-0.14/libs/pfasta.h000066400000000000000000000053631415070357400147460ustar00rootroot00000000000000/* * Copyright (c) 2015-2020, Fabian Klötzl * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef PFASTA_H #define PFASTA_H #ifdef __cplusplus extern "C" { #endif #include /** * There is no magic to this structure. Its just a container of three strings. * Feel free to duplicate or move them. But don't forget to free the data after * usage! */ struct pfasta_record { char *name, *comment, *sequence; size_t name_length, comment_length, sequence_length; }; /** * This structure holds a number of members to represent the state of the FASTA * parser. Please make sure that it is properly initialized before usage. * Always free this structure when the parser is done. */ struct pfasta_parser { const char *errstr; int done; /*< private -- do not touch! >*/ int file_descriptor; char *buffer; char *read_ptr, *fill_ptr; size_t line_number; }; /** * This function initializes a `pfasta_parser` struct with a parser bound to a * specific file descriptor. Iff an error occurred `errstr` is set to contain a * suitable message. Otherwise you can read data from it as long as `done` isn't * set. The parser should be freed after usage. * * Please note that the user is responsible for opening the file descriptor as * readable and closing after usage. */ struct pfasta_parser pfasta_init(int file_descriptor); /** * Using a properly initialized parser, this function can read FASTA sequences. * These are stored in the simple structure and returned. On error, the `errstr` * property of the parser is set. */ struct pfasta_record pfasta_read(struct pfasta_parser *pp); /** * This function frees the resources held by a pfasta record. */ void pfasta_record_free(struct pfasta_record *pr); /** * This function frees the resources held by a pfasta parser. */ void pfasta_free(struct pfasta_parser *pp); /** * Get a string defining the version of the pfasta library. */ const char *pfasta_version(void); /** * Returns 0 iff pfasta is not threadsafe. */ int pfasta_threadsafe(); #ifdef __cplusplus } #endif #endif /* PFASTA_H */ andi-0.14/m4/000077500000000000000000000000001415070357400126775ustar00rootroot00000000000000andi-0.14/m4/ax_cxx_compile_stdcxx_11.m4000066400000000000000000000123351415070357400200450ustar00rootroot00000000000000# ============================================================================ # http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html # ============================================================================ # # SYNOPSIS # # AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 # standard; if necessary, add switches to CXXFLAGS to enable support. # # The first argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. # -std=c++11). If neither is specified, you get whatever works, with # preference for an extended mode. # # The second argument, if specified 'mandatory' or if left unspecified, # indicates that baseline C++11 support is required and that the macro # should error out if no mode with that support is found. If specified # 'optional', then configuration proceeds regardless, after defining # HAVE_CXX11 if and only if a supporting mode is found. # # LICENSE # # Copyright (c) 2008 Benjamin Kosnik # Copyright (c) 2012 Zack Weinberg # Copyright (c) 2013 Roy Stogner # Copyright (c) 2014 Alexey Sokolov # Copyright (c) 2014, 2015 Google Inc. # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 7 m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; struct Base { virtual void f() {} }; struct Child : public Base { virtual void f() override {} }; typedef check> right_angle_brackets; int a; decltype(a) b; typedef check check_type; check_type c; check_type&& cr = static_cast(c); auto d = a; auto l = [](){}; // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test() { func(0); } } ]]) AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl m4_if([$1], [], [], [$1], [ext], [], [$1], [noext], [], [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], [$2], [optional], [ax_cxx_compile_cxx11_required=false], [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) AC_LANG_PUSH([C++])dnl ac_success=no AC_CACHE_CHECK(whether $CXX supports C++11 features by default, ax_cv_cxx_compile_cxx11, [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [ax_cv_cxx_compile_cxx11=yes], [ax_cv_cxx_compile_cxx11=no])]) if test x$ax_cv_cxx_compile_cxx11 = xyes; then ac_success=yes fi m4_if([$1], [noext], [], [dnl if test x$ac_success = xno; then for switch in -std=gnu++11 -std=gnu++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) m4_if([$1], [ext], [], [dnl if test x$ac_success = xno; then for switch in -std=c++11 -std=c++0x; do cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, $cachevar, [ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $switch" AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], [eval $cachevar=yes], [eval $cachevar=no]) CXXFLAGS="$ac_save_CXXFLAGS"]) if eval test x\$$cachevar = xyes; then CXXFLAGS="$CXXFLAGS $switch" ac_success=yes break fi done fi]) AC_LANG_POP([C++]) if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) fi else if test x$ac_success = xno; then HAVE_CXX11=0 AC_MSG_NOTICE([No compiler with C++11 support was found]) else HAVE_CXX11=1 AC_DEFINE(HAVE_CXX11,1, [define if the compiler supports basic C++11 syntax]) fi AC_SUBST(HAVE_CXX11) fi ]) andi-0.14/opt/000077500000000000000000000000001415070357400131615ustar00rootroot00000000000000andi-0.14/opt/Makefile.am000066400000000000000000000003211415070357400152110ustar00rootroot00000000000000noinst_LIBRARIES= libcompat.a libcompat_a_SOURCES= compat-string.h compat-stdlib.h if !HAVE_STRCHRNUL libcompat_a_SOURCES+= strchrnul.c endif if !HAVE_REALLOCARRAY libcompat_a_SOURCES+= reallocarray.c endif andi-0.14/opt/compat-stdlib.h000066400000000000000000000001201415070357400160650ustar00rootroot00000000000000#include void *reallocarray(void *optr, size_t nmemb, size_t size); andi-0.14/opt/compat-string.h000066400000000000000000000001051415070357400161150ustar00rootroot00000000000000#ifndef HAVE_STRCHRNUL char *strchrnul(const char *s, int c); #endif andi-0.14/opt/reallocarray.c000066400000000000000000000023721415070357400160110ustar00rootroot00000000000000#include #include #include "compat-stdlib.h" /* * Copyright (c) 2008 Otto Moerbeek * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW */ #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) void *reallocarray(void *optr, size_t nmemb, size_t size) { if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) { errno = ENOMEM; return NULL; } return realloc(optr, size * nmemb); } andi-0.14/opt/strchrnul.c000066400000000000000000000004031415070357400153460ustar00rootroot00000000000000/* @brief Here follows a simple implementation of the GNU function `strchrnul`. * Please check the gnulib manual for details. */ #include char *strchrnul(const char *s, int c){ char *p = strchr(s,c); return p != NULL ? p : strchr(s, '\0'); } andi-0.14/scripts/000077500000000000000000000000001415070357400140465ustar00rootroot00000000000000andi-0.14/scripts/_andi000077500000000000000000000036141415070357400150520ustar00rootroot00000000000000#compdef andi # This file allows zsh to complete arguments for andi. As the syntax is # totally non-obvious, I'll explain the basics here. For details see # http://zsh.sourceforge.net/Doc/Release/Completion-System.html # Each line consists of three parts: (A){B}[C] # The B part performs brace expansion as on the commandline. Thus each # line with braces gets translated into multiple arguments! Also the # B part lists the relevant argument for which we are trying to set # the completion rules. The A part simply states that B shall not be # completed if A is already present. i.e. Most flags only make sense once, # with the exception of -v. The string C is simply the message that is # displayed to the user. local info="-h --help --version" local ret=1 local -a args args+=( "($info -b --bootstrap)"{-b+,--bootstrap=}'[Print additional bootstrap matrices]:int:' "($info)*--file-of-filenames=[Read additional filenames from file; one per line]:file:_files" "($info -j --join)"{-j,--join}'[Treat all sequences from one file as a single genome]' "($info -l --low-memory)"{-l,--low-memory}'[Use less memory at the cost of speed]' "($info -m --model)"{-m+,--model=}'[Pick an evolutionary model]:model:(( Raw\:Uncorrected\ distances JC\:Jukes\-Cantor\ corrected Kimura\:Kimura\-two\-parameter LogDet\:Logarithmic\ determinant ))' "($info)-p+[Significance of an anchor; default\: 0.025]:float:" "($info)--progress=[Show progress bar]:when:(always auto never)" "($info -t --threads)"{-t+,--threads=}'[The number of threads to be used; by default, all available processors are used]:num_threads:' "($info)--truncate-names[Print only the first ten characters of each name]" "($info)*"{-v,--verbose}'[Prints additional information]' '(- *)'{-h,--help}'[Display help and exit]' '(- *)--version[Output version information and acknowledgments]' '*:file:_files' ) _arguments -w -s -S $args[@] && ret=0 return ret andi-0.14/scripts/failed.zsh000077500000000000000000000012641415070357400160260ustar00rootroot00000000000000#!/usr/bin/zsh # Compute the number of failing comparisons for different distances. DISTS=(0.1 0.2 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7) LENGTH=100000 for dist in $DISTS; do echo "" > est_$dist.dist for (( i = 0; i < 1000; i++ )); do ../test/test_fasta -l $LENGTH -d $dist > temp.fa ../src/andi ./temp.fa > est.dist 2> /dev/null tail -n 1 est.dist >> est_$dist.dist done avg=$(cat est_$dist.dist | awk '"nan" !~ $2 {sum+=$2;c++}END{print sum/c}') sd=$(grep -v 'nan' est_$dist.dist | awk '{a[c++]=$2;aa+=$2}END{aa/=NR;for(c=0;c file.maf > file.phy"; exit(-1); } numName = 0; test = "mult=" n; }{ if(/^a/){ if($0 ~ test) open = 1; else open = 0; } if(open && /^s/){ if(!s[$2]) names[numNames++] = $2; s[$2] = s[$2] $7; } }END{ # check equal length of sequences len = -1; for(i=0;i 0){ if(length(s[name]) != len){ print "sequence length should be " len " but is in fact " length(s[name]); exit(-1); } }else len = length(s[name]); } print numNames, len; start = 1; l = 60; for(i=0;i /dev/null # In theory we have to calculate the anchors distance here using the previously # computed matches. But since vmatch is already significantly slower than andi, # we skip this step. done andi-0.14/src/000077500000000000000000000000001415070357400131465ustar00rootroot00000000000000andi-0.14/src/Makefile.am000066400000000000000000000007171415070357400152070ustar00rootroot00000000000000bin_PROGRAMS = andi andi_SOURCES = andi.c esa.c process.c sequence.c io.c global.h esa.h process.h sequence.h io.h dist_hack.h \ model.h model.c andi_CPPFLAGS = $(OPENMP_CFLAGS) -I$(top_srcdir)/libs -I$(top_srcdir)/opt -std=gnu99 andi_CFLAGS = $(OPENMP_CFLAGS) -Wall -Wextra -Wno-missing-field-initializers andi_LDADD = $(top_builddir)/libs/libpfasta.a $(top_builddir)/opt/libcompat.a .PHONY: perf perf: CFLAGS+= -g -O3 -ggdb -fno-omit-frame-pointer perf: andi andi-0.14/src/andi.c000066400000000000000000000254621415070357400142360ustar00rootroot00000000000000/** * @file * * This is the main file. It contains functions to parse the commandline * arguments, read files etc. * * @brief The main file * @author Fabian Klötzl * * @section License * * 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 at * http://www.gnu.org/copyleft/gpl.html * */ #include "global.h" #include "io.h" #include "process.h" #include "sequence.h" #include #include #include #include #include #include #include #include #include #include #ifdef _OPENMP #include #endif /* Global variables */ int FLAGS = 0; int THREADS = 1; long unsigned int BOOTSTRAP = 0; double ANCHOR_P_VALUE = 0.025; gsl_rng *RNG = NULL; int MODEL = M_JC; void usage(int); void version(void); /** * @brief The main function. * * The main function reads and parses the commandline arguments. Depending on * the set flags it reads the input files and forwards the contained sequences * to processing. Also it verifies the input for correctness and issues warnings * and errors. */ int main(int argc, char *argv[]) { struct option long_options[] = { {"version", no_argument, NULL, 0}, {"truncate-names", no_argument, NULL, 0}, {"file-of-filenames", required_argument, NULL, 0}, {"progress", optional_argument, NULL, 0}, {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {"join", no_argument, NULL, 'j'}, {"low-memory", no_argument, NULL, 'l'}, {"threads", required_argument, NULL, 't'}, {"bootstrap", required_argument, NULL, 'b'}, {"model", required_argument, NULL, 'm'}, {0, 0, 0, 0}}; #ifdef _OPENMP // Use all available processors by default. THREADS = omp_get_num_procs(); #endif enum { P_AUTO, P_NEVER, P_ALWAYS } progress = P_AUTO; struct string_vector file_names; string_vector_init(&file_names); // parse arguments while (1) { int option_index = 0; int c = getopt_long(argc, argv, "jvht:p:m:b:l", long_options, &option_index); if (c == -1) { break; } switch (c) { case 0: { const char *option_str = long_options[option_index].name; if (strcasecmp(option_str, "version") == 0) { version(); } if (strcasecmp(option_str, "truncate-names") == 0) { FLAGS |= F_TRUNCATE_NAMES; } if (strcasecmp(option_str, "file-of-filenames") == 0) { read_into_string_vector(optarg, &file_names); } if (strcasecmp(option_str, "progress") == 0) { if (!optarg || strcasecmp(optarg, "always") == 0) { progress = P_ALWAYS; } else if (strcasecmp(optarg, "auto") == 0) { progress = P_AUTO; } else if (strcasecmp(optarg, "never") == 0) { progress = P_NEVER; } else { warnx("invalid argument to --progress '%s'. Expected " "one of 'auto', 'always', or 'never'.", optarg); } } break; } case 'h': usage(EXIT_SUCCESS); break; case 'v': FLAGS |= FLAGS & F_VERBOSE ? F_EXTRA_VERBOSE : F_VERBOSE; break; case 'p': { errno = 0; char *end; double prop = strtod(optarg, &end); if (errno || end == optarg || *end != '\0') { soft_errx( "Expected a floating point number for -p argument, but " "'%s' was given. Skipping argument.", optarg); break; } if (prop <= 0.0 || prop >= 1.0) { soft_errx("A probability should be a value between 0 and " "1, exclusive; Ignoring -p %f argument.", prop); break; } ANCHOR_P_VALUE = prop; break; } case 'l': FLAGS |= F_LOW_MEMORY; break; case 'j': FLAGS |= F_JOIN; break; case 't': { #ifdef _OPENMP errno = 0; char *end; long unsigned int threads = strtoul(optarg, &end, 10); if (errno || end == optarg || *end != '\0') { warnx("Expected a number for -t argument, but '%s' was " "given. Ignoring -t argument.", optarg); break; } if (threads > (long unsigned int)omp_get_num_procs()) { warnx( "The number of threads to be used, is greater than the " "number of available processors; Ignoring -t %lu " "argument.", threads); break; } THREADS = threads; #else warnx( "This version of andi was built without OpenMP and thus " "does not support multi threading. Ignoring -t argument."); #endif break; } case 'b': { errno = 0; char *end; long unsigned int bootstrap = strtoul(optarg, &end, 10); if (errno || end == optarg || *end != '\0' || bootstrap == 0) { soft_errx( "Expected a positive number for -b argument, but '%s' " "was given. Ignoring -b argument.", optarg); break; } BOOTSTRAP = bootstrap - 1; break; } case 'm': { if (strcasecmp(optarg, "RAW") == 0) { MODEL = M_RAW; } else if (strcasecmp(optarg, "JC") == 0) { MODEL = M_JC; } else if (strcasecmp(optarg, "KIMURA") == 0) { MODEL = M_KIMURA; } else if (strcasecmp(optarg, "LOGDET") == 0) { MODEL = M_LOGDET; } else { soft_errx("Ignoring argument for --model. Expected Raw, " "JC, Kimura or LogDet"); } break; } case '?': /* intentional fall-through */ default: usage(EXIT_FAILURE); break; } } argc -= optind; argv += optind; // copy command line arguments into vector // std::copy, anyone? for (size_t i = 0; i < (unsigned int)argc; i++) { string_vector_push_back(&file_names, argv[i]); } // at least one file name must be given if (FLAGS & F_JOIN && string_vector_size(&file_names) == 0) { errx(1, "In join mode at least one filename needs to be supplied."); } size_t minfiles = FLAGS & F_JOIN ? 2 : 1; if (string_vector_size(&file_names) < minfiles) { // not enough files passed via arguments if (!isatty(STDIN_FILENO)) { // read from stdin in pipe string_vector_push_back(&file_names, "-"); } else { // print a helpful message on './andi' without args usage(EXIT_FAILURE); } } // parse fasta files dsa_t dsa; dsa_init(&dsa); for (size_t i = 0; i < string_vector_size(&file_names); i++) { char *file_name = string_vector_at(&file_names, i); if (FLAGS & F_JOIN) { read_fasta_join(file_name, &dsa); } else { read_fasta(file_name, &dsa); } } string_vector_free(&file_names); size_t n = dsa_size(&dsa); if (n < 2) { errx(1, "I am truly sorry, but with less than two sequences (%zu given) " "there is nothing to compare.", n); } RNG = gsl_rng_alloc(gsl_rng_default); if (!RNG) { err(1, "RNG allocation failed."); } // seed the random number generator with the current time // TODO: enable seeding for reproducibility gsl_rng_set(RNG, time(NULL)); // Warn about non ACGT residues. if (FLAGS & F_NON_ACGT) { warnx("The input sequences contained characters other than acgtACGT. " "These were automatically stripped to ensure correct results."); } // validate sequence correctness const seq_t *seq = dsa_data(&dsa); for (size_t i = 0; i < n; ++i, seq++) { if ((FLAGS & F_TRUNCATE_NAMES) && strlen(seq->name) > 10) { warnx("The sequence name '%s' is longer than ten characters. It " "will be truncated in the output to '%.10s'.", seq->name, seq->name); } const size_t LENGTH_LIMIT = (INT_MAX - 1) / 2; if (seq->len > LENGTH_LIMIT) { errx(1, "The sequence %s is too long. The technical limit is %zu.", seq->name, LENGTH_LIMIT); } if (seq->len == 0) { errx(1, "The sequence %s is empty.", seq->name); } if (seq->len < 1000) { FLAGS |= F_SHORT; } } if (FLAGS & F_SHORT) { soft_errx( "One of the given input sequences is shorter than a thousand " "nucleotides. This may result in inaccurate distances. Try an " "alignment instead."); } // determine whether to print a progress bar if (progress == P_AUTO) { progress = isatty(STDERR_FILENO) ? P_ALWAYS : P_NEVER; } if (progress == P_ALWAYS) { FLAGS |= F_PRINT_PROGRESS; } // compute distance matrix calculate_distances(dsa_data(&dsa), n); dsa_free(&dsa); gsl_rng_free(RNG); return FLAGS & F_SOFT_ERROR ? EXIT_FAILURE : EXIT_SUCCESS; } /** * @brief Prints the usage and then exits. */ void usage(int status) { const char str[] = { "Usage: andi [OPTIONS...] FILES...\n" "\tFILES... can be any sequence of FASTA files.\n" "\tUse '-' as file name to read from stdin.\n" "Options:\n" " -b, --bootstrap=INT Print additional bootstrap matrices\n" " --file-of-filenames=FILE Read additional filenames from FILE; " "one per line\n" " -j, --join Treat all sequences from one file as a single " "genome\n" " -l, --low-memory Use less memory at the cost of speed\n" " -m, --model=MODEL Pick an evolutionary model of 'Raw', 'JC', " "'Kimura', 'LogDet'; default: JC\n" " -p FLOAT Significance of an anchor; default: 0.025\n" " --progress=WHEN Print a progress bar 'always', 'never', or " "'auto'; default: auto\n" #ifdef _OPENMP " -t, --threads=INT Set the number of threads; by default, all " "processors are used\n" #endif " --truncate-names Truncate names to ten characters\n" " -v, --verbose Prints additional information\n" " -h, --help Display this help and exit\n" " --version Output version information and " "acknowledgments\n"}; fprintf(status == EXIT_SUCCESS ? stdout : stderr, "%s", str); exit(status); } /** * @brief This function just prints the version string and then aborts * the program. It conforms to the [GNU Coding * Standard](http://www.gnu.org/prep/standards/html_node/_002d_002dversion.html#g_t_002d_002dversion). */ void version(void) { const char str[] = { "andi " VERSION "\n" "Copyright (C) 2014 - 2020 Fabian Klötzl\n" "License GPLv3+: GNU GPL version 3 or later " "\n" "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n\n" "Acknowledgments:\n" "1) Andi: Haubold, B. Klötzl, F. and Pfaffelhuber, P. (2015). " "Fast and accurate estimation of evolutionary distances between " "closely related genomes, Bioinformatics.\n" "2) Algorithms: Ohlebusch, E. (2013). Bioinformatics Algorithms. " "Sequence Analysis, Genome Rearrangements, and Phylogenetic " "Reconstruction. pp 118f.\n" "3) SA construction: Mori, Y. (2005). libdivsufsort, unpublished.\n" "4) Bootstrapping: Klötzl, F. and Haubold, B. (2016). Support Values " "for Genome Phylogenies, Life 6.1.\n"}; printf("%s", str); exit(EXIT_SUCCESS); } andi-0.14/src/dist_hack.h000066400000000000000000000051061415070357400152520ustar00rootroot00000000000000/** @file * @brief This file is a preprocessor hack for the two functions `distMatrix` * and `distMatrixLM`. */ // clang-format off #ifdef FAST #define NAME distMatrix #define P_OUTER _Pragma("omp parallel for num_threads( THREADS) default(none) shared(progress_counter) firstprivate( stderr, M, sequences, n, print_progress)") #define P_INNER #else #undef NAME #undef P_OUTER #undef P_INNER #define NAME distMatrixLM #define P_OUTER #define P_INNER _Pragma("omp parallel for num_threads( THREADS) default(none) shared(progress_counter) firstprivate( stderr, M, sequences, n, print_progress, i, E, subject)") #endif // clang-format on /** @brief This function calls dist_andi for pairs of subjects and queries, and * thereby fills the distance matrix. * * This function is actually two functions. It is one template that gets * compiled into two functions via preprocessor hacks. The reason is DRY (Do not * Repeat Yourselves). * The two functions only differ by their name and pragmas; i.e. They run in * different parallel modes. * `distMatrix` is faster than `distMatrixLM` but needs more memory. * * @param sequences - The sequences to compare * @param n - The number of sequences * @param M - A matrix for additional output data */ void NAME(struct model *M, const seq_t *sequences, size_t n) { size_t i; size_t progress_counter = 0; int print_progress = FLAGS & F_PRINT_PROGRESS; if (print_progress) { fprintf(stderr, "Comparing %zu sequences: %5.1f%% (%zu/%zu)", n, 0.0, (size_t)0, n * n - n); } //#pragma P_OUTER for (i = 0; i < n; i++) { seq_subject subject; esa_s E; if (seq_subject_init(&subject, &sequences[i]) || esa_init(&E, &subject)) { errx(1, "Failed to create index for %s.", sequences[i].name); } // now compare every other sequence to i size_t j; P_INNER for (j = 0; j < n; j++) { if (j == i) { M(i, j) = (struct model){.seq_len = 9, .counts = {9}}; continue; } size_t ql = sequences[j].len; M(i, j) = dist_anchor(&E, sequences[j].S, ql, subject.threshold); #pragma omp atomic update progress_counter++; } if (print_progress) { size_t local_progress_counter; size_t num_comparisons = n * n - n; #pragma omp atomic read local_progress_counter = progress_counter; double progress = 100.0 * (double)local_progress_counter / num_comparisons; #pragma omp critical fprintf(stderr, "\rComparing %zu sequences: %5.1f%% (%zu/%zu)", n, progress, local_progress_counter, num_comparisons); } esa_free(&E); seq_subject_free(&subject); } if (print_progress) { fprintf(stderr, ", done.\n"); } } andi-0.14/src/esa.c000066400000000000000000000376451415070357400141010ustar00rootroot00000000000000/** * @file * @brief ESA functions * * This file contains various functions that operate on an enhanced suffix * array. The basic algorithms originate from the book of Ohlebusch * "Bioinformatics Algorithms" (2013). Most of these were heavily modified * for improved performance. One example is the lcp-cache. * * The ESA structure defined in esa.h contains a `cache` field. This cache is * used to quickly look up lcp-intervals. Consider the queries "AAGT" and * "AACG". In both cases the interval for "AA" has to be looked up in the * ESA. If we simply store the interval for "AA" in the cache, once and use it * for each query we are significantly faster (up to 7 times). */ #include "esa.h" #include "global.h" #include #include #include static void esa_init_cache_dfs(esa_s *, char *str, size_t pos, lcp_inter_t in); static void esa_init_cache_fill(esa_s *, char *str, size_t pos, lcp_inter_t in); static lcp_inter_t get_interval(const esa_s *, lcp_inter_t ij, char a); lcp_inter_t get_match(const esa_s *, const char *query, size_t qlen); static lcp_inter_t get_match_from(const esa_s *, const char *query, size_t qlen, saidx_t k, lcp_inter_t ij); static int esa_init_SA(esa_s *); static int esa_init_LCP(esa_s *); static int esa_init_CLD(esa_s *); /** @brief The prefix length up to which LCP-intervals are cached. */ const size_t CACHE_LENGTH = 10; /** @brief Map a code to the character. */ char code2char(ssize_t code) { switch (code & 0x3) { case 0: return 'A'; case 1: return 'C'; case 2: return 'G'; case 3: return 'T'; } return '\0'; } /** @brief Map a character to a two bit code. */ ssize_t char2code(const char c) { ssize_t result = -1; switch (c) { case 'A': result = 0; break; case 'C': result = 1; break; case 'G': result = 2; break; case 'T': result = 3; break; } return result; } #define R(CLD, i) ((CLD)[(i)]) #define L(CLD, i) ((CLD)[(i)-1]) /** @brief Fills the LCP-Interval cache. * * Traversing the virtual suffix tree, created by SA, LCP and CLD is rather * slow. Hence we create a cache, holding the LCP-interval for a prefix of a * certain length ::CACHE_LENGTH. This function it the entry point for the * cache filling routine. * * @param self - The ESA. * @returns 0 iff successful */ int esa_init_cache(esa_s *self) { lcp_inter_t *cache = malloc((1 << (2 * CACHE_LENGTH)) * sizeof(*cache)); CHECK_MALLOC(cache); self->cache = cache; char str[CACHE_LENGTH + 1]; str[CACHE_LENGTH] = '\0'; saidx_t m = L(self->CLD, self->len); lcp_inter_t ij = {.i = 0, .j = self->len - 1, .m = m, .l = self->LCP[m]}; esa_init_cache_dfs(self, str, 0, ij); return 0; } /** @brief Fills the cache — one char at a time. * * This function is a depth first search on the virtual suffix tree and fills * the cache. Or rather it calls it self until some value to cache is * calculated. This function is a recursive version of get_interval but with * more edge cases. * * @param C - The ESA. * @param str - The current prefix. * @param pos - The length of the prefix. * @param in - The LCP-interval of prefix[0..pos-1]. */ void esa_init_cache_dfs(esa_s *C, char *str, size_t pos, const lcp_inter_t in) { // we are not yet done, but the current strings do not exist in the subject. if (pos < CACHE_LENGTH && in.i == -1 && in.j == -1) { esa_init_cache_fill(C, str, pos, in); return; } // we are past the caching length if (pos >= CACHE_LENGTH) { esa_init_cache_fill(C, str, pos, in); return; } lcp_inter_t ij; // iterate over all nucleotides for (int code = 0; code < 4; ++code) { str[pos] = code2char(code); ij = get_interval(C, in, str[pos]); // fail early if (ij.i == -1 && ij.j == -1) { // if the current extension cannot be found, will with previous one esa_init_cache_fill(C, str, pos + 1, in); continue; } // singleton if (ij.i == ij.j) { // fix length ij.l = pos + 1; esa_init_cache_fill(C, str, pos + 1, ij); continue; } if (ij.l <= (ssize_t)(pos + 1)) { // Continue one level deeper // This is the usual case esa_init_cache_dfs(C, str, pos + 1, ij); continue; } // The LCP-interval is deeper than expected // Check if it still fits into the cache if ((size_t)ij.l >= CACHE_LENGTH) { // If the lcp-interval exceeds the cache depth, stop here and fill esa_init_cache_fill(C, str, pos + 1, in); continue; } /* At this point the prefix `str` of length `pos` has been found. * However, the call to `getInterval` above found an interval with * an LCP value bigger than `pos`. This means that not all elongations * (more precise: just one) of `str` appear in the subject. Thus fill * all values with the matched result to far and continue only with * the one special substring. */ esa_init_cache_fill(C, str, pos + 1, in); char non_acgt = 0; // fast forward size_t k = pos + 1; for (; k < (size_t)ij.l; k++) { // In some very edgy edge cases the lcp-interval `ij` // contains a `;` or another non-acgt character. Since we // cannot cache those, break. char c = C->S[C->SA[ij.i] + k]; if (char2code(c) < 0) { non_acgt = 1; break; } str[k] = c; } // We are skipping intervals here. Maybe for each of them we should also // fill the cache. However, I haven't yet figured out how to do that // properly and whether it is worth it. if (non_acgt) { esa_init_cache_fill(C, str, k, ij); } else { esa_init_cache_dfs(C, str, k, ij); } } } /** @brief Fills the cache with a given value. * * Given a prefix and a value this function fills the cache beyond this point * the value. * * @param C - The ESA. * @param str - The current prefix. * @param pos - The length of the prefix. * @param in - The LCP-interval of prefix[0..pos-1]. */ void esa_init_cache_fill(esa_s *C, char *str, size_t pos, lcp_inter_t in) { if (pos < CACHE_LENGTH) { for (int code = 0; code < 4; ++code) { str[pos] = code2char(code); esa_init_cache_fill(C, str, pos + 1, in); } } else { ssize_t code = 0; for (size_t i = 0; i < CACHE_LENGTH; ++i) { code <<= 2; code |= char2code(str[i]); } C->cache[code] = in; } } /** * @brief Initializes the FVC (first variant character) array. * * The FVC is of my own invention and simply defined as * `FVC[i] = S[SA[i]+LCP[i]]`. This expression is constantly used in * get_interval. By precomputing the result, we have less memory * accesses, less cache misses, and thus improved runtimes of up to 15% * faster matching. This comes at a negligible cost of increased memory. * * @param self - The ESA * @returns 0 iff successful */ int esa_init_FVC(esa_s *self) { size_t len = self->len; char *FVC = self->FVC = malloc(len); CHECK_MALLOC(FVC); const char *S = self->S; const int *SA = self->SA; const int *LCP = self->LCP; FVC[0] = '\0'; for (size_t i = len; i; i--, FVC++, SA++, LCP++) { *FVC = S[*SA + *LCP]; } return 0; } /** @brief Initializes an ESA. * * This function initializes an ESA with respect to the provided sequence. * @param C - The ESA to initialize. * @param S - The sequence * @returns 0 iff successful */ int esa_init(esa_s *C, const seq_subject *S) { if (!C || !S || !S->RS) return 1; *C = (esa_s){.S = S->RS, .len = S->RSlen}; int result; result = esa_init_SA(C); if (result) return result; result = esa_init_LCP(C); if (result) return result; result = esa_init_CLD(C); if (result) return result; result = esa_init_FVC(C); if (result) return result; result = esa_init_cache(C); if (result) return result; return 0; } /** @brief Free the private data of an ESA. */ void esa_free(esa_s *self) { free(self->SA); free(self->LCP); free(self->CLD); free(self->cache); free(self->FVC); *self = (esa_s){}; } /** * Computes the SA given a string S. To do so it uses libdivsufsort. * @param C The enhanced suffix array to use. Reads C->S, fills C->SA. * @returns 0 iff successful */ int esa_init_SA(esa_s *C) { // assert c.S if (!C || !C->S) { return 1; } C->SA = malloc(C->len * sizeof(*C->SA)); CHECK_MALLOC(C->SA); return divsufsort((const unsigned char *)C->S, C->SA, C->len); } /** @brief Initializes the CLD (child) array. * * See Ohlebusch. * * @param C - The ESA */ int esa_init_CLD(esa_s *C) { if (!C || !C->LCP) { return 1; } saidx_t *CLD = C->CLD = malloc((C->len + 1) * sizeof(*CLD)); CHECK_MALLOC(CLD); const saidx_t *LCP = C->LCP; typedef struct pair_s { saidx_t idx, lcp; } pair_t; pair_t *stack = malloc((C->len + 1) * sizeof(*stack)); CHECK_MALLOC(stack); pair_t *top = stack; // points at the topmost filled element pair_t last; R(CLD, 0) = C->len; top->idx = 0; top->lcp = -1; // iterate over all elements for (size_t k = 1; k < (size_t)(C->len + 1); k++) { while (LCP[k] < top->lcp) { // top->lcp is a leaf last = *top--; // link all elements of same lcp value in a chain while (top->lcp == last.lcp) { R(CLD, top->idx) = last.idx; last = *top--; } // store the l-index of last if (LCP[k] < top->lcp) { R(CLD, top->idx) = last.idx; } else { L(CLD, k) = last.idx; } } // continue one level deeper top++; top->idx = k; top->lcp = LCP[k]; } free(stack); return 0; } /** * This function computed the LCP array, given the suffix array. Thereto it uses * a special `phi` array, which makes it slightly faster than the original * linear-time algorithm by Kasai et al. * * @param C The enhanced suffix array to compute the LCP from. * @returns 0 iff successful */ int esa_init_LCP(esa_s *C) { const char *S = C->S; const saidx_t *SA = C->SA; saidx_t len = C->len; // Trivial safety checks if (!C || !S || !SA || len == 0) { return 1; } // Allocate new memory // The LCP array is one element longer than S. saidx_t *LCP = C->LCP = malloc((len + 1) * sizeof(*LCP)); CHECK_MALLOC(LCP); LCP[0] = -1; LCP[len] = -1; // Allocate temporary arrays saidx_t *PHI = malloc(len * sizeof(*PHI)); saidx_t *PLCP = PHI; CHECK_MALLOC(PHI); PHI[SA[0]] = -1; saidx_t k; ssize_t i; for (i = 1; i < len; i++) { PHI[SA[i]] = SA[i - 1]; } ssize_t l = 0; for (i = 0; i < len; i++) { k = PHI[i]; if (k != -1) { while (S[k + l] == S[i + l]) { l++; } PLCP[i] = l; l--; if (l < 0) l = 0; } else { PLCP[i] = -1; } } // unpermutate the LCP array for (i = 1; i < len; i++) { LCP[i] = PLCP[SA[i]]; } free(PHI); return 0; } /** @brief For the lcp-interval of string `w` compute the interval for `wa` * * Say, we already know the LCP-interval ij for a string `w`. Now we want to * check if `wa` may also be found in the ESA and thus in the subject. So we * look for the sub interval of `ij` in which all strings feature an `a` as * the next character. If such a sub interval is found, its boundaries are * returned. * * @param self - The ESA. * @param ij - The lcp-interval for `w`. * @param a - The next character. * @returns The lcp-interval one level deeper. */ static lcp_inter_t get_interval(const esa_s *self, lcp_inter_t ij, char a) { saidx_t i = ij.i; saidx_t j = ij.j; const saidx_t *SA = self->SA; const saidx_t *LCP = self->LCP; const char *S = self->S; const saidx_t *CLD = self->CLD; const char *FVC = self->FVC; // check for singleton or empty interval if (i == j) { if (S[SA[i] + ij.l] != a) { ij.i = ij.j = -1; } return ij; } int m = ij.m; int l = ij.l; char c = S[SA[i] + l]; goto SoSueMe; do { c = FVC[i]; SoSueMe: if (c == a) { /* found ! */ if (i != m - 1) { // found interval contains >1 element saidx_t n = L(CLD, m); ij = (lcp_inter_t){.i = i, .j = m - 1, .m = n, .l = LCP[n]}; } else { // empty or singleton // doing L(CLD, m) is not valid in this case! ij = (lcp_inter_t){.i = i, .j = i, .m = -1, .l = LCP[i]}; } return ij; } if (c > a) { break; } i = m; if (i == j) { break; // singleton interval, or `a` not found } m = R(CLD, m); } while (/*m != "bottom" && */ LCP[m] == l); // final sanity check if (i != ij.i ? FVC[i] == a : S[SA[i] + l] == a) { ij.i = i; ij.j = j; /* Also return the length of the LCP interval including `a` and * possibly even more characters. Note: l + 1 <= LCP[m] */ ij.l = LCP[m]; ij.m = m; } else { ij.i = ij.j = -1; } return ij; } /** @brief Compute the longest match of a query with the subject. * * The *longest match* is the core concept of `andi`. Its simply defined as the * longest prefix of a query Q appearing anywhere in the subject S. Talking * about genetic sequences, a match is a homologous region, likely followed by a * SNP. * * This function returns the interval for where the longest match of the query * can be found in the ESA. Thereto it expects a starting interval for the * search. * * @param C - The enhanced suffix array for the subject. * @param query - The query sequence. * @param qlen - The length of the query. Should correspond to `strlen(query)`. * @param k - The starting index into the query. * @param ij - The LCP interval for the string `query[0..k]`. * @returns The LCP interval for the longest prefix. */ lcp_inter_t get_match_from(const esa_s *C, const char *query, size_t qlen, saidx_t k, lcp_inter_t ij) { if (ij.i == -1 && ij.j == -1) { return ij; } // fail early on singleton intervals. if (ij.i == ij.j) { // try to extend the match. See line 513 below. saidx_t p = C->SA[ij.i]; size_t k = ij.l; const char *S = (const char *)C->S; for (; k < qlen && S[p + k]; k++) { if (S[p + k] != query[k]) { ij.l = k; return ij; } } ij.l = k; return ij; } saidx_t l, i, j; lcp_inter_t res = ij; const saidx_t *SA = C->SA; const char *S = C->S; // Loop over the query until a mismatch is found do { // Get the subinterval for the next character. ij = get_interval(C, ij, query[k]); i = ij.i; j = ij.j; // If our match cannot be extended further, return. if (i == -1 && j == -1) { res.l = k; return res; } res.i = ij.i; res.j = ij.j; l = qlen; if (i < j && ij.l < l) { /* Instead of making another look up we can use the LCP interval * calculated in get_interval */ l = ij.l; } // By definition, the kth letter of the query was matched. k++; // Extend the match for (int p = SA[i]; k < l; k++) { if (S[p + k] != query[k]) { res.l = k; return res; } } } while (k < (ssize_t)qlen); res.l = qlen; return res; } /** @brief Get a match. * * Given an ESA and a string Q find the longest prefix of Q that matches * somewhere in C. This search is done entirely via jumping around in the ESA, * and thus is slow. * * @param C - The ESA. * @param query - The query string — duh. * @param qlen - The length of the query. * @returns the lcp interval of the match. */ lcp_inter_t get_match(const esa_s *C, const char *query, size_t qlen) { // sanity checks if (!C || !query || !C->len || !C->SA || !C->LCP || !C->S || !C->CLD) { return (lcp_inter_t){-1, -1, -1, -1}; } saidx_t m = L(C->CLD, C->len); lcp_inter_t ij = {.i = 0, .j = C->len - 1, .m = m, .l = C->LCP[m]}; return get_match_from(C, query, qlen, 0, ij); } /** @brief Compute the LCP interval of a query. For a certain prefix length of * the query its LCP interval is retrieved from a cache. Hence this is faster * than the naive `get_match`. If the cache fails to provide a proper value, we * fall back to the standard search. * * @param C - The enhanced suffix array for the subject. * @param query - The query sequence. * @param qlen - The length of the query. Should correspond to `strlen(query)`. * @returns The LCP interval for the longest prefix. */ lcp_inter_t get_match_cached(const esa_s *C, const char *query, size_t qlen) { if (qlen <= CACHE_LENGTH) return get_match(C, query, qlen); ssize_t offset = 0; for (size_t i = 0; i < CACHE_LENGTH && offset >= 0; i++) { offset <<= 2; offset |= char2code(query[i]); } if (offset < 0) { return get_match(C, query, qlen); } lcp_inter_t ij = C->cache[offset]; if (ij.i == -1 && ij.j == -1) { return get_match(C, query, qlen); } return get_match_from(C, query, qlen, ij.l, ij); } andi-0.14/src/esa.h000066400000000000000000000036701415070357400140750ustar00rootroot00000000000000/** * @file * @brief This header contains the declarations for functions in esa.c. * */ #ifndef _ESA_H_ #define _ESA_H_ #include "config.h" #include "sequence.h" #include #include /** * @brief Represents LCP-Intervals. * * This struct is used to represent LCP-intervals. The member `i` should * coincide with the lower bound whereas `j` is the upper bound. Both bounds * are inclusive. So if `i == j` the interval contains exactly one element, * namely `i`. To represent an empty interval please use `i == j == -1`. * Other variants, such as `i == j == -2` can be used to indicate an error. * The common prefix length is denoted by l and should always be non-negative. * Variables of this type are often called `ij`. */ typedef struct { /** @brief The common prefix length */ saidx_t l; /** @brief lower bound */ saidx_t i; /** @brief upper bound */ saidx_t j; /** The new middle. */ saidx_t m; } lcp_inter_t; /** * @brief The ESA type. * * This structure holds arrays and objects associated with an enhanced * suffix array (ESA). */ typedef struct esa_s { /** The base string from which the ESA was generated. */ const char *S; /** The actual suffix array with indexes into S. */ saidx_t *SA; /** The LCP holds the number of letters up to which a suffix `S[SA[i]]` equals `S[SA[i-1]]`. Hence the name longest common prefix. For `i = 0` and `i = len` the LCP value is -1. */ saidx_t *LCP; /** The length of the string S. */ saidx_t len; /** A cache for lcp-intervals */ lcp_inter_t *cache; /** The FVC array holds the character after the LCP. */ char *FVC; /** This is the child array. */ saidx_t *CLD; } esa_s; lcp_inter_t get_match_cached(const esa_s *, const char *query, size_t qlen); lcp_inter_t get_match(const esa_s *, const char *query, size_t qlen); int esa_init(esa_s *, const seq_subject *S); void esa_free(esa_s *); #ifdef DEBUG char code2char(ssize_t code); #endif // DEBUG #endif andi-0.14/src/global.h000066400000000000000000000054511415070357400145640ustar00rootroot00000000000000/** * @file * @brief Global Definitions * * This file contains the declaration of global variables and * their related values. The actual definition is located in andi.c */ #ifndef _GLOBAL_H_ #define _GLOBAL_H_ #include #include "config.h" #include /** * The *global* variable ::FLAGS is used to set different options * for the execution of the program. Use `FLAGS & F_NAME` to check * if `F_NAME` was set. */ extern int FLAGS; /** * The *global* variable ::THREADS contains the number of threads the program * should use. */ extern int THREADS; /** * The ::ANCHOR_P_VALUE represents the probability that an anchor will be found, * if the two sequences are unrelated. I.e. it is the p-value for H_0: random * sequences. Its value can be set using the `-p` switch. */ extern double ANCHOR_P_VALUE; /** * The number of matrices that should be bootstrapped. */ extern long unsigned int BOOTSTRAP; /** * A global random number generator. Has to be seedable. */ extern gsl_rng *RNG; /** * The evolutionary model. */ extern int MODEL; enum { M_RAW, M_JC, M_KIMURA, M_LOGDET }; /** * This enum contains the available flags. Please note that all * available options are a power of 2. */ enum { F_NONE = 0, F_TRUNCATE_NAMES = 1, F_VERBOSE = 2, F_EXTRA_VERBOSE = 4, F_NON_ACGT = 8, F_JOIN = 16, F_LOW_MEMORY = 32, F_SHORT = 64, F_PRINT_PROGRESS = 128, F_SOFT_ERROR = 256 }; /** * @brief This macro is used to unify the checks for the return value of malloc. * * @param PTR - The pointer getting checked. */ #define CHECK_MALLOC(PTR) \ do { \ if (PTR == NULL) { \ err(errno, "Out of memory"); \ } \ } while (0) /** * @brief This macro is used to print a warning and make the program exit with * an failure exit code, later. */ #define soft_err(...) \ do { \ FLAGS |= F_SOFT_ERROR; \ warn(__VA_ARGS__); \ } while (0) /** * @brief This macro is used to print a warning and make the program exit with * an failure exit code, later. */ #define soft_errx(...) \ do { \ FLAGS |= F_SOFT_ERROR; \ warnx(__VA_ARGS__); \ } while (0) #endif andi-0.14/src/io.c000066400000000000000000000200621415070357400137210ustar00rootroot00000000000000/** * @file * @brief This file contains the definitions for various io methods. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include "global.h" #include "io.h" /** * @brief Access an element. * @param sv - The base vector. * @param index - The element index to access. * @returns the string at position `index`. */ char *string_vector_at(struct string_vector *sv, size_t index) { return sv->data[index]; } /** * @brief Access the underlying buffer. * @param sv - The base vector. * @returns the underlying buffer. */ char **string_vector_data(struct string_vector *sv) { return sv->data; } /** * @brief Free all data. * @param sv - The base vector. */ void string_vector_free(struct string_vector *sv) { size_t i = 0; for (; i < sv->size; i++) { free(sv->data[i]); } free(sv->data); } /** * @brief Initialise the vector. * @param sv - The base vector. */ void string_vector_init(struct string_vector *sv) { sv->data = malloc(sizeof(*sv->data) * 4); CHECK_MALLOC(sv->data); sv->capacity = 4; sv->size = 0; } /** * @brief Adds a copy to the end of the vector. * @param sv - The base vector. * @param str - The new string to add. */ void string_vector_push_back(struct string_vector *sv, const char *str) { string_vector_emplace_back(sv, strdup(str)); } /** * @brief Add a file name to the end of the vector, directly. * @param sv - The base vector. * @param str - The string to emplace. */ void string_vector_emplace_back(struct string_vector *sv, char *str) { if (sv->size < sv->capacity) { sv->data[sv->size++] = str; } else { char **ptr = reallocarray(sv->data, sv->capacity / 2, 3 * sizeof(*ptr)); CHECK_MALLOC(ptr); sv->data = ptr; sv->capacity = (sv->capacity / 2) * 3; sv->data[sv->size++] = str; } } /** * @brief Return the number of elements. * @param sv - The base vector. * @returns the size of the vector. */ size_t string_vector_size(const struct string_vector *sv) { return sv->size; } /** * @brief Read a *fof* and add its contents into a vector. * @param file_name - The file of file names aka. fof. * @param sv - The vector to add file names to. */ void read_into_string_vector(const char *file_name, struct string_vector *sv) { FILE *file = strcmp(file_name, "-") ? fopen(file_name, "r") : stdin; if (!file) { soft_err("%s", file_name); return; } while (1) { char *str = NULL; size_t buffer_size = 0; ssize_t check = getline(&str, &buffer_size, file); // EOF is set only *after* getline tried to read past it. if (check == -1 && feof(file) != 0) { free(str); break; // EOF } if (check == -1) { soft_err("%s", file_name); break; } char *nl = strchr(str, '\n'); if (nl) { *nl = '\0'; // remove newline character } // ignore empty lines if (strlen(str) == 0) { free(str); continue; } string_vector_emplace_back(sv, str); } int check = fclose(file); if (check != 0) { soft_err("%s", file_name); } } /** * @brief Joins all sequences from a file into a single long sequence. * * Apart from reading all sequences from a file, this function also * merges them into one long sequence. * * "I didn't learn joined up handwriting for nothing, you know." * ~ Gilderoy Lockhart * * @param file_name - The name of the file to be used for reading. The name is * also used to infer the sequence name. * @param dsa - (output parameter) An array that holds found sequences. */ void read_fasta_join(const char *file_name, dsa_t *dsa) { if (!file_name || !dsa) return; dsa_t single; dsa_init(&single); read_fasta(file_name, &single); if (dsa_size(&single) == 0) { return; } seq_t joined = dsa_join(&single); /* In join mode we try to be clever about the sequence name. Given the file * path we extract just the file name. ie. path/file.ext -> file * This obviously fails on Windows. */ const char *left = strrchr(file_name, '/'); // find the last path separator left = (left == NULL) ? file_name : left + 1; // left is the position one of to the right of the path separator const char *dot = strchrnul(left, '.'); // find the extension // copy only the file name, not its path or extension joined.name = strndup(left, dot - left); CHECK_MALLOC(joined.name); dsa_push(dsa, joined); dsa_free(&single); } /** * @brief This function reads sequences from a file. * @param file_name - The file to read. * @param dsa - (output parameter) An array that holds found sequences. */ void read_fasta(const char *file_name, dsa_t *dsa) { if (!file_name || !dsa) return; int file_descriptor = strcmp(file_name, "-") ? open(file_name, O_RDONLY) : STDIN_FILENO; if (file_descriptor < 0) { soft_err("%s", file_name); return; } struct pfasta_parser pp = pfasta_init(file_descriptor); if (pp.errstr) { soft_errx("%s: %s", file_name, pp.errstr); goto fail; } seq_t top = {}; while (!pp.done) { struct pfasta_record pr = pfasta_read(&pp); if (pp.errstr) { soft_errx("%s: %s", file_name, pp.errstr); goto fail; } int check = seq_init(&top, pr.sequence, pr.name); // skip broken sequences if (check != 0) continue; dsa_push(dsa, top); pfasta_record_free(&pr); } fail: pfasta_free(&pp); close(file_descriptor); } /** * @brief Prints the distance matrix. * * This function pretty prints the distance matrix. For small distances * scientific notation is used. * * @param D - The distance matrix * @param sequences - An array of pointers to the sequences. * @param n - The number of sequences. * @param warnings - Print warnings? Set to 0 for bootstrapped matrices. */ void print_distances(const struct model *D, const seq_t *sequences, size_t n, int warnings) { size_t i, j; int use_scientific = 0; double *DD = malloc(n * n * sizeof(*DD)); CHECK_MALLOC(DD); #define DD(X, Y) (DD[(X)*n + (Y)]) typedef double(estimate_fn)(const model *); estimate_fn *estimate; switch (MODEL) { case M_RAW: estimate = &estimate_RAW; break; default: /* intentional fall-through. This is just here to silence any * compiler warnings. The real default is set in andi.c.*/ case M_JC: estimate = &estimate_JC; break; case M_KIMURA: estimate = &estimate_KIMURA; break; case M_LOGDET: estimate = &estimate_LOGDET; break; } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { model datum = D(i, j); if (!(FLAGS & F_EXTRA_VERBOSE)) { datum = model_average(&D(i, j), &D(j, i)); } double dist = DD(i, j) = i == j ? 0.0 : estimate(&datum); if (dist > 0 && dist < 0.001) { use_scientific = 1; } if (isnan(dist) && warnings) { const char str[] = { "For the two sequences '%s' and '%s' the distance " "computation failed and is reported as nan. " "Please refer to the documentation for further details."}; soft_errx(str, sequences[i].name, sequences[j].name); } if (!isnan(dist) && i < j && warnings) { double coverage1 = model_coverage(&D(i, j)); double coverage2 = model_coverage(&D(j, i)); if (coverage1 < 0.2 || coverage2 < 0.2) { const char str[] = { "For the two sequences '%s' and '%s' very little " "homology was found (%f and %f, respectively)."}; soft_errx(str, sequences[i].name, sequences[j].name, coverage1, coverage2); } } } } printf("%zu\n", n); for (i = 0; i < n; i++) { // Print ten characters of the name. Pad with spaces, if // necessary. Truncate to exactly ten characters if requested by user. printf(FLAGS & F_TRUNCATE_NAMES ? "%-10.10s" : "%-10s", sequences[i].name); for (j = 0; j < n; j++) { // use scientific notation for small numbers printf(use_scientific ? " %1.4e" : " %1.4f", DD(i, j)); } printf("\n"); } free(DD); } /** * @brief Prints the coverage matrix. * @param D - The distance matrix * @param n - The number of sequences. */ void print_coverages(const struct model *D, size_t n) { size_t i, j; printf("\nCoverage:\n"); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { printf("%1.4e ", model_coverage(&D(i, j))); } printf("\n"); } } andi-0.14/src/io.h000066400000000000000000000022241415070357400137260ustar00rootroot00000000000000/** * @file * @brief This header contains function declarations for io procedures. */ #ifndef _IO_H_ #define _IO_H_ #include "model.h" #include "sequence.h" #include #include #include /** * This is a neat hack for dealing with matrices. */ #define D(X, Y) (D[(X)*n + (Y)]) #define M(X, Y) (M[(X)*n + (Y)]) void read_fasta(const char *, dsa_t *dsa); void read_fasta_join(const char *, dsa_t *dsa); void print_distances(const struct model *, const seq_t *, size_t, int); void print_coverages(const struct model *, size_t); /** * @brief A dynamically growing structure for file_names. */ struct string_vector { char **data; size_t capacity, size; }; char *string_vector_at(struct string_vector *, size_t); char **string_vector_data(struct string_vector *); void string_vector_free(struct string_vector *); void string_vector_init(struct string_vector *); void string_vector_push_back(struct string_vector *, const char *); void string_vector_emplace_back(struct string_vector *, char *); size_t string_vector_size(const struct string_vector *); void read_into_string_vector(const char *, struct string_vector *); #endif // _IO_H_ andi-0.14/src/model.c000066400000000000000000000221531415070357400144150ustar00rootroot00000000000000/** @file * @brief This file contains all functions for the mutation matrix and the * estimation of evolutionary distances thereof. */ #include "model.h" #include "global.h" #include #include #include #include /** * @brief Sum some mutation count specified by `summands`. Intended to be used * through the `model_sum` macro. * * @param MM - The mutation matrix. * @param summands - The mutations to add. * @returns The sum of mutations. */ static size_t model_sum_types(const model *MM, const int summands[]) { size_t total = 0; for (int i = 0; summands[i] != MUTCOUNTS; ++i) { total += MM->counts[summands[i]]; } return total; } #define model_sum(MM, ...) \ model_sum_types((MM), (int[]){__VA_ARGS__, MUTCOUNTS}) /** * @brief Average two mutation matrices. * * @param MM - One matrix * @param NN - Second matrix * @returns The average (sum) of two mutation matrices. */ model model_average(const model *MM, const model *NN) { model ret = *MM; for (int i = 0; i != MUTCOUNTS; ++i) { ret.counts[i] += NN->counts[i]; } ret.seq_len += NN->seq_len; return ret; } /** * @brief Compute the total number of nucleotides in the pairwise alignment. * * @param MM - The mutation matrix. * @returns The length of the alignment. */ size_t model_total(const model *MM) { size_t total = 0; for (size_t i = 0; i < MUTCOUNTS; ++i) { total += MM->counts[i]; } return total; } /** * @brief Compute the coverage of an alignment. * * @param MM - The mutation matrix. * @returns The relative coverage */ double model_coverage(const model *MM) { size_t covered = model_total(MM); size_t actual = MM->seq_len; return (double)covered / (double)actual; } /** * @brief Estimate the uncorrected distance of a pairwise alignment. * * @param MM - The mutation matrix. * @returns The uncorrected substitution rate. */ double estimate_RAW(const model *MM) { size_t nucl = model_total(MM); size_t SNPs = model_sum(MM, AtoC, AtoG, AtoT, CtoA, CtoG, CtoT, GtoA, GtoC, GtoT, TtoA, TtoC, TtoG); // Insignificant results. All abort the fail train. if (nucl <= 3) { return NAN; } return (double)SNPs / (double)nucl; } /** * @brief Compute the Jukes-Cantor distance. * * @param MM - The mutation matrix. * @returns The corrected JC distance. */ double estimate_JC(const model *MM) { double dist = estimate_RAW(MM); dist = -0.75 * log(1.0 - (4.0 / 3.0) * dist); // jukes cantor // fix negative zero return dist <= 0.0 ? 0.0 : dist; } /** @brief computes the evolutionary distance using K80. * * @param MM - The mutation matrix. * @returns The corrected Kimura distance. */ double estimate_KIMURA(const model *MM) { size_t nucl = model_total(MM); size_t transitions = model_sum(MM, AtoG, GtoA, CtoT, TtoC); size_t transversions = model_sum(MM, AtoC, CtoA, AtoT, TtoA, GtoC, CtoG, GtoT, TtoG); double P = (double)transitions / (double)nucl; double Q = (double)transversions / (double)nucl; double tmp = 1.0 - 2.0 * P - Q; double dist = -0.25 * log((1.0 - 2.0 * Q) * tmp * tmp); // fix negative zero return dist <= 0.0 ? 0.0 : dist; } /** @brief computes the evolutionary distance using LogDet. * * The LogDet distance between sequence X and and sequence Y * is given as * * -(1 / K) * (log(det(Fxy)) - 0.5 * log(det(Fxx * Fyy))) * * Where K is the number of character states, Fxy is the site-pattern * frequency matrix, and diagonal matrices Fxx and Fyy give the * frequencies of the different character states in sequences X and Y. * * Each i,j-th entry in Fxy is the proportion of homologous sites * where sequences X and Y have character states i and j, respectively. * * For our purposes, X is the Subject (From) sequence and Y is the * Query (To) sequence and matrix Fxy looks like * * To A C G T * From * A ( ) * C ( ) * G ( ) * T ( ) * * @param MM - The mutation matrix. * @returns The LogDet distance. */ double estimate_LOGDET(const model *MM) { double nucl = (double)model_total(MM); double P[MUTCOUNTS]; for (int i = 0; i < MUTCOUNTS; i++) { P[i] = MM->counts[i] / nucl; } double logDetFxxFyy = // log determinant of diagonal matrix of row sums log(model_sum(MM, AtoA, AtoC, AtoG, AtoT) / nucl) + log(model_sum(MM, CtoA, CtoC, CtoG, CtoT) / nucl) + log(model_sum(MM, GtoA, GtoC, GtoG, GtoT) / nucl) + log(model_sum(MM, TtoA, TtoC, TtoG, TtoT) / nucl) + // log determinant of diagonal matrix of column sums log(model_sum(MM, AtoA, CtoA, GtoA, TtoA) / nucl) + log(model_sum(MM, AtoC, CtoC, GtoC, TtoC) / nucl) + log(model_sum(MM, AtoG, CtoG, GtoG, TtoG) / nucl) + log(model_sum(MM, AtoT, CtoT, GtoT, TtoT) / nucl); // determinant of the site-pattern frequency matrix double detFxy = P[AtoA] * P[CtoC] * (P[GtoG] * P[TtoT] - P[TtoG] * P[GtoT]) - P[AtoA] * P[CtoG] * (P[GtoC] * P[TtoT] - P[TtoC] * P[GtoT]) + P[AtoA] * P[CtoT] * (P[GtoC] * P[TtoG] - P[TtoC] * P[GtoG]) - P[AtoC] * P[CtoA] * (P[GtoG] * P[TtoT] - P[TtoG] * P[GtoT]) + P[AtoC] * P[CtoG] * (P[GtoA] * P[TtoT] - P[TtoA] * P[GtoT]) - P[AtoC] * P[CtoT] * (P[GtoA] * P[TtoG] - P[TtoA] * P[GtoG]) + P[AtoG] * P[CtoA] * (P[GtoC] * P[TtoT] - P[TtoC] * P[GtoT]) - P[AtoG] * P[CtoC] * (P[GtoA] * P[TtoT] - P[TtoA] * P[GtoT]) + P[AtoG] * P[CtoT] * (P[GtoA] * P[TtoC] - P[TtoA] * P[GtoC]) - P[AtoT] * P[CtoA] * (P[GtoC] * P[TtoG] - P[TtoC] * P[GtoG]) + P[AtoT] * P[CtoC] * (P[GtoA] * P[TtoG] - P[TtoA] * P[GtoG]) - P[AtoT] * P[CtoG] * (P[GtoA] * P[TtoC] - P[TtoA] * P[GtoC]); double dist = -0.25 * (log(detFxy) - 0.5 * logDetFxxFyy); // fix negative zero return dist <= 0.0 ? 0.0 : dist; } /** @brief Bootstrap a mutation matrix. * * The classical bootstrapping process, as described by Felsenstein, resamples * all nucleotides of a MSA. As andi only computes a pairwise alignment, this * process boils down to a simple multinomial distribution. We just have to * resample the elements of the mutation matrix. See Klötzl & Haubold (2016) * for details. http://www.mdpi.com/2075-1729/6/1/11/htm * * @param datum - The original mutation matrix. * @returns A bootstrapped mutation matrix. */ model model_bootstrap(model datum) { size_t nucl = model_total(&datum); double p[MUTCOUNTS]; for (size_t i = 0; i < MUTCOUNTS; ++i) { p[i] = datum.counts[i] / (double)nucl; } gsl_ran_multinomial(RNG, MUTCOUNTS, nucl, p, datum.counts); return datum; } /** * @brief Given an anchor, classify nucleotides. * * For anchors we already know that the nucleotides of the subject and the query * are equal. Thus only one sequence has to be analysed. Most models don't * actually care about the individual nucleotides as long as they are equal in * the two sequences. For these models, we just assume equal distribution. * * @param MM - The mutation matrix * @param S - The subject * @param len - The anchor length */ void model_count_equal(model *MM, const char *S, size_t len) { if (MODEL == M_RAW || MODEL == M_JC || MODEL == M_KIMURA) { size_t fourth = len / 4; MM->counts[AtoA] += fourth; MM->counts[CtoC] += fourth; MM->counts[GtoG] += fourth; MM->counts[TtoT] += fourth + (len & 3); return; } // Fall-back algorithm for future models. Note, as this works on a // per-character basis it is slow. size_t local_counts[4] = {0}; for (; len--;) { char s = *S++; // ';!#' are all smaller than 'A' if (s < 'A') { // Technically, s can only be ';' at this point. continue; } // The four canonical nucleotides can be uniquely identified by the bits // 0x6: A -> 0, C → 1, G → 3, T → 2. Thus the order below is changed. local_counts[(s >> 1) & 3]++; } MM->counts[AtoA] += local_counts[0]; MM->counts[CtoC] += local_counts[1]; MM->counts[GtoG] += local_counts[3]; MM->counts[TtoT] += local_counts[2]; } /** @brief Convert a nucleotide to a 2bit representation. * * We want to map characters: * A → 0 * C → 1 * G → 2 * T → 3 * The trick used below is that the three lower bits of the * characters are unique. Thus, they can be used to compute the mapping * above. The mapping itself is done via tricky bitwise operations. * * @param c - input nucleotide * @returns 2bit representation. */ char nucl2bit(unsigned char c) { c &= 6; c ^= c >> 1; return c >> 1; } /** * @brief Count the substitutions and add them to the mutation matrix. * * @param MM - The mutation matrix. * @param S - The subject * @param Q - The query * @param len - The length of the alignment */ void model_count(model *MM, const char *S, const char *Q, size_t len) { size_t local_counts[MUTCOUNTS] = {0}; for (size_t i = 0; i < len; S++, Q++, i++) { char s = *S; char q = *Q; // Skip special characters. if (s < 'A' || q < 'A') { continue; } // Pick the correct two bits representing s and q. unsigned char foo = nucl2bit(s); unsigned char bar = nucl2bit(q); /* * Finally, we want to map the indices to the correct mutation. This is * done by utilising the mutation types in model.h. */ unsigned int index = (foo << 2) + bar; local_counts[index]++; } for (int i = 0; i != MUTCOUNTS; ++i) { MM->counts[i] += local_counts[i]; } } andi-0.14/src/model.h000066400000000000000000000030321415070357400144150ustar00rootroot00000000000000/** @file * @brief This header contains all structures and prototypes for creating a * mutation matrix and estimating distances trough an evolutionary model * thereof. */ #pragma once #include /** * This enum contains all possible mutations. The total number * of different possible mutations is MUTCOUNTS. */ enum { AtoA, AtoC, AtoG, AtoT, CtoA, CtoC, CtoG, CtoT, GtoA, GtoC, GtoG, GtoT, TtoA, TtoC, TtoG, TtoT, MUTCOUNTS }; /** @brief The mutation matrix. * * We need to keep track of the different types of mutations between two * sequences. For this the following matrix is filled. * * To A C G T * From * A ( ) * C ( ) * G ( ) * T ( ) * * The cells are absolute counts. Together with seq_len (the query length), * we can deduce the substitution rate and coverage. * * As libdivsufsort is 32 bit the sequence length is limited to (INT_MAX-1)/2. * We can thus use the same limit for the counts. */ typedef struct model { /** The absolute counts of mutation types. */ unsigned int counts[MUTCOUNTS]; /** The query length. */ unsigned int seq_len; } model; void model_count_equal(model *, const char *, size_t); void model_count(model *, const char *, const char *, size_t); model model_average(const model *, const model *); double model_coverage(const model *); double estimate_RAW(const model *); double estimate_JC(const model *); double estimate_KIMURA(const model *); double estimate_LOGDET(const model *); model model_bootstrap(model); andi-0.14/src/process.c000066400000000000000000000220241415070357400147700ustar00rootroot00000000000000 /** * @file * @brief This file contains various distance methods. */ #include "process.h" #include "esa.h" #include "global.h" #include "io.h" #include "model.h" #include "sequence.h" #include #include #include #include #ifdef _OPENMP #include #endif int calculate_bootstrap(const struct model *M, const seq_t *sequences, size_t n); typedef _Bool bool; #define false 0 #define true !false /** * @brief This structure captures properties of an anchor. */ struct anchor { /** The position on the subject. */ size_t pos_S; /** The position on the query. */ size_t pos_Q; /** The length of the exact match. */ size_t length; }; /** * @brief This is a structure of assorted variables needed for anchor finding. */ struct context { const esa_s *C; const char *query; size_t query_length; size_t threshold; }; /** * @brief Compute the length of the longest common prefix of two strings. * * @param S - One string. * @param Q - Another string. * @param remaining - The length of one of the strings. * @returns the length of the lcp. */ static inline size_t lcp(const char *S, const char *Q, size_t remaining) { size_t length = 0; while (length < remaining && S[length] == Q[length]) { length++; } return length; } /** * @brief Check whether the last anchor can be extended by a lucky anchor. * * Anchors are defined to be unique and of a minimum length. The uniqueness * requires us to search throw the suffix array for a second appearance of the * anchor. However, if a left anchor is already unique, we could be sloppy and * drop the uniqueness criterion for the second anchor. This way we can skip the * lookup and just compare characters directly. However, for a lucky anchor the * match still has to be longer than the threshold. * * @param ctx - Matching context of various variables. * @param last_match - The last anchor. * @param this_match - Input/Output variable for the current match. * @returns true iff the current match is a lucky anchor. */ static inline bool lucky_anchor(const struct context *ctx, const struct anchor *last_match, struct anchor *this_match) { size_t advance = this_match->pos_Q - last_match->pos_Q; size_t gap = this_match->pos_Q - last_match->pos_Q - last_match->length; size_t try_pos_S = last_match->pos_S + advance; if (try_pos_S >= (size_t)ctx->C->len || gap > ctx->threshold) { return false; } this_match->pos_S = try_pos_S; this_match->length = lcp(ctx->query + this_match->pos_Q, ctx->C->S + try_pos_S, ctx->query_length - this_match->pos_Q); return this_match->length >= ctx->threshold; } /** * @brief Check for a new anchor. * * Given the current context and starting position check if the new match is an * anchor. The latter requires uniqueness and a certain minimum length. * * @param ctx - Matching context of various variables. * @param last_match - (unused) * @param this_match - Input/Output variable for the current match. * @returns true iff an anchor was found. */ static inline bool anchor(const struct context *ctx, const struct anchor *last_match, struct anchor *this_match) { lcp_inter_t inter = get_match_cached(ctx->C, ctx->query + this_match->pos_Q, ctx->query_length - this_match->pos_Q); this_match->pos_S = ctx->C->SA[inter.i]; this_match->length = inter.l <= 0 ? 0 : inter.l; return inter.i == inter.j && this_match->length >= ctx->threshold; } /** * @brief Divergence estimation using the anchor technique. * * The dist_anchor() function estimates the divergence between two * DNA sequences. The subject is given as an ESA, whereas the query * is a simple string. This function then looks for *anchors* -- long * substrings that exist in both sequences. Then it manually checks for * mutations between those anchors. * * @param C - The enhanced suffix array of the subject. * @param query - The actual query string. * @param query_length - The length of the query string. Needed for speed * reasons. * @param threshold - Minimal length for an anchor. * @returns A matrix with estimates of base substitutions. */ model dist_anchor(const esa_s *C, const char *query, size_t query_length, size_t threshold) { struct model ret = {.seq_len = query_length, .counts = {0}}; struct anchor this_match = {0}; struct anchor last_match = {0}; bool last_was_right_anchor = false; size_t border = C->len / 2; struct context ctx = {C, query, query_length, threshold}; // Iterate over the complete query. while (this_match.pos_Q < query_length) { // Check for lucky anchors and fall back to normal strategy. if (lucky_anchor(&ctx, &last_match, &this_match) || anchor(&ctx, &last_match, &this_match)) { // We have reached a new anchor. size_t end_S = last_match.pos_S + last_match.length; size_t end_Q = last_match.pos_Q + last_match.length; // Check if this can be a right anchor to the last one. if (this_match.pos_S > end_S && this_match.pos_Q - end_Q == this_match.pos_S - end_S && (this_match.pos_S < border) == (last_match.pos_S < border)) { // classify nucleotides in the left qanchor model_count_equal(&ret, query + last_match.pos_Q, last_match.length); // Count the SNPs in between. model_count(&ret, C->S + end_S, query + end_Q, this_match.pos_Q - end_Q); last_was_right_anchor = true; } else { if (last_was_right_anchor) { // If the last was a right anchor, but with the current one, // we cannot extend, then add its length. model_count_equal(&ret, query + last_match.pos_Q, last_match.length); } else if (last_match.length >= threshold * 2) { // The last anchor wasn't neither a left or right anchor. // But, it was as long as an anchor pair. So still count it. model_count_equal(&ret, query + last_match.pos_Q, last_match.length); } last_was_right_anchor = false; } // Cache values for later last_match = this_match; } // Advance this_match.pos_Q += this_match.length + 1; } // Very special case: The sequences are identical if (last_match.length >= query_length) { model_count_equal(&ret, query, query_length); return ret; } // We might miss a few nucleotides if the last anchor was also a right // anchor. The logic is the same as a few lines above. if (last_was_right_anchor) { model_count_equal(&ret, query + last_match.pos_Q, last_match.length); } else if (last_match.length >= threshold * 2) { model_count_equal(&ret, query + last_match.pos_Q, last_match.length); } return ret; } /* * Include distMatrix and distMatrixLM. */ #define FAST #include "dist_hack.h" #undef FAST #include "dist_hack.h" /** * @brief Calculates and prints the distance matrix * @param sequences - An array of pointers to the sequences. * @param n - The number of sequences. */ void calculate_distances(seq_t *sequences, size_t n) { struct model *M = NULL; // The maximum number of sequences is near 457'845'052. size_t intermediate = SIZE_MAX / sizeof(*M) / n; if (intermediate < n) { size_t root = (size_t)sqrt(SIZE_MAX / sizeof(*M)); err(1, "Comparison is limited to %zu sequences (%zu given).", root, n); } M = malloc(n * n * sizeof(*M)); if (!M) { err(errno, "Could not allocate enough memory for the comparison " "matrix. Try using --join or --low-memory."); } // compute the distances if (FLAGS & F_LOW_MEMORY) { distMatrixLM(M, sequences, n); } else { distMatrix(M, sequences, n); } // print the results print_distances(M, sequences, n, 1); // print additional information. if (FLAGS & F_VERBOSE) { print_coverages(M, n); } // create new bootstrapped distance matrices if (BOOTSTRAP) { int res = calculate_bootstrap(M, sequences, n); if (res) { soft_errx("Bootstrapping failed."); } } free(M); } /** Yet another hack. */ #define B(X, Y) (B[(X)*n + (Y)]) /** @brief Computes a bootstrap from _pairwise_ alignments. * * Doing bootstrapping for alignments with only two sequences is easy. It boils * down to a simple multi-nomial process over the substitution matrix. * * @param M - the initial distance matrix * @param sequences - a list of the sequences, containing their lengths * @param n - the number of sequences * * The number of bootstrapped distance matrices to print is implicitly * passed via the global `BOOTSTRAP` variable. * * @returns 0 iff successful. */ int calculate_bootstrap(const struct model *M, const seq_t *sequences, size_t n) { if (!M || !sequences || !n) { return 1; } // B is the new bootstrap matrix struct model *B = malloc(n * n * sizeof(*B)); CHECK_MALLOC(B); // Compute a number of new distance matrices while (BOOTSTRAP--) { for (size_t i = 0; i < n; i++) { for (size_t j = i; j < n; j++) { if (i == j) { B(i, j) = (struct model){.seq_len = 1.0, .counts = {1.0}}; continue; } // Bootstrapping should only be used with averaged distances. model datum = model_average(&M(i, j), &M(j, i)); datum = model_bootstrap(datum); B(j, i) = B(i, j) = datum; } } print_distances(B, sequences, n, 0); } free(B); return 0; } andi-0.14/src/process.h000066400000000000000000000003321415070357400147730ustar00rootroot00000000000000/** * @file * @brief This file contains the declarations of functions in process.c * */ #ifndef _PROCESS_H_ #define _PROCESS_H_ #include "sequence.h" void calculate_distances(seq_t *sequences, size_t n); #endif andi-0.14/src/sequence.c000066400000000000000000000174171415070357400151340ustar00rootroot00000000000000/** * @file * @brief Sequence utilities * * This file contains utility functions for working with DNA sequences. */ #include #include #include #include #include #include "global.h" #include "sequence.h" #include void normalize(seq_t *S); double shustring_cum_prob(size_t x, double g, size_t l); size_t min_anchor_length(double p, double g, size_t l); /** Create a new dynamic array for sequences. */ int dsa_init(dsa_t *A) { // allocate at least 4 slots so the growth by 1.5 below doesn't get stuck // at 3 slots. A->data = malloc(sizeof(*A->data) * 4); CHECK_MALLOC(A->data); A->capacity = 4; A->size = 0; return 0; } /** Add a sequence to an array. */ void dsa_push(dsa_t *A, seq_t S) { if (A->size < A->capacity) { A->data[A->size++] = S; } else { // use the near-optimal growth factor of 1.5 seq_t *ptr = reallocarray(A->data, A->capacity / 2, sizeof(seq_t) * 3); CHECK_MALLOC(ptr); A->capacity = (A->capacity / 2) * 3; A->data = ptr; A->data[A->size++] = S; } } /** Frees the array and all sequences stored within. */ void dsa_free(dsa_t *A) { size_t i; for (i = 0; i < A->size; i++) { seq_free(&A->data[i]); } free(A->data); *A = (dsa_t){}; } /** Returns the number of sequences stored within an array. */ size_t dsa_size(const dsa_t *A) { return A->size; } /** Get the raw C array. */ seq_t *dsa_data(dsa_t *A) { return A->data; } /** * @brief Convert an array of multiple sequences into a single sequence. * * This function joins all sequences contained in an array into one * long sequence. The sequences are separated by a `!` character. The * caller has to free the initial array. * * @returns A new sequence representation the union of the array. */ seq_t dsa_join(dsa_t *A) { seq_t joined = {}; if (A->size == 0) { return joined; } if (A->size == 1) { /* If we are to join just one sequence, _move_ its contents. */ joined = A->data[0]; A->data[0] = (seq_t){}; return joined; } seq_t *data = A->data; seq_t *it = data; // Compute the total length size_t total = 0, i; for (i = 0; i < A->size; i++, it++) { total += it->len + 1; } // A single malloc for the whole new sequence char *ptr = malloc(total); CHECK_MALLOC(ptr); char *next = ptr; // Copy all old sequences and add a `!` in between it = data; memcpy(next, it->S, it->len); next += it->len; for (i = 1, it++; i < A->size; i++, it++) { *next++ = '!'; memcpy(next, it->S, it->len); next += it->len; } // Don't forget the null byte. *next = '\0'; joined.S = ptr; joined.len = total - 1; // subtract the null byte return joined; } /** * @brief Frees the memory of a given sequence. * @param S - The sequence to free. */ void seq_free(seq_t *S) { free(S->S); free(S->name); *S = (seq_t){}; } /** * @brief Compute the reverse complement. * @param str The master string. * @param len The length of the master string * @return The reverse complement. The caller has to free it! */ char *revcomp(const char *str, size_t len) { if (!str) return NULL; char *rev = malloc(len + 1); CHECK_MALLOC(rev); char *r = rev; const char *s = &str[len - 1]; rev[len] = '\0'; do { char c = *s--; char d; if (c < 'A') { d = ';'; // rosebud } else { d = c ^= c & 2 ? 4 : 21; } *r++ = d; } while (--len); return rev; } /** * @brief This function concatenates the reverse complement to a given master * string. A `#` sign is used as a separator. * @param s The master string. * @param len Its length. * @return The newly concatenated string. */ char *catcomp(char *s, size_t len) { if (!s) return NULL; char *rev = revcomp(s, len); char *temp = realloc(rev, 2 * len + 2); CHECK_MALLOC(temp); rev = temp; rev[len] = '#'; memcpy(rev + len + 1, s, len + 1); return rev; } /** * @brief Calculates the GC content of a sequence. * * This function computes the relative amount of G and C in the total sequence. */ double calc_gc(const seq_t *S) { size_t GC = 0; const char *p = S->S; for (; *p; p++) { if (*p == 'G' || *p == 'C') { GC++; } } return (double)GC / S->len; } /** @brief Prepares a sequences to be used as the subject in a comparison. */ int seq_subject_init(seq_subject *S, const seq_t *base) { S->gc = calc_gc(base); S->RS = catcomp(base->S, base->len); if (!S->RS) return 1; S->RSlen = 2 * base->len + 1; S->threshold = min_anchor_length(ANCHOR_P_VALUE, S->gc, S->RSlen); return 0; } /** @brief Frees some memory unused for when a sequence is only used as query. */ void seq_subject_free(seq_subject *S) { free(S->RS); S->RS = NULL; S->RSlen = 0; S->gc = 0.0; } /** @brief Initializes a sequences * * @returns 0 iff successful. */ int seq_init(seq_t *S, const char *seq, const char *name) { if (!S || !seq || !name) { return 1; } *S = (seq_t){.S = strdup(seq), .name = strdup(name)}; CHECK_MALLOC(S->S); CHECK_MALLOC(S->name); normalize(S); // recalculate the length because `normalize` might have stripped some // characters. S->len = strlen(S->S); return 0; } /** * @brief Restricts a sequence characters set to ACGT. * * This function strips a sequence of non ACGT characters and converts acgt to * the upper case equivalent. A flag is set if a non-canonical character was * encountered. */ void normalize(seq_t *S) { char *p, *q; char local_non_acgt = 0; for (p = q = S->S; *p; p++) { switch (*p) { case 'A': case 'C': case 'G': case 'T': case '!': *q++ = *p; break; case 'a': case 'c': case 'g': case 't': *q++ = toupper((unsigned char)*p); break; default: local_non_acgt = 1; break; } } *q = '\0'; if (local_non_acgt) { #pragma omp atomic FLAGS |= F_NON_ACGT; } } /** * @brief Calculates the minimum anchor length. * * Given some parameters calculate the minimum length for anchors according * to the distribution from Haubold et al. (2009). * * @param p - The probability with which an anchor will be created under a * random model. * @param g - The the relative amount of GC in the subject. * @param l - The length of the subject (includes revcomp). * @returns The minimum length of an anchor. */ size_t min_anchor_length(double p, double g, size_t l) { size_t x = 1; while (shustring_cum_prob(x, g / 2, l) < 1 - p) { x++; } return x; } /** * @brief Calculates the binomial coefficient of n and k. * * We could (and probably should) use gsl_sf_lnchoose(xx,kk) for this. * * @param n - The n part of the binomial coefficient. * @param k - analogue. * @returns (n choose k) */ size_t binomial_coefficient(size_t n, size_t k) { if (n <= 0 || k > n) { return 0; } if (k == 0 || k == n) { return 1; } if (k > n - k) { k = n - k; } size_t res = 1; for (size_t i = 1; i <= k; i++) { res *= n - k + i; res /= i; } return res; } /** * @brief Given `x` this function calculates the probability of a shustring * with a length less or equal to `x` under a random model. This means, it is * the cumulative probability. * * Let X be the longest shortest unique substring (shustring) at any position. * Then this function computes P{X <= x} with respect to the given parameter * set. See Haubold et al. (2009). Note that `x` includes the final mismatch. * Thus, `x` is `match length + 1`. * * @param x - The maximum length of a shustring. * @param p - The half of the relative amount of GC in the DNA. * @param l - The length of the subject. * @returns The probability of a certain shustring length. */ double shustring_cum_prob(size_t x, double p, size_t l) { double xx = (double)x; double ll = (double)l; size_t k; double s = 0.0; for (k = 0; k <= x; k++) { double kk = (double)k; double t = pow(p, kk) * pow(0.5 - p, xx - kk); s += pow(2, xx) * (t * pow(1 - t, ll)) * (double)binomial_coefficient(x, k); if (s >= 1.0) { s = 1.0; break; } } return s; } andi-0.14/src/sequence.h000066400000000000000000000026111415070357400151270ustar00rootroot00000000000000/** * @file * @brief Functions and structures for DNA sequences * */ #ifndef _SEQUENCE_H_ #define _SEQUENCE_H_ #include #include #include /** * @brief A structure for sequences. * * This structure is used to represent a DNA sequence of some kind. */ typedef struct seq_s { /** This is the DNAs forward strand as a string. */ char *S; /** The length of the forward strand. */ size_t len; /** A name for this sequence */ char *name; } seq_t; /** * @brief This structure enhances the usual sequence with its reverse * complement. */ typedef struct seq_subject { /** This member contains first the reverse strand and then the forward strand. */ char *RS; /** Corresponds to strlen(RS) */ size_t RSlen; /** * @brief GC-Content * * The relative amount of G or C in the DNA. */ double gc; /** The minimum length for an anchor. */ size_t threshold; } seq_subject; void seq_free(seq_t *S); int seq_subject_init(seq_subject *S, const seq_t *); void seq_subject_free(seq_subject *S); int seq_init(seq_t *S, const char *seq, const char *name); /** * @brief A dynamically growing structure for sequences. */ typedef struct dsa_s { seq_t *data; size_t capacity, size; } dsa_t; int dsa_init(dsa_t *A); void dsa_push(dsa_t *A, seq_t S); void dsa_free(dsa_t *A); size_t dsa_size(const dsa_t *A); seq_t *dsa_data(dsa_t *A); seq_t dsa_join(dsa_t *dsa); #endif andi-0.14/test/000077500000000000000000000000001415070357400133365ustar00rootroot00000000000000andi-0.14/test/Makefile.am000066400000000000000000000025571415070357400154030ustar00rootroot00000000000000check_PROGRAMS = test_esa test_seq test_fasta test_process dist_noinst_DATA = test_extra.sh test_random.sh test_join.sh nan.sh low_homo.sh test_seq_SOURCES = test_seq.c $(top_srcdir)/src/sequence.c test_seq_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/opt -DDEBUG -std=gnu99 test_seq_CFLAGS = -Wall -Wextra $(GLIB_CFLAGS) -Wno-missing-field-initializers test_seq_LDADD = $(GLIB_LIBS) $(top_builddir)/opt/libcompat.a test_process_SOURCES = test_process.c $(top_srcdir)/src/esa.c $(top_srcdir)/src/io.c $(top_srcdir)/src/model.c $(top_srcdir)/src/process.c $(top_srcdir)/src/sequence.c $(top_srcdir)/src/global.h test_process_CPPFLAGS = $(OPENMP_CFLAGS) -I$(top_srcdir)/src -I$(top_srcdir)/opt -I$(top_srcdir)/libs -DDEBUG -std=gnu99 test_process_CFLAGS = $(OPENMP_CFLAGS) -Wall -Wextra $(GLIB_CFLAGS) -Wno-missing-field-initializers test_process_LDADD = $(GLIB_LIBS) $(top_builddir)/opt/libcompat.a $(top_builddir)/libs/libpfasta.a test_esa_SOURCES = test_esa.c $(top_srcdir)/src/esa.c $(top_srcdir)/src/sequence.c $(top_srcdir)/src/esa.h test_esa_CPPFLAGS = $(OPENMP_CFLAGS) -I$(top_srcdir)/libs -I$(top_srcdir)/opt -I$(top_srcdir)/src -DDEBUG -std=gnu99 test_esa_CFLAGS = $(OPENMP_CFLAGS) -Wall -Wextra $(GLIB_CFLAGS) -Wno-missing-field-initializers test_esa_LDADD = $(GLIB_LIBS) $(top_builddir)/opt/libcompat.a test_fasta_SOURCES = test_fasta.cxx .PHONY: all all: $(check_PROGRAMS) andi-0.14/test/low_homo.sh000077500000000000000000000014131415070357400155170ustar00rootroot00000000000000#!/bin/bash -f SEED=${RANDOM_SEED:-0} SEED2=0 SEED3=0 if test $SEED -ne 0; then SEED=$((SEED + 1)) SEED2=$((SEED + 2)) SEED3=$((SEED + 3)) fi ./test/test_fasta -s $SEED -l 100000 > a_low.fa ./test/test_fasta -s $SEED2 -l 100000 > b_low.fa ./test/test_fasta -s $SEED3 -l 100 > both_low.fa cat both_low.fa a_low.fa | awk -v RS='>' '{if($1 == "S0")print ">"$0 > "S0_low.fa"}' cat both_low.fa b_low.fa | awk -v RS='>' '{if($1 == "S1")print ">"$0 > "S1_low.fa"}' # this is expected to trigger the low homology warning ./src/andi -j S0_low.fa S1_low.fa 2>&1 | grep 'homology' EXIT_VAL=$? if [[ EXIT_VAL -ge 1 ]]; then echo "Triggering low homology failed" >&2 grep '^>' a_low.fa b_low.fa both_low.fa fi rm -f a_low.fa b_low.fa both_low.fa S0_low.fa S1_low.fa exit $EXIT_VAL andi-0.14/test/nan.sh000077500000000000000000000007151415070357400144540ustar00rootroot00000000000000#!/bin/bash -f SEED=${RANDOM_SEED:-0} SEED2=0 if test $SEED -ne 0; then SEED=$((SEED + 1)) SEED2=$((SEED + 2)) fi ./test/test_fasta -s $SEED -l 10000 > a_nan.fa ./test/test_fasta -s $SEED2 -l 10000 > b_nan.fa # this is expected to trigger the nan warning ./src/andi -j a_nan.fa b_nan.fa 2>&1 | grep 'nan' EXIT_VAL=$? if [[ EXIT_VAL -ge 1 ]]; then echo "Triggering nan failed" >&2 grep '^>' a_nan.fa b_nan.fa fi rm -f a_nan.fa b_nan.fa exit $EXIT_VAL andi-0.14/test/test_esa.c000066400000000000000000000121261415070357400153130ustar00rootroot00000000000000#include "esa.h" #include #include "global.h" #include #include int FLAGS = F_NONE; int THREADS = 1; double ANCHOR_P_VALUE = 0.025; extern const int CACHE_LENGTH; char code3char( ssize_t code){ switch( code & 0x7){ case 0: return 'A'; case 1: return 'C'; case 2: return 'G'; case 3: return 'T'; case 4: return '!'; case 5: return ';'; case 6: return '#'; } return '\0'; } typedef struct { esa_s *C; seq_t *S; seq_subject subject; } esa_fixture; void assert_equal_lcp( const lcp_inter_t *a, const lcp_inter_t *b){ g_assert_cmpint( a->i, ==, b->i); g_assert_cmpint( a->j, ==, b->j); g_assert_cmpint( a->l, ==, b->l); } void assert_equal_cache_nocache( const esa_s *C, const char *str, size_t qlen){ lcp_inter_t a = get_match_cached(C, str, qlen); lcp_inter_t b = get_match(C, str, qlen); assert_equal_lcp( &a, &b); g_assert(strncmp(str, C->S + C->SA[a.i], a.l) == 0); g_assert( str[a.l] != C->S[ a.l + C->SA[a.i]] || str[a.l] == '\0'); } void setup( esa_fixture *ef, gconstpointer test_data){ ef->C = malloc( sizeof(esa_s)); ef->S = malloc( sizeof(seq_t)); g_assert( ef->C != NULL); g_assert( ef->S != NULL); const char *seq = { "TACGAGCACTGGTGGAATTGATGTC" "CAGTCTTATATGGCGCACCAGGCTG" "ATAGTAGTAGCAGTTTGCTTATCTC" "ATCGCGTGTTTCCGGATGACAGAGA" "TACGTGCACTGGTGGGATTGATGTC" "TAGTATTATATGGCGCACCAGGATG" "ATAGTAGTAGCAGTTTGCTTATCCC" "ATCGCGTGTTTGCGGATGACCGAGA" }; g_assert( seq_init( ef->S, seq, "S0" ) == 0); seq_subject_init( &ef->subject, ef->S); g_assert( ef->subject.RS != NULL); int check = esa_init( ef->C, &ef->subject); g_assert( check == 0); } void setup2( esa_fixture *ef, gconstpointer test_data){ ef->C = malloc( sizeof(esa_s)); ef->S = malloc( sizeof(seq_t)); g_assert( ef->C != NULL); g_assert( ef->S != NULL); const char *seq = { "TACGAGCACTGGTGGAATTGATGTC" "CAGTCTTATATGGCGCACCAGGCTG" "ATAGTAGTAGCAGTTTGCTTATCTC" "ATCGCGTGTTTCCGGATGACAGAGA" "!" "TACGTGCACTGGTGGGATTGATGTC" "TAGTATTATATGGCGCACCAGGATG" "ATAGTAGTAGCAGTTTGCTTATCCC" "ATCGCGTGTTTGCGGATGACCGAGA" }; g_assert( seq_init( ef->S, seq, "S0" ) == 0); seq_subject_init( &ef->subject, ef->S); g_assert( ef->subject.RS != NULL); int check = esa_init( ef->C, &ef->subject); g_assert( check == 0); } void teardown( esa_fixture *ef, gconstpointer test_data){ esa_free(ef->C); free(ef->C); seq_free(ef->S); free(ef->S); seq_subject_free(&ef->subject); } extern int count; void basic( esa_fixture *ef, gconstpointer test_data){ esa_s *C = ef->C; g_assert( C->SA); lcp_inter_t a = get_match_cached(C, "AAGACTGG", 8); lcp_inter_t b = get_match(C, "AAGACTGG", 8); assert_equal_lcp( &a, &b); g_assert(strncmp("AAGACTGG",C->S + C->SA[a.i], 8) == 0); a = get_match_cached(C, "AATTAAAA", 8); b = get_match(C, "AATTAAAA", 8); assert_equal_lcp( &a, &b); g_assert(strncmp("AATTAAAA",C->S + C->SA[a.i], a.l) == 0); a = get_match_cached(C, "ACCGAGAA", 8); b = get_match(C, "ACCGAGAA", 8); assert_equal_lcp( &a, &b); g_assert(strncmp("ACCGAGAA",C->S + C->SA[a.i], a.l) == 0); a = get_match_cached(C, "AAAAAAAAAAAA", 12); b = get_match(C, "AAAAAAAAAAAA", 12); assert_equal_lcp( &a, &b); g_assert(strncmp("AAAAAAAAAAAA",C->S + C->SA[a.i], a.l) == 0); //g_assert_cmpint(count, >=, 1 << (2*8)); } void normq_cached( esa_fixture *ef, gconstpointer test_data){ esa_s *C = ef->C; g_assert( C->SA); lcp_inter_t a, b; a = get_match_cached(C, "A", 1); b = get_match(C, "A", 1); assert_equal_lcp( &a, &b); a = get_match_cached(C, "C", 1); b = get_match(C, "C", 1); assert_equal_lcp( &a, &b); a = get_match_cached(C, "CT", 2); b = get_match(C, "CT", 2); assert_equal_lcp( &a, &b); a = get_match_cached(C, "AAGACTGG", 8); b = get_match(C, "AAGACTGG", 8); assert_equal_lcp( &a, &b); a = get_match_cached(C, "AATTAAAA", 8); b = get_match(C, "AATTAAAA", 8); assert_equal_lcp( &a, &b); a = get_match_cached(C, "ACCGAGAA", 8); b = get_match(C, "ACCGAGAA", 8); assert_equal_lcp( &a, &b); a = get_match_cached(C, "AAAAAAAAAAAA", 12); b = get_match(C, "AAAAAAAAAAAA", 12); assert_equal_lcp( &a, &b); a = get_match_cached(C, "!AAAAAAAAAAAA", 12); b = get_match(C, "!AAAAAAAAAAAA", 12); assert_equal_lcp( &a, &b); } size_t MAX_DEPTH = 11; void prefix_dfs( esa_s *C, char *str, size_t depth); void prefix( esa_fixture *ef, gconstpointer test_data){ esa_s *C = ef->C; char str[MAX_DEPTH+1]; str[MAX_DEPTH] = '\0'; prefix_dfs( C, str, 0); } void prefix_dfs( esa_s *C, char *str, size_t depth){ if( depth < MAX_DEPTH){ for( int code = 0; code < 4; ++code){ str[depth] = code2char(code); prefix_dfs( C, str, depth + 1); } } else { assert_equal_cache_nocache(C, str, depth); } } int main(int argc, char *argv[]) { g_test_init( &argc, &argv, NULL); g_test_add("/esa/basic", esa_fixture, NULL, setup, basic, teardown); g_test_add("/esa/sample cache", esa_fixture, NULL, setup, normq_cached, teardown); g_test_add("/esa/sample cache 2", esa_fixture, NULL, setup2, normq_cached, teardown); g_test_add("/esa/full cache", esa_fixture, NULL, setup, prefix, teardown); g_test_add("/esa/full cache 2", esa_fixture, NULL, setup2, prefix, teardown); return g_test_run(); } andi-0.14/test/test_extra.sh000077500000000000000000000020431415070357400160560ustar00rootroot00000000000000#!/bin/sh -f # Test if andi exists, and can be executed ./src/andi --version > /dev/null || exit 1 SEED=${RANDOM_SEED:-0} SEED2=0 SEED3=0 if test $SEED -ne 0; then SEED=$((SEED + 1)) SEED2=$((SEED + 2)) SEED3=$((SEED + 3)) fi # Test andi for more than just two sequences at a time ./test/test_fasta -s $SEED -l 100000 -d 0.01 -d 0.01 -d 0.01 -d 0.01 | ./src/andi > /dev/null || exit 1 # Test low-memory mode ./test/test_fasta -s $SEED2 -l 10000 > test_extra.fasta ./src/andi test_extra.fasta > extra.out ./src/andi test_extra.fasta --low-memory > extra_low_memory.out diff extra.out extra_low_memory.out || exit 1 # Test file of filenames ./test/test_fasta -s $SEED3 -l 10000 > test_extra.fasta echo "$PWD/test_extra.fasta" > fof.txt ./src/andi test_extra.fasta > extra.out ./src/andi --file-of-filenames fof.txt > fof.out cat fof.txt | ./src/andi --file-of-filenames - > fof2.out diff extra.out fof.out || exit 1 diff extra.out fof2.out || exit 1 rm -f test_extra.fasta extra.out extra_low_memory.out fof.out fof2.out fof.txt andi-0.14/test/test_fasta.cxx000066400000000000000000000051661415070357400162270ustar00rootroot00000000000000/** * This program can create genome sequences with a specific distance. */ #include #include #include #include #include using namespace std; void usage(); void print_seq( unsigned, unsigned, int, int, double); int main(int argc, char *argv[]){ random_device rd{}; auto seed = rd(); int length = 1000; int line_length = 70; int raw = 0; auto seqs = vector{0}; int check; while((check = getopt(argc, argv, "s:l:L:d:r")) != -1){ switch(check) { case 's': { seed = static_cast(stol(optarg)); if( seed == 0){ seed = rd(); } break; } case 'l': length = stoi(optarg); break; case 'L': line_length = stoi(optarg); break; case 'd': seqs.push_back(stod(optarg)); break; case 'r': raw = 1; break; case '?': default: usage(); return 1; } } if( seqs.size() < 2){ seqs.push_back(0.1); } if( !raw){ for(auto& dist : seqs) { auto d = dist; auto p = 0.75 - 0.75 * exp(-(4.0/3.0) * d); dist = p; } } auto base_seed = seed; for( int i=0; i< seqs.size(); i++){ cout << ">S" << i << " (base_seed: " << base_seed << ")" << endl; print_seq( base_seed, seed++, length, line_length, seqs[i]); } return 0; } static auto ACGT = "ACGT"; static auto NO_A = "CGT"; static auto NO_C = "AGT"; static auto NO_G = "ACT"; static auto NO_T = "ACG"; void print_seq( unsigned base_seed, unsigned mut_seed, int length, int line_length, double divergence){ char line[line_length+1]; line[line_length] = '\0'; auto base_rand = default_random_engine{base_seed}; auto base_dist = uniform_int_distribution{0,3}; auto base_acgt = [&]{return ACGT[base_dist(base_rand)];}; auto mut_rand = default_random_engine{mut_seed}; auto mut_dist = uniform_real_distribution{0,1}; auto mut = bind( mut_dist, mut_rand); auto mut_acgt = uniform_int_distribution{0,2}; auto mutate = [&](char c){ int idx = mut_acgt(mut_rand); switch(c){ case 'A': return NO_A[idx]; case 'C': return NO_C[idx]; case 'G': return NO_G[idx]; case 'T': return NO_T[idx]; default: return 'X'; } }; double nucleotides = (double)length; double mutations = nucleotides * divergence; for(int i= length, j; i > 0; i -= j){ j = min(line_length, i); for(auto k=0; k /dev/null || exit 1 SEED=${RANDOM_SEED:-0} SEED2=0 SEED3=0 if test $SEED -ne 0; then SEED=$((SEED + 1)) SEED2=$((SEED + 2)) SEED3=$((SEED + 3)) fi # Simple join test ./test/test_fasta -s $SEED -l 1000 -L 1000 -d 0.1 > p1_join.fasta ./test/test_fasta -s $SEED2 -l 1000 -L 1000 -d 0.1 > p2_join.fasta ./test/test_fasta -s $SEED3 -l 10000 -L 10000 -d 0.1 > p3_join.fasta head -qn 2 p1_join.fasta p2_join.fasta p3_join.fasta > S0_join.fasta tail -qn 2 p1_join.fasta p2_join.fasta p3_join.fasta > S1_join.fasta rm p1_join.fasta p2_join.fasta p3_join.fasta; RES=$(./src/andi -m RAW -t 1 -j S0_join.fasta S1_join.fasta | tail -n 1 | awk '{print ($2 - 0.1)}' | awk 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($1-$2) < 0.03}' ) if test $RES -ne 1; then echo "The last test computed a distance deviating more than three percent from its intended value." echo "See S0_join.fasta and S1_join.fasta for the used sequences." exit 1; fi SEED=${RANDOM_SEED:-0} SEED2=0 if test $SEED -ne 0; then SEED=$((SEED + 5)) SEED2=$((SEED + 6)) fi #unbalanced number of contigs ./test/test_fasta -s $SEED -l 1000 -L 1000 -d 0.1 > p2_join.fasta ./test/test_fasta -s $SEED2 -l 10000 -L 10000 -d 0.1 > p3_join.fasta head -qn 2 p3_join.fasta > S0_join.fasta tail -qn 2 p2_join.fasta p3_join.fasta > S1_join.fasta rm p2_join.fasta p3_join.fasta; RES=$(./src/andi -m RAW -t1 -j S0_join.fasta S1_join.fasta | tail -n 1 | awk '{print ($2 - 0.1)}' | awk 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($1-$2) < 0.03}' ) if test $RES -ne 1; then echo "The last test computed a distance deviating more than three percent from its intended value." echo "See S0_join.fasta and S1_join.fasta for the used sequences." exit 1; fi SEED=${RANDOM_SEED:-0} SEED2=0 SEED3=0 if test $SEED -ne 0; then SEED=$((SEED + 11)) SEED2=$((SEED + 12)) SEED3=$((SEED + 13)) fi #unbalanced number of contigs 2 ./test/test_fasta -s $SEED -l 1000 -L 1000 -d 0.1 > p1_join.fasta ./test/test_fasta -s $SEED2 -l 1000 -L 1000 -d 0.1 > p2_join.fasta ./test/test_fasta -s $SEED3 -l 10000 -L 10000 -d 0.1 > p3_join.fasta head -qn 2 p1_join.fasta p3_join.fasta > S0_join.fasta tail -qn 2 p1_join.fasta p2_join.fasta p3_join.fasta > S1_join.fasta rm p1_join.fasta p2_join.fasta p3_join.fasta; RES=$(./src/andi -mRAW -t 1 -j S0_join.fasta S1_join.fasta | tail -n 1 | awk '{print ($2 - 0.1)}' | awk 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($1-$2) < 0.03}' ) if test $RES -ne 1; then echo "The last test computed a distance deviating more than three percent from its intended value." echo "See S0_join.fasta and S1_join.fasta for the used sequences." exit 1; fi rm S0_join.fasta S1_join.fasta andi-0.14/test/test_process.c000066400000000000000000000016061415070357400162220ustar00rootroot00000000000000#include "global.h" #include "process.h" #include #include int FLAGS = 0; int THREADS = 1; long unsigned int BOOTSTRAP = 0; double ANCHOR_P_VALUE = 0.025; gsl_rng *RNG = NULL; int MODEL = M_JC; double shustring_cum_prob(size_t x, double g, size_t l); size_t min_anchor_length(double p, double g, size_t l); void test_shustring_cum_prob() { int len = 100000; double gc = 0.5; double p_value = 0.025; size_t threshold = min_anchor_length(p_value, gc, len); g_assert_cmpfloat(1 - p_value, <, shustring_cum_prob(threshold + 1, gc / 2, len)); g_assert_cmpfloat(1 - p_value, <=, shustring_cum_prob(threshold, gc / 2, len)); g_assert_cmpfloat(1 - p_value, >, shustring_cum_prob(threshold - 1, gc / 2, len)); } int main(int argc, char *argv[]) { g_test_init(&argc, &argv, NULL); g_test_add_func("/process/shustring_cum_prob", test_shustring_cum_prob); return g_test_run(); } andi-0.14/test/test_random.sh000077500000000000000000000044141415070357400162170ustar00rootroot00000000000000#!/bin/sh -f # This scripts test the accuracy of andi with random inputs. For that # it uses the small program test_random to generate pairs of sequences # with a given distance. By default, test_random creates a new set of # sequences each time it is called. Thus, this test has a small, but # non-zero probability of failing. That is a problem with Debian's # reproducible builds effort. So this script acts as a wrapper around # this issue. # # Simply calling this script via # % ./test/test_random.sh # checks a new test-case every time. But with the right parameter # % RANDOM_SEED=1729 ./test/test_random.sh # one specific set of sequences is validated. ./src/andi --help > /dev/null || exit 1 LENGTH=100000 # If RANDOM_SEED is set, use its value. Otherwise 0 is used to signal # to test_random that a new set of sequences shall be generated. SEED=${RANDOM_SEED:-0} for dist in 0.0 0.001 0.01 0.02 0.05 0.1 0.2 0.3 do for n in $(seq 10) do if test $SEED -ne 0; then SEED=$((SEED + 1)) fi res=$(./test/test_fasta -s $SEED -l $LENGTH -d $dist | tee ./test/test_random.fasta | ./src/andi -t 1 | tail -n 1 | awk -v dist=$dist '{print $2, dist}' | awk 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($1-$2) <= 0.055 && abs($1-$2) <= 0.055 * $2}') if test $res -ne 1; then echo "The last test computed a distance deviating more than five percent from its intended value." echo "See test_random.fasta for the used sequences." echo "./test/test_fasta -s $SEED -l $LENGTH -d $dist" head -n 1 ./test/test_random.fasta exit 1; fi done # raw for n in $(seq 10) do if test $SEED -ne 0; then SEED=$((SEED + 1)) fi res=$(./test/test_fasta -r -s $SEED -l $LENGTH -d $dist | tee ./test/test_random.fasta | ./src/andi -m RAW -t 1 | tail -n 1 | awk -v dist=$dist '{print $2, dist}' | awk 'function abs(x){return ((x < 0.0) ? -x : x)} {print abs($1-$2) <= 0.055 && abs($1-$2) <= 0.055 * $2}') if test $res -ne 1; then echo "The last test computed a distance deviating more than five percent from its intended value." echo "See test_random.fasta for the used sequences." echo "./test/test_fasta -r -s $SEED -l $LENGTH -d $dist" head -n 1 ./test/test_random.fasta exit 1; fi done done rm ./test/test_random.fasta andi-0.14/test/test_seq.c000066400000000000000000000033321415070357400153320ustar00rootroot00000000000000#include #include "global.h" #include #include #include "sequence.h" double ANCHOR_P_VALUE = 0.025; int FLAGS = F_NONE; void test_seq_basic(){ seq_t S; seq_init( &S, "ACGT", "name"); g_assert_cmpstr(S.S, ==, "ACGT"); g_assert_cmpstr(S.name, ==, "name"); g_assert_cmpuint(S.len, ==, 4); seq_free( &S); } void test_seq_full(){ seq_t S; seq_subject subject; seq_init( &S, "ACGTTGCA", "name"); int check = seq_subject_init( &subject, &S); g_assert_cmpint(check, ==, 0); g_assert_cmpstr(subject.RS, ==, "TGCAACGT#ACGTTGCA"); g_assert_cmpuint(subject.RSlen, ==, 8*2+1); g_assert( subject.gc == 0.5); seq_subject_free( &subject); seq_free( &S); } void test_seq_nonacgt(){ seq_t S; seq_subject subject; seq_init( &S, "11ACGTNN7682394689NNTGCA11", "name"); seq_subject_init( &subject, &S); g_assert_cmpstr(S.S, ==, "ACGTTGCA"); g_assert_cmpuint(S.len, ==, 8 ); g_assert( FLAGS & F_NON_ACGT); g_assert_cmpstr(subject.RS, ==, "TGCAACGT#ACGTTGCA"); g_assert_cmpuint(subject.RSlen, ==, 8*2+1); g_assert( subject.gc == 0.5); seq_subject_free( &subject); seq_free( &S); FLAGS = F_NONE; seq_init( &S, "@ACGT_!0TGCA ", "name"); seq_subject_init( &subject, &S); g_assert_cmpstr(S.S, ==, "ACGT!TGCA"); g_assert_cmpuint(S.len, ==, 9 ); g_assert( FLAGS & F_NON_ACGT); g_assert_cmpstr(subject.RS, ==, "TGCA;ACGT#ACGT!TGCA"); g_assert_cmpuint(subject.RSlen, ==, 9*2+1); seq_subject_free( &subject); seq_free( &S); FLAGS = F_NONE; } int main(int argc, char *argv[]) { g_test_init( &argc, &argv, NULL); g_test_add_func("/seq/basic", test_seq_basic); g_test_add_func("/seq/full", test_seq_full); g_test_add_func("/seq/non acgt", test_seq_nonacgt); return g_test_run(); }