sumaclust_v1.0.10/000777 000765 000024 00000000000 12560645264 016050 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/._global.mk000644 000765 000024 00000000253 12551722535 020047 0ustar00celinemercierstaff000000 000000 Mac OS X  2y«TEXTATTR«œœcom.apple.TextEncodingUTF-8;134217984sumaclust_v1.0.10/global.mk000644 000765 000024 00000001425 12551722535 017634 0ustar00celinemercierstaff000000 000000 LIBFASTAPATH = -L./sumalibs/libfasta LIBLCSPATH = -L./sumalibs/liblcs LIBFILEPATH = -L./sumalibs/libfile LIBUTILSPATH = -L./sumalibs/libutils LIBFASTA = ./sumalibs/libfasta/libfasta.a LIBLCS = ./sumalibs/liblcs/liblcs.a LIBFILE = ./sumalibs/libfile/libfile.a LIBUTILS = ./sumalibs/libutils/libutils.a CC=gcc LDFLAGS= ifeq ($(CC),gcc) CFLAGS = -O3 -s -DOMP_SUPPORT -fopenmp -w else CFLAGS = -O3 -w endif default: all %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< $(LIB) ######## # # libraries compilation # ######## ./sumalibs/libfasta/libfasta.a: $(MAKE) -C ./sumalibs/libfasta ./sumalibs/liblcs/liblcs.a: $(MAKE) -C ./sumalibs/liblcs ./sumalibs/libfile/libfile.a: $(MAKE) -C ./sumalibs/libfile ./sumalibs/libutils/libutils.a: $(MAKE) -C ./sumalibs/libutilssumaclust_v1.0.10/Licence_CeCILL_V2-en.txt000644 000765 000024 00000051151 12551664362 022174 0ustar00celinemercierstaff000000 000000 CeCILL FREE SOFTWARE LICENSE AGREEMENT Notice This Agreement is a Free Software license agreement that is the result of discussions between its authors in order to ensure compliance with the two main principles guiding its drafting: * firstly, compliance with the principles governing the distribution of Free Software: access to source code, broad rights granted to users, * secondly, the election of a governing law, French law, with which it is conformant, both as regards the law of torts and intellectual property law, and the protection that it offers to both authors and holders of the economic rights over software. The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) license are: Commissariat à l'Energie Atomique - CEA, a public scientific, technical and industrial research establishment, having its principal place of business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. Centre National de la Recherche Scientifique - CNRS, a public scientific and technological establishment, having its principal place of business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. Institut National de Recherche en Informatique et en Automatique - INRIA, a public scientific and technological establishment, having its principal place of business at Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex, France. Preamble The purpose of this Free Software license agreement is to grant users the right to modify and redistribute the software governed by this license within the framework of an open source distribution model. The exercising of these rights is conditional upon certain obligations for users so as to preserve this status for all subsequent redistributions. In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. In this respect, the risks associated with loading, using, modifying and/or developing or reproducing the software by the user are brought to the user's attention, given its Free Software status, which may make it complicated to use, with the result that its use is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the suitability of the software as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions of security. This Agreement may be freely reproduced and published, provided it is not altered, and that no provisions are either added or removed herefrom. This Agreement may apply to any or all software for which the holder of the economic rights decides to submit the use thereof to its provisions. Article 1 - DEFINITIONS For the purpose of this Agreement, when the following expressions commence with a capital letter, they shall have the following meaning: Agreement: means this license agreement, and its possible subsequent versions and annexes. Software: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. Initial Software: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. Modified Software: means the Software modified by at least one Contribution. Source Code: means all the Software's instructions and program lines to which access is required so as to modify the Software. Object Code: means the binary files originating from the compilation of the Source Code. Holder: means the holder(s) of the economic rights over the Initial Software. Licensee: means the Software user(s) having accepted the Agreement. Contributor: means a Licensee having made at least one Contribution. Licensor: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. Contribution: means any or all modifications, corrections, translations, adaptations and/or new functions integrated into the Software by any or all Contributors, as well as any or all Internal Modules. Module: means a set of sources files including their documentation that enables supplementary functions or services in addition to those offered by the Software. External Module: means any or all Modules, not derived from the Software, so that this Module and the Software run in separate address spaces, with one calling the other when they are run. Internal Module: means any or all Module, connected to the Software so that they both execute in the same address space. GNU GPL: means the GNU General Public License version 2 or any subsequent version, as published by the Free Software Foundation Inc. Parties: mean both the Licensee and the Licensor. These expressions may be used both in singular and plural form. Article 2 - PURPOSE The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. Article 3 - ACCEPTANCE 3.1 The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: * (i) loading the Software by any or all means, notably, by downloading from a remote server, or by loading from a physical medium; * (ii) the first time the Licensee exercises any of the rights granted hereunder. 3.2 One copy of the Agreement, containing a notice relating to the characteristics of the Software, to the limited warranty, and to the fact that its use is restricted to experienced users has been provided to the Licensee prior to its acceptance as set forth in Article 3.1 hereinabove, and the Licensee hereby acknowledges that it has read and understood it. Article 4 - EFFECTIVE DATE AND TERM 4.1 EFFECTIVE DATE The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3.1. 4.2 TERM The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. Article 5 - SCOPE OF RIGHTS GRANTED The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for any or all use, and for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. Besides, if the Licensor owns or comes to own one or more patents protecting all or part of the functions of the Software or of its components, the Licensor undertakes not to enforce the rights granted by these patents against successive Licensees using, exploiting or modifying the Software. If these patents are transferred, the Licensor undertakes to have the transferees subscribe to the obligations set forth in this paragraph. 5.1 RIGHT OF USE The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: 1. permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. 2. loading, displaying, running, or storing the Software on any or all medium. 3. entitlement to observe, study or test its operation so as to determine the ideas and principles behind any or all constituent elements of said Software. This shall apply when the Licensee carries out any or all loading, displaying, running, transmission or storage operation as regards the Software, that it is entitled to carry out hereunder. 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS The right to make Contributions includes the right to translate, adapt, arrange, or make any or all modifications to the Software, and the right to reproduce the resulting software. The Licensee is authorized to make any or all Contributions to the Software provided that it includes an explicit notice that it is the author of said Contribution and indicates the date of the creation thereof. 5.3 RIGHT OF DISTRIBUTION In particular, the right of distribution includes the right to publish, transmit and communicate the Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or free of charge, one or more copies of the Software by any means. The Licensee is further authorized to distribute copies of the modified or unmodified Software to third parties according to the terms and conditions set forth hereinafter. 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION The Licensee is authorized to distribute true copies of the Software in Source Code or Object Code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the Object Code of the Software is redistributed, the Licensee allows future Licensees unhindered access to the full Source Code of the Software by indicating how to access it, it being understood that the additional cost of acquiring the Source Code shall not exceed the cost of transferring the data. 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE When the Licensee makes a Contribution to the Software, the terms and conditions for the distribution of the resulting Modified Software become subject to all the provisions of this Agreement. The Licensee is authorized to distribute the Modified Software, in source code or object code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the object code of the Modified Software is redistributed, the Licensee allows future Licensees unhindered access to the full source code of the Modified Software by indicating how to access it, it being understood that the additional cost of acquiring the source code shall not exceed the cost of transferring the data. 5.3.3 DISTRIBUTION OF EXTERNAL MODULES When the Licensee has developed an External Module, the terms and conditions of this Agreement do not apply to said External Module, that may be distributed under a separate license agreement. 5.3.4 COMPATIBILITY WITH THE GNU GPL The Licensee can include a code that is subject to the provisions of one of the versions of the GNU GPL in the Modified or unmodified Software, and distribute that entire code under the terms of the same version of the GNU GPL. The Licensee can include the Modified or unmodified Software in a code that is subject to the provisions of one of the versions of the GNU GPL, and distribute that entire code under the terms of the same version of the GNU GPL. Article 6 - INTELLECTUAL PROPERTY 6.1 OVER THE INITIAL SOFTWARE The Holder owns the economic rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. The Holder undertakes that the Initial Software will remain ruled at least by this Agreement, for the duration set forth in Article 4.2. 6.2 OVER THE CONTRIBUTIONS The Licensee who develops a Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. 6.3 OVER THE EXTERNAL MODULES The Licensee who develops an External Module is the owner of the intellectual property rights over this External Module as defined by applicable law and is free to choose the type of agreement that shall govern its distribution. 6.4 JOINT PROVISIONS The Licensee expressly undertakes: 1. not to remove, or modify, in any manner, the intellectual property notices attached to the Software; 2. to reproduce said notices, in an identical manner, in the copies of the Software modified or not. The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder and/or Contributors on the Software and to take, where applicable, vis-à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder and/or Contributors. Article 7 - RELATED SERVICES 7.1 Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. Only the Licensor offering said maintenance and/or technical assistance services shall incur liability therefor. 7.2 Similarly, any Licensor is entitled to offer to its licensees, under its sole responsibility, a warranty, that shall only be binding upon itself, for the redistribution of the Software and/or the Modified Software, under terms and conditions that it is free to decide. Said warranty, and the financial terms and conditions of its application, shall be subject of a separate instrument executed between the Licensor and the Licensee. Article 8 - LIABILITY 8.1 Subject to the provisions of Article 8.2, the Licensee shall be entitled to claim compensation for any direct loss it may have suffered from the Software as a result of a fault on the part of the relevant Licensor, subject to providing evidence thereof. 8.2 The Licensor's liability is limited to the commitments made under this Agreement and shall not be incurred as a result of in particular: (i) loss due the Licensee's total or partial failure to fulfill its obligations, (ii) direct or consequential loss that is suffered by the Licensee due to the use or performance of the Software, and (iii) more generally, any consequential loss. In particular the Parties expressly agree that any or all pecuniary or business loss (i.e. loss of data, loss of profits, operating loss, loss of customers or orders, opportunity cost, any disturbance to business activities) or any or all legal proceedings instituted against the Licensee by a third party, shall constitute consequential loss and shall not provide entitlement to any or all compensation from the Licensor. Article 9 - WARRANTY 9.1 The Licensee acknowledges that the scientific and technical state-of-the-art when the Software was distributed did not enable all possible uses to be tested and verified, nor for the presence of possible defects to be detected. In this respect, the Licensee's attention has been drawn to the risks associated with loading, using, modifying and/or developing and reproducing the Software which are reserved for experienced users. The Licensee shall be responsible for verifying, by any or all means, the suitability of the product for its requirements, its good working order, and for ensuring that it shall not cause damage to either persons or properties. 9.2 The Licensor hereby represents, in good faith, that it is entitled to grant all the rights over the Software (including in particular the rights set forth in Article 5). 9.3 The Licensee acknowledges that the Software is supplied "as is" by the Licensor without any other express or tacit warranty, other than that provided for in Article 9.2 and, in particular, without any warranty as to its commercial value, its secured, safe, innovative or relevant nature. Specifically, the Licensor does not warrant that the Software is free from any error, that it will operate without interruption, that it will be compatible with the Licensee's own equipment and software configuration, nor that it will meet the Licensee's requirements. 9.4 The Licensor does not either expressly or tacitly warrant that the Software does not infringe any third party intellectual property right relating to a patent, software or any other property right. Therefore, the Licensor disclaims any and all liability towards the Licensee arising out of any or all proceedings for infringement that may be instituted in respect of the use, modification and redistribution of the Software. Nevertheless, should such proceedings be instituted against the Licensee, the Licensor shall provide it with technical and legal assistance for its defense. Such technical and legal assistance shall be decided on a case-by-case basis between the relevant Licensor and the Licensee pursuant to a memorandum of understanding. The Licensor disclaims any and all liability as regards the Licensee's use of the name of the Software. No warranty is given as regards the existence of prior rights over the name of the Software or as regards the existence of a trademark. Article 10 - TERMINATION 10.1 In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. 10.2 A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. Article 11 - MISCELLANEOUS 11.1 EXCUSABLE EVENTS Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. 11.2 Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. 11.3 The Agreement cancels and replaces any or all previous agreements, whether written or oral, between the Parties and having the same purpose, and constitutes the entirety of the agreement between said Parties concerning said purpose. No supplement or modification to the terms and conditions hereof shall be effective as between the Parties unless it is made in writing and signed by their duly authorized representatives. 11.4 In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. 11.5 LANGUAGE The Agreement is drafted in both French and English and both versions are deemed authentic. Article 12 - NEW VERSIONS OF THE AGREEMENT 12.1 Any person is authorized to duplicate and distribute copies of this Agreement. 12.2 So as to ensure coherence, the wording of this Agreement is protected and may only be modified by the authors of the License, who reserve the right to periodically publish updates or new versions of the Agreement, each with a separate number. These subsequent versions may address new issues encountered by Free Software. 12.3 Any Software distributed under a given version of the Agreement may only be subsequently distributed under the same version of the Agreement or a subsequent version, subject to the provisions of Article 5.3.4. Article 13 - GOVERNING LAW AND JURISDICTION 13.1 The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. 13.2 Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Paris Courts having jurisdiction, by the more diligent Party. Version 2.0 dated 2006-09-05. sumaclust_v1.0.10/Licence_CeCILL_V2-fr.txt000644 000765 000024 00000051733 12551664362 022207 0ustar00celinemercierstaff000000 000000 CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL Avertissement Ce contrat est une licence de logiciel libre issue d'une concertation entre ses auteurs afin que le respect de deux grands principes préside à sa rédaction: * d'une part, le respect des principes de diffusion des logiciels libres: accès au code source, droits étendus conférés aux utilisateurs, * d'autre part, la désignation d'un droit applicable, le droit français, auquel elle est conforme, tant au regard du droit de la responsabilité civile que du droit de la propriété intellectuelle et de la protection qu'il offre aux auteurs et titulaires des droits patrimoniaux sur un logiciel. Les auteurs de la licence CeCILL (pour Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) sont: Commissariat à l'Energie Atomique - CEA, établissement public de recherche à caractère scientifique, technique et industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris. Centre National de la Recherche Scientifique - CNRS, établissement public à caractère scientifique et technologique, dont le siège est situé 3 rue Michel-Ange, 75794 Paris cedex 16. Institut National de Recherche en Informatique et en Automatique - INRIA, établissement public à caractère scientifique et technologique, dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex. Préambule Ce contrat est une licence de logiciel libre dont l'objectif est de conférer aux utilisateurs la liberté de modification et de redistribution du logiciel régi par cette licence dans le cadre d'un modèle de diffusion en logiciel libre. L'exercice de ces libertés est assorti de certains devoirs à la charge des utilisateurs afin de préserver ce statut au cours des redistributions ultérieures. L'accessibilité au code source et les droits de copie, de modification et de redistribution qui en découlent ont pour contrepartie de n'offrir aux utilisateurs qu'une garantie limitée et de ne faire peser sur l'auteur du logiciel, le titulaire des droits patrimoniaux et les concédants successifs qu'une responsabilité restreinte. A cet égard l'attention de l'utilisateur est attirée sur les risques associés au chargement, à l'utilisation, à la modification et/ou au développement et à la reproduction du logiciel par l'utilisateur étant donné sa spécificité de logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve donc à des développeurs ou des professionnels avertis possédant des connaissances informatiques approfondies. Les utilisateurs sont donc invités à charger et tester l'adéquation du logiciel à leurs besoins dans des conditions permettant d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus généralement, à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. Ce contrat peut être reproduit et diffusé librement, sous réserve de le conserver en l'état, sans ajout ni suppression de clauses. Ce contrat est susceptible de s'appliquer à tout logiciel dont le titulaire des droits patrimoniaux décide de soumettre l'exploitation aux dispositions qu'il contient. Article 1 - DEFINITIONS Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une lettre capitale, auront la signification suivante: Contrat: désigne le présent contrat de licence, ses éventuelles versions postérieures et annexes. Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code Source et le cas échéant sa documentation, dans leur état au moment de l'acceptation du Contrat par le Licencié. Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et éventuellement de Code Objet et le cas échéant sa documentation, dans leur état au moment de leur première diffusion sous les termes du Contrat. Logiciel Modifié: désigne le Logiciel modifié par au moins une Contribution. Code Source: désigne l'ensemble des instructions et des lignes de programme du Logiciel et auquel l'accès est nécessaire en vue de modifier le Logiciel. Code Objet: désigne les fichiers binaires issus de la compilation du Code Source. Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur sur le Logiciel Initial. Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le Contrat. Contributeur: désigne le Licencié auteur d'au moins une Contribution. Concédant: désigne le Titulaire ou toute personne physique ou morale distribuant le Logiciel sous le Contrat. Contribution: désigne l'ensemble des modifications, corrections, traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans le Logiciel par tout Contributeur, ainsi que tout Module Interne. Module: désigne un ensemble de fichiers sources y compris leur documentation qui permet de réaliser des fonctionnalités ou services supplémentaires à ceux fournis par le Logiciel. Module Externe: désigne tout Module, non dérivé du Logiciel, tel que ce Module et le Logiciel s'exécutent dans des espaces d'adressage différents, l'un appelant l'autre au moment de leur exécution. Module Interne: désigne tout Module lié au Logiciel de telle sorte qu'ils s'exécutent dans le même espace d'adressage. GNU GPL: désigne la GNU General Public License dans sa version 2 ou toute version ultérieure, telle que publiée par Free Software Foundation Inc. Parties: désigne collectivement le Licencié et le Concédant. Ces termes s'entendent au singulier comme au pluriel. Article 2 - OBJET Le Contrat a pour objet la concession par le Concédant au Licencié d'une licence non exclusive, cessible et mondiale du Logiciel telle que définie ci-après à l'article 5 pour toute la durée de protection des droits portant sur ce Logiciel. Article 3 - ACCEPTATION 3.1 L'acceptation par le Licencié des termes du Contrat est réputée acquise du fait du premier des faits suivants: * (i) le chargement du Logiciel par tout moyen notamment par téléchargement à partir d'un serveur distant ou par chargement à partir d'un support physique; * (ii) le premier exercice par le Licencié de l'un quelconque des droits concédés par le Contrat. 3.2 Un exemplaire du Contrat, contenant notamment un avertissement relatif aux spécificités du Logiciel, à la restriction de garantie et à la limitation à un usage par des utilisateurs expérimentés a été mis à disposition du Licencié préalablement à son acceptation telle que définie à l'article 3.1 ci dessus et le Licencié reconnaît en avoir pris connaissance. Article 4 - ENTREE EN VIGUEUR ET DUREE 4.1 ENTREE EN VIGUEUR Le Contrat entre en vigueur à la date de son acceptation par le Licencié telle que définie en 3.1. 4.2 DUREE Le Contrat produira ses effets pendant toute la durée légale de protection des droits patrimoniaux portant sur le Logiciel. Article 5 - ETENDUE DES DROITS CONCEDES Le Concédant concède au Licencié, qui accepte, les droits suivants sur le Logiciel pour toutes destinations et pour la durée du Contrat dans les conditions ci-après détaillées. Par ailleurs, si le Concédant détient ou venait à détenir un ou plusieurs brevets d'invention protégeant tout ou partie des fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas opposer les éventuels droits conférés par ces brevets aux Licenciés successifs qui utiliseraient, exploiteraient ou modifieraient le Logiciel. En cas de cession de ces brevets, le Concédant s'engage à faire reprendre les obligations du présent alinéa aux cessionnaires. 5.1 DROIT D'UTILISATION Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant aux domaines d'application, étant ci-après précisé que cela comporte: 1. la reproduction permanente ou provisoire du Logiciel en tout ou partie par tout moyen et sous toute forme. 2. le chargement, l'affichage, l'exécution, ou le stockage du Logiciel sur tout support. 3. la possibilité d'en observer, d'en étudier, ou d'en tester le fonctionnement afin de déterminer les idées et principes qui sont à la base de n'importe quel élément de ce Logiciel; et ceci, lorsque le Licencié effectue toute opération de chargement, d'affichage, d'exécution, de transmission ou de stockage du Logiciel qu'il est en droit d'effectuer en vertu du Contrat. 5.2 DROIT D'APPORTER DES CONTRIBUTIONS Le droit d'apporter des Contributions comporte le droit de traduire, d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel et le droit de reproduire le logiciel en résultant. Le Licencié est autorisé à apporter toute Contribution au Logiciel sous réserve de mentionner, de façon explicite, son nom en tant qu'auteur de cette Contribution et la date de création de celle-ci. 5.3 DROIT DE DISTRIBUTION Le droit de distribution comporte notamment le droit de diffuser, de transmettre et de communiquer le Logiciel au public sur tout support et par tout moyen ainsi que le droit de mettre sur le marché à titre onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé. Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou non, à des tiers dans les conditions ci-après détaillées. 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION Le Licencié est autorisé à distribuer des copies conformes du Logiciel, sous forme de Code Source ou de Code Objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le Code Objet du Logiciel est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au Code Source complet du Logiciel en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du Code Source ne devra pas excéder le simple coût de transfert des données. 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE Lorsque le Licencié apporte une Contribution au Logiciel, les conditions de distribution du Logiciel Modifié en résultant sont alors soumises à l'intégralité des dispositions du Contrat. Le Licencié est autorisé à distribuer le Logiciel Modifié, sous forme de code source ou de code objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le code objet du Logiciel Modifié est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au code source complet du Logiciel Modifié en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du code source ne devra pas excéder le simple coût de transfert des données. 5.3.3 DISTRIBUTION DES MODULES EXTERNES Lorsque le Licencié a développé un Module Externe les conditions du Contrat ne s'appliquent pas à ce Module Externe, qui peut être distribué sous un contrat de licence différent. 5.3.4 COMPATIBILITE AVEC LA LICENCE GNU GPL Le Licencié peut inclure un code soumis aux dispositions d'une des versions de la licence GNU GPL dans le Logiciel modifié ou non et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Le Licencié peut inclure le Logiciel modifié ou non dans un code soumis aux dispositions d'une des versions de la licence GNU GPL et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Article 6 - PROPRIETE INTELLECTUELLE 6.1 SUR LE LOGICIEL INITIAL Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel Initial. Toute utilisation du Logiciel Initial est soumise au respect des conditions dans lesquelles le Titulaire a choisi de diffuser son oeuvre et nul autre n'a la faculté de modifier les conditions de diffusion de ce Logiciel Initial. Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi par le Contrat et ce, pour la durée visée à l'article 4.2. 6.2 SUR LES CONTRIBUTIONS Le Licencié qui a développé une Contribution est titulaire sur celle-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable. 6.3 SUR LES MODULES EXTERNES Le Licencié qui a développé un Module Externe est titulaire sur celui-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable et reste libre du choix du contrat régissant sa diffusion. 6.4 DISPOSITIONS COMMUNES Le Licencié s'engage expressément: 1. à ne pas supprimer ou modifier de quelque manière que ce soit les mentions de propriété intellectuelle apposées sur le Logiciel; 2. à reproduire à l'identique lesdites mentions de propriété intellectuelle sur les copies du Logiciel modifié ou non. Le Licencié s'engage à ne pas porter atteinte, directement ou indirectement, aux droits de propriété intellectuelle du Titulaire et/ou des Contributeurs sur le Logiciel et à prendre, le cas échéant, à l'égard de son personnel toutes les mesures nécessaires pour assurer le respect des dits droits de propriété intellectuelle du Titulaire et/ou des Contributeurs. Article 7 - SERVICES ASSOCIES 7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de prestations d'assistance technique ou de maintenance du Logiciel. Cependant le Concédant reste libre de proposer ce type de services. Les termes et conditions d'une telle assistance technique et/ou d'une telle maintenance seront alors déterminés dans un acte séparé. Ces actes de maintenance et/ou assistance technique n'engageront que la seule responsabilité du Concédant qui les propose. 7.2 De même, tout Concédant est libre de proposer, sous sa seule responsabilité, à ses licenciés une garantie, qui n'engagera que lui, lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce, dans les conditions qu'il souhaite. Cette garantie et les modalités financières de son application feront l'objet d'un acte séparé entre le Concédant et le Licencié. Article 8 - RESPONSABILITE 8.1 Sous réserve des dispositions de l'article 8.2, le Licencié a la faculté, sous réserve de prouver la faute du Concédant concerné, de solliciter la réparation du préjudice direct qu'il subirait du fait du Logiciel et dont il apportera la preuve. 8.2 La responsabilité du Concédant est limitée aux engagements pris en application du Contrat et ne saurait être engagée en raison notamment: (i) des dommages dus à l'inexécution, totale ou partielle, de ses obligations par le Licencié, (ii) des dommages directs ou indirects découlant de l'utilisation ou des performances du Logiciel subis par le Licencié et (iii) plus généralement d'un quelconque dommage indirect. En particulier, les Parties conviennent expressément que tout préjudice financier ou commercial (par exemple perte de données, perte de bénéfices, perte d'exploitation, perte de clientèle ou de commandes, manque à gagner, trouble commercial quelconque) ou toute action dirigée contre le Licencié par un tiers, constitue un dommage indirect et n'ouvre pas droit à réparation par le Concédant. Article 9 - GARANTIE 9.1 Le Licencié reconnaît que l'état actuel des connaissances scientifiques et techniques au moment de la mise en circulation du Logiciel ne permet pas d'en tester et d'en vérifier toutes les utilisations ni de détecter l'existence d'éventuels défauts. L'attention du Licencié a été attirée sur ce point sur les risques associés au chargement, à l'utilisation, la modification et/ou au développement et à la reproduction du Logiciel qui sont réservés à des utilisateurs avertis. Il relève de la responsabilité du Licencié de contrôler, par tous moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. 9.2 Le Concédant déclare de bonne foi être en droit de concéder l'ensemble des droits attachés au Logiciel (comprenant notamment les droits visés à l'article 5). 9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le Concédant sans autre garantie, expresse ou tacite, que celle prévue à l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, son caractère sécurisé, innovant ou pertinent. En particulier, le Concédant ne garantit pas que le Logiciel est exempt d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible avec l'équipement du Licencié et sa configuration logicielle ni qu'il remplira les besoins du Licencié. 9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le Logiciel ne porte pas atteinte à un quelconque droit de propriété intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout autre droit de propriété. Ainsi, le Concédant exclut toute garantie au profit du Licencié contre les actions en contrefaçon qui pourraient être diligentées au titre de l'utilisation, de la modification, et de la redistribution du Logiciel. Néanmoins, si de telles actions sont exercées contre le Licencié, le Concédant lui apportera son aide technique et juridique pour sa défense. Cette aide technique et juridique est déterminée au cas par cas entre le Concédant concerné et le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage toute responsabilité quant à l'utilisation de la dénomination du Logiciel par le Licencié. Aucune garantie n'est apportée quant à l'existence de droits antérieurs sur le nom du Logiciel et sur l'existence d'une marque. Article 10 - RESILIATION 10.1 En cas de manquement par le Licencié aux obligations mises à sa charge par le Contrat, le Concédant pourra résilier de plein droit le Contrat trente (30) jours après notification adressée au Licencié et restée sans effet. 10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé à utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les licences qu'il aura concédées antérieurement à la résiliation du Contrat resteront valides sous réserve qu'elles aient été effectuées en conformité avec le Contrat. Article 11 - DISPOSITIONS DIVERSES 11.1 CAUSE EXTERIEURE Aucune des Parties ne sera responsable d'un retard ou d'une défaillance d'exécution du Contrat qui serait dû à un cas de force majeure, un cas fortuit ou une cause extérieure, telle que, notamment, le mauvais fonctionnement ou les interruptions du réseau électrique ou de télécommunication, la paralysie du réseau liée à une attaque informatique, l'intervention des autorités gouvernementales, les catastrophes naturelles, les dégâts des eaux, les tremblements de terre, le feu, les explosions, les grèves et les conflits sociaux, l'état de guerre... 11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer renonciation par la Partie intéressée à s'en prévaloir ultérieurement. 11.3 Le Contrat annule et remplace toute convention antérieure, écrite ou orale, entre les Parties sur le même objet et constitue l'accord entier entre les Parties sur cet objet. Aucune addition ou modification aux termes du Contrat n'aura d'effet à l'égard des Parties à moins d'être faite par écrit et signée par leurs représentants dûment habilités. 11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat s'avèrerait contraire à une loi ou à un texte applicable, existants ou futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les amendements nécessaires pour se conformer à cette loi ou à ce texte. Toutes les autres dispositions resteront en vigueur. De même, la nullité, pour quelque raison que ce soit, d'une des dispositions du Contrat ne saurait entraîner la nullité de l'ensemble du Contrat. 11.5 LANGUE Le Contrat est rédigé en langue française et en langue anglaise, ces deux versions faisant également foi. Article 12 - NOUVELLES VERSIONS DU CONTRAT 12.1 Toute personne est autorisée à copier et distribuer des copies de ce Contrat. 12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé et ne peut être modifié que par les auteurs de la licence, lesquels se réservent le droit de publier périodiquement des mises à jour ou de nouvelles versions du Contrat, qui posséderont chacune un numéro distinct. Ces versions ultérieures seront susceptibles de prendre en compte de nouvelles problématiques rencontrées par les logiciels libres. 12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra faire l'objet d'une diffusion ultérieure que sous la même version du Contrat ou une version postérieure, sous réserve des dispositions de l'article 5.3.4. Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE 13.1 Le Contrat est régi par la loi française. Les Parties conviennent de tenter de régler à l'amiable les différends ou litiges qui viendraient à se produire par suite ou à l'occasion du Contrat. 13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter de leur survenance et sauf situation relevant d'une procédure d'urgence, les différends ou litiges seront portés par la Partie la plus diligente devant les Tribunaux compétents de Paris. Version 2.0 du 2006-09-05. sumaclust_v1.0.10/Makefile000666 000765 000024 00000001520 12551722704 017501 0ustar00celinemercierstaff000000 000000 EXEC=sumaclust SUMACLUST_SRC= sumaclust.c \ mtcompare_sumaclust.c SUMACLUST_OBJ= $(patsubst %.c,%.o,$(SUMACLUST_SRC)) SRCS= $(SUMACLUST_SRC) LIB= -lfasta -llcs -lfile -lutils -lm #-ll include ./global.mk all: $(EXEC) ######## # # sumaclust compilation # ######## # executable compilation and link ifeq ($(CC),gcc) LFLAGS = -fopenmp else LFLAGS = endif sumaclust: $(SUMACLUST_OBJ) $(LIBFASTA) $(LIBLCS) $(LIBFILE) $(LIBUTILS) $(CC) $(LDFLAGS) -o $@ $(LFLAGS) $(SUMACLUST_OBJ) $(LIB) $(LIBFASTAPATH) $(LIBLCSPATH) $(LIBFILEPATH) $(LIBUTILSPATH) ######## # # project management # ######## clean: rm -f *.o rm -f *.P rm -f $(EXEC) $(MAKE) -C ./sumalibs/libfasta clean $(MAKE) -C ./sumalibs/liblcs clean $(MAKE) -C ./sumalibs/libfile clean $(MAKE) -C ./sumalibs/libutils clean sumaclust_v1.0.10/mtcompare_sumaclust.c000666 000765 000024 00000021560 12551723142 022277 0ustar00celinemercierstaff000000 000000 /* * mtcompare_cumaclust.c * * Author: Celine Mercier * */ #ifdef OMP_SUPPORT #include #endif #include #include #include #include #include "./sumalibs/libfasta/sequence.h" #include "./sumalibs/libutils/utilities.h" #include "./sumalibs/liblcs/upperband.h" #include "./sumalibs/liblcs/sse_banded_LCS_alignment.h" #include "sumaclust.h" static double computeScore(void* c, int32_t seed_number, int32_t i, int thread_number,int32_t maxcount) { thread_control_t *control=(thread_control_t*)c; fastaSeqPtr* db = control->db; fastaSeqPtr db_i = db[i]; fastaSeqPtr db_seed_number = db[seed_number]; int LCSmin; double score; score = control->worstscore; if (db_i->count <= maxcount) filters(db_i, db_seed_number, control->threshold, control->normalize, control->reference, control->lcsmode, &score, &LCSmin); if (score == -1.0) score = alignForSumathings(db_seed_number->sequence, control->iseqs1[thread_number], db_i->sequence, control->iseqs2[thread_number], db_seed_number->length, db_i->length, control->normalize, control->reference, control->lcsmode, control->addresses[thread_number], control->sizeForSeqs, LCSmin); return score; } inline void putSeqInClusterMT(void *c, int32_t center_idx, int32_t seq, double score) { // saves a sequence as belonging to a cluster and its score with the seed thread_control_t *control=(thread_control_t*)c; fastaSeqPtr* db = control->db; fastaSeqPtr pseq = db[seq]; pseq->center = db+center_idx; pseq->center_index = center_idx; // saves cluster pseq->score = score; // saves score with the seed pseq->cluster_center = FALSE; } int64_t timevaldiff(struct timeval *starttime, struct timeval *finishtime) { int64_t msec; msec=(finishtime->tv_sec-starttime->tv_sec)*1000000; msec+=(finishtime->tv_usec-starttime->tv_usec)/1000000; return msec; } void computeOneSeed(void* c) { thread_control_t *control=(thread_control_t*)c; BOOL found; int32_t seed_number; int32_t nextone=control->n; int64_t elapsedtime; struct timeval current; struct timeval start; seed_number = control->next; found = FALSE; //printf("\n seed = %d, n = %d", seed_number, control->n); #ifdef OMP_SUPPORT omp_set_num_threads(control->threads_number); #endif gettimeofday(&start,NULL); #ifdef OMP_SUPPORT #pragma omp parallel default(none) \ firstprivate(found) \ firstprivate(seed_number) \ firstprivate(control) \ shared(nextone) #endif { int32_t i; double score; int32_t current_seed; #ifdef OMP_SUPPORT int thread_id=omp_get_thread_num(); #else int thread_id=0; #endif int nseq = control->n; BOOL fast = control->fast; BOOL lcsmode = control->lcsmode; int normalize = control->normalize; double threshold = control->threshold; BOOL first = TRUE; BOOL not_already_in_a_cluster; BOOL threshold_bad; int32_t priv_nextone=control->n; int32_t maxcount = (double)(control->db[seed_number]->count) * control->max_ratio; fastaSeqPtr* db = control->db; #ifdef OMP_SUPPORT #pragma omp for schedule(dynamic,10) #endif for (i=seed_number+1; \ i < nseq; \ i++) { current_seed = db[i]->center_index; not_already_in_a_cluster = current_seed == i; // At the beginning all the sequences are their own center if ((! fast) || not_already_in_a_cluster) { score = computeScore((void*)control, seed_number, i, thread_id,maxcount); // computes LCS score or 0 if k-mer filter not passed if (lcsmode || normalize) threshold_bad = (score < threshold); else threshold_bad = (score > threshold); if (threshold_bad) // similarity under threshold { if (!found && not_already_in_a_cluster && (i < priv_nextone)) { priv_nextone=i; // saves potential next seed // *potential_nexts_list = i; found = TRUE; // saves the fact that a next seed // has been found for this thread } } else if (not_already_in_a_cluster || \ ((! fast) && \ (db[i]->score < score))) { // if seq matching with current seed : // clustering with seed if seq doesn't belong to any cluster yet // OR in exact mode and the score is better with this seed if (! lcsmode && normalize) score = 1.0 - score; putSeqInClusterMT((void*)control, seed_number, i, score); // saves new seed for this seq } } // if ((! fast) || on_current_seed) } // for (i=seed_number+1;... #ifdef OMP_SUPPORT #pragma omp flush(nextone) #endif if (priv_nextone < nextone) #ifdef OMP_SUPPORT #pragma omp critical #endif if (priv_nextone < nextone) nextone=priv_nextone; } gettimeofday(¤t,NULL); elapsedtime = timevaldiff(&start,¤t); control->elapsedtime+=elapsedtime; control->next=nextone; if (control->next < (control->n)-1) (control->seeds_counter)++; else if (control->next == (control->n)-1) { control->stop = TRUE; (control->seeds_counter)++; } else if (control->next == control->n) control->stop = TRUE; } void initializeCentersAndScores(void *c) { // Initializing the scores table for each seq : thread_control_t *control = (thread_control_t*) c; int32_t i; fastaSeqPtr *db_i; int scoremax; if (control->normalize && control->lcsmode) scoremax = 1.0; else if (!control->lcsmode) scoremax = 0.0; else scoremax = (*(control->db))->length; for (i=0, db_i = control->db; i <= control->n-1; i++,db_i++) { (*db_i)->center = (control->db)+i; (*db_i)->center_index = i; (*db_i)->score = scoremax; (*db_i)->cluster_center = TRUE; } } void freeEverything(void *c) { thread_control_t *control=(thread_control_t*)c; int i; // free(control->potential_nexts_list); if ((control->reference == ALILEN) && (control->normalize || !control->lcsmode)) { for (i=0; i < control->threads_number; i++) free(control->addresses[i]); free(control->addresses); } free(control->iseqs1); free(control->iseqs2); } int mt_compare_sumaclust(fastaSeqPtr* db, int n, BOOL fast, double threshold, BOOL normalize, int reference, BOOL lcsmode, int threads_number, double max_ratio) { thread_control_t control; int32_t i; int lmax, lmin; if (lcsmode || normalize) fprintf(stderr,"Clustering sequences when similarity >= %lf\n", threshold); else fprintf(stderr,"Clustering sequences when distance <= %lf\n", threshold); fprintf(stderr,"Aligning and clustering... \n"); #ifdef OMP_SUPPORT control.threads_number = omp_get_max_threads(); #else control.threads_number = 1; #endif if (threads_number < control.threads_number) control.threads_number = threads_number; calculateMaxAndMinLen(db, n, &lmax, &lmin); control.addresses = (int16_t**) malloc(control.threads_number*sizeof(int16_t*)); control.iseqs1 = (int16_t**) malloc(control.threads_number*sizeof(int16_t*)); control.iseqs2 = (int16_t**) malloc(control.threads_number*sizeof(int16_t*)); for (i=0; i < control.threads_number; i++) control.sizeForSeqs = prepareTablesForSumathings(lmax, lmin, threshold, normalize, reference, lcsmode, (control.addresses)+i, (control.iseqs1)+i, (control.iseqs2)+i); control.db = db; control.next = 0; control.normalize = normalize; control.reference = reference; control.threshold = threshold; control.max_ratio = max_ratio; control.lcsmode = lcsmode; control.stop = FALSE; control.fast = fast; control.seeds_counter = 1; // control.potential_nexts_list = (int*) calloc(control.threads_number, sizeof(int)); control.n = n; if (lcsmode || normalize) control.worstscore = 0.0; else control.worstscore = lmax; control.elapsedtime=0; fprintf(stderr, "%d threads running\n", control.threads_number); // initialize scores table : initializeCentersAndScores(&control); while (control.stop == FALSE) { if ((control.next)%100 == 0) { float p = ((float)(control.next)/(float)n)*100; fprintf(stderr,"\rDone : %f %% ",p); } computeOneSeed(&control); } for (i=0; i < control.threads_number; i++) { free((*((control.iseqs1)+i))-(control.sizeForSeqs)+lmax); free((*((control.iseqs2)+i))-(control.sizeForSeqs)+lmax); } freeEverything(&control); fprintf(stderr,"\rDone : 100 %% %d clusters created. \n\n", control.seeds_counter); fprintf(stderr,"Pure computation time %f \n\n", (double)control.elapsedtime/1000000.); return(control.seeds_counter); } sumaclust_v1.0.10/mtcompare_sumaclust.h000666 000765 000024 00000000500 12551664362 022303 0ustar00celinemercierstaff000000 000000 /* * mtcompare.h * * Created on: 12 mars 2013 * Author: celinemercier */ #ifndef MTCOMPARE_H_ #define MTCOMPARE_H_ int mt_compare_sumaclust(fastaSeqPtr* db, int n, BOOL fast, double threshold, BOOL normalize, int reference, BOOL lcsmode, int threads_number, double max_ratio); #endif /* MTCOMPARE_H_ */ sumaclust_v1.0.10/sumaclust.c000666 000765 000024 00000105545 12560646012 020236 0ustar00celinemercierstaff000000 000000 /** * FileName: sumaclust.c * Author: Celine Mercier * Description: star clustering of DNA sequences * **/ #include #include #include #include #include #include #include "./sumalibs/libutils/utilities.h" #include "./sumalibs/libfasta/sequence.h" #include "./sumalibs/libfasta/fasta_header_parser.h" #include "./sumalibs/libfasta/fasta_header_handler.h" #include "./sumalibs/libfasta/fasta_seq_writer.h" #include "./sumalibs/liblcs/upperband.h" #include "./sumalibs/liblcs/sse_banded_LCS_alignment.h" #include "mtcompare_sumaclust.h" #include "sumaclust.h" #define VERSION "1.0.10" /* ----------------------------------------------- */ /* printout help */ /* ----------------------------------------------- */ #define PP fprintf(stdout, static void PrintHelp() { PP "------------------------------------------------------------\n"); PP " SUMACLUST Version %s\n", VERSION); PP "------------------------------------------------------------\n"); PP " Synopsis : star clustering of sequences.\n"); PP " Usage: sumaclust [options] \n"); PP "------------------------------------------------------------\n"); PP " Options:\n"); PP " -h : [H]elp - print help\n\n"); PP " -l : Reference sequence length is the shortest. \n\n"); PP " -L : Reference sequence length is the largest. \n\n"); PP " -a : Reference sequence length is the alignment length (default). \n\n"); PP " -n : Score is normalized by reference sequence length (default).\n\n"); PP " -r : Raw score, not normalized. \n\n"); PP " -d : Score is expressed in distance (default : score is expressed in similarity). \n\n"); PP " -t ##.## : Score threshold for clustering. If the score is normalized and expressed in similarity (default),\n"); PP " it is an identity, e.g. 0.95 for an identity of 95%%. If the score is normalized\n"); PP " and expressed in distance, it is (1.0 - identity), e.g. 0.05 for an identity of 95%%.\n"); PP " If the score is not normalized and expressed in similarity, it is the length of the\n"); PP " Longest Common Subsequence. If the score is not normalized and expressed in distance,\n"); PP " it is (reference length - LCS length).\n"); PP " Only sequences with a similarity above ##.## with the center sequence of a cluster\n"); PP " are assigned to that cluster. Default: 0.97.\n\n"); PP " -e : Exact option : A sequence is assigned to the cluster with the center sequence presenting the\n"); PP " highest similarity score > threshold, as opposed to the default 'fast' option where a sequence is\n"); PP " assigned to the first cluster found with a center sequence presenting a score > threshold.\n\n"); PP " -R ## : Maximum ratio between the counts of two sequences so that the less abundant one can be considered\n"); PP " as a variant of the more abundant one. Default: 1.0.\n\n"); PP " -p ## : Multithreading with ## threads using openMP.\n\n"); PP " -s #### : Sorting by ####. Must be 'None' for no sorting, or a key in the fasta header of each sequence,\n"); PP " except for the count that can be computed (default : sorting by count).\n\n"); PP " -o : Sorting is in ascending order (default : descending).\n\n"); PP " -g : n's are replaced with a's (default: sequences with n's are discarded).\n\n"); PP " -B ### : Output of the OTU table in BIOM format is activated, and written to file ###.\n\n"); PP " -O ### : Output of the OTU map (observation map) is activated, and written to file ###.\n\n"); PP " -F ### : Output in FASTA format is written to file ### instead of standard output.\n\n"); PP " -f : Output in FASTA format is deactivated.\n"); PP "\n"); PP "------------------------------------------------------------\n"); PP " Argument : the nucleotide dataset to cluster\n"); PP "------------------------------------------------------------\n"); PP " http://metabarcoding.org/sumatra\n"); PP "------------------------------------------------------------\n\n"); } #undef PP /* ----------------------------------------------- */ /* printout usage and exit */ /* ----------------------------------------------- */ #define PP fprintf(stderr, static void ExitUsage(stat) int stat; { PP "usage: sumaclust [-l|L|a|n|r|d|e|o|g|f] [-t threshold_value] [-s sorting_key] [-R maximum_ratio] [-p number_of_threads]\n"); PP "[-B file_name_for_BIOM-formatted_output] [-O file_name_for_OTU_table-formatted_output] [-F file_name_for_FASTA-formatted_output] dataset\n"); PP "type \"sumaclust -h\" for help\n"); if (stat) exit(stat); } #undef PP static char* sortingKey="count"; static int sortSeqsP(const void **s1, const void **s2) { int res; double r1; double r2; r1 = atof(getItemFromHeader(sortingKey, ((fastaSeqPtr) *s2)->header)); r2 = atof(getItemFromHeader(sortingKey, ((fastaSeqPtr) *s2)->header)); if (r2 > r1) res = 1; else if (r2 < r1) res = -1; else res = 0; return(res); } static int reverseSortSeqsP(const void **s1, const void **s2) { int res; double r1; double r2; r1 = atof(getItemFromHeader(sortingKey, ((fastaSeqPtr) *s2)->header)); r2 = atof(getItemFromHeader(sortingKey, ((fastaSeqPtr) *s2)->header)); if (r1 > r2) res = 1; else if (r1 < r2) res = -1; else res = 0; return(res); } int uniqSeqsDoubleSortFunction(const void *s1, const void *s2) { int c; char* str_r1; double r1; double r2; c = strcmp(((fastaSeqPtr) s1)->sequence, ((fastaSeqPtr) s2)->sequence); if (c == 0) { str_r1 = getItemFromHeader(sortingKey, ((fastaSeqPtr) s1)->header); if (str_r1 == NULL) { fprintf(stderr, "\nERROR: '%s' not in sequence header(s).\n\n", sortingKey); exit(1); } r1 = atof(str_r1); r2 = atof(getItemFromHeader(sortingKey, ((fastaSeqPtr) s2)->header)); if (r2 > r1) c = 1; else if (r2 < r1) c = -1; else c = 0; } return(c); } int uniqSeqsDoubleReverseSortFunction(const void *s1, const void *s2) { int c; char* str_r1; double r1; double r2; c = strcmp(((fastaSeqPtr) s1)->sequence, ((fastaSeqPtr) s2)->sequence); if (c == 0) { str_r1 = getItemFromHeader(sortingKey, ((fastaSeqPtr) s1)->header); if (str_r1 == NULL) { fprintf(stderr, "\nERROR: '%s' not in sequence header(s).\n\n", sortingKey); exit(1); } r1 = atof(str_r1); r2 = atof(getItemFromHeader(sortingKey, ((fastaSeqPtr) s2)->header)); if (r1 > r2) c = 1; else if (r1 < r2) c = -1; else c = 0; } return(c); } void printInBIOMformat(fastaSeqPtr* uniqSeqs, int count, int numberOfCenters, char* biomFile_name) { int i, j, n; FILE* biomFile; struct tm* tm_info; time_t timer; char buffer_date[20]; fastaSeqPtr* c; fastaSeqPtr* seq; int id_len; int row_number; BOOL first_center = TRUE; int buffer_col_rows; int buffer_col_rows_1; int buffer_col_rows_2; buffer_col_rows = 29; buffer_col_rows_1 = 9; buffer_col_rows_2 = 20; n = 0; biomFile = fopen(biomFile_name, "w"); if (biomFile == NULL) fprintf(stderr, "\nCan't open BIOM output file.\n"); //, %s outputFilename); for (i=0; iaccession_id); j=0; if ((*seq)->cluster_center) // center sequence { n++; (*seq)->cluster_weight_unique_ids = 1; if (first_center) { (*seq)->columns_BIOM_size = id_len + buffer_col_rows; (*seq)->columns_BIOM = (char*) malloc(((*seq)->columns_BIOM_size)*sizeof(char)); strcpy((*seq)->columns_BIOM, "{\"id\": \""); first_center = FALSE; } else { (*seq)->columns_BIOM_size = id_len + buffer_col_rows + 1; (*seq)->columns_BIOM = (char*) malloc(((*seq)->columns_BIOM_size)*sizeof(char)); strcpy((*seq)->columns_BIOM, ",{\"id\": \""); } memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - id_len - buffer_col_rows_2 - 1, (*seq)->accession_id, id_len); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - buffer_col_rows_2 - 1, "\", \"metadata\": null}", buffer_col_rows_2+1); if ((*seq)->next != NULL) // not last sequence { for (j=1; ((((*seq)+j)->next != NULL) && (((*seq)+j)->uniqHead == FALSE)); j++) // identical sequences { id_len = strlen((*(seq)+j)->accession_id); n++; (*seq)->cluster_weight_unique_ids++; (*seq)->columns_BIOM_size = (*seq)->columns_BIOM_size + id_len + buffer_col_rows; (*seq)->columns_BIOM = realloc((*seq)->columns_BIOM, ((*seq)->columns_BIOM_size) * sizeof(char)); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - buffer_col_rows - id_len - 1, ",{\"id\": \"", buffer_col_rows_1); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - id_len - buffer_col_rows_2 - 1, (*(seq)+j)->accession_id, id_len); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - buffer_col_rows_2 - 1, "\", \"metadata\": null}", buffer_col_rows_2+1); } if ((((*seq)+j)->next == NULL) && (((*seq)+j)->uniqHead == FALSE)) // last sequence { id_len = strlen((*(seq)+j)->accession_id); n++; (*seq)->cluster_weight_unique_ids++; (*seq)->columns_BIOM_size = (*seq)->columns_BIOM_size + id_len + buffer_col_rows; (*seq)->columns_BIOM = realloc((*seq)->columns_BIOM, ((*seq)->columns_BIOM_size) * sizeof(char)); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - buffer_col_rows - id_len - 1, ",{\"id\": \"", buffer_col_rows_1); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - id_len - buffer_col_rows_2 - 1, (*(seq)+j)->accession_id, id_len); memcpy((*seq)->columns_BIOM + (*seq)->columns_BIOM_size - buffer_col_rows_2 - 1, "\", \"metadata\": null}", buffer_col_rows_2+1); } } } else // not a center sequence { n++; c = (*seq)->center; id_len = strlen((*seq)->accession_id); n++; (*c)->cluster_weight_unique_ids++; (*c)->columns_BIOM_size = (*c)->columns_BIOM_size + id_len + buffer_col_rows; (*c)->columns_BIOM = realloc((*c)->columns_BIOM, ((*c)->columns_BIOM_size) * sizeof(char)); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - buffer_col_rows - id_len - 1, ",{\"id\": \"", buffer_col_rows_1); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - id_len - buffer_col_rows_2 - 1, (*seq)->accession_id, id_len); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - buffer_col_rows_2 - 1, "\", \"metadata\": null}", buffer_col_rows_2+1); if ((*seq)->next != NULL) // not last sequence { for (j=1; ((((*seq)+j)->next != NULL) && (((*seq)+j)->uniqHead == FALSE)); j++) // identical sequences { id_len = strlen((*(seq)+j)->accession_id); n++; (*c)->cluster_weight_unique_ids++; (*c)->columns_BIOM_size = (*c)->columns_BIOM_size + id_len + buffer_col_rows; (*c)->columns_BIOM = realloc((*c)->columns_BIOM, ((*c)->columns_BIOM_size) * sizeof(char)); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - buffer_col_rows - id_len - 1, ",{\"id\": \"", buffer_col_rows_1); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - id_len - buffer_col_rows_2 - 1, (*(seq)+j)->accession_id, id_len); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - buffer_col_rows_2 - 1, "\", \"metadata\": null}", buffer_col_rows_2+1); } if ((((*seq)+j)->next == NULL) && (((*seq)+j)->uniqHead == FALSE)) // last sequence { id_len = strlen((*(seq)+j)->accession_id); n++; (*c)->cluster_weight_unique_ids++; (*c)->columns_BIOM_size = (*c)->columns_BIOM_size + id_len + buffer_col_rows; (*c)->columns_BIOM = realloc((*c)->columns_BIOM, ((*c)->columns_BIOM_size) * sizeof(char)); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - buffer_col_rows - id_len - 1, ",{\"id\": \"", buffer_col_rows_1); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - id_len - buffer_col_rows_2 - 1, (*(seq)+j)->accession_id, id_len); memcpy((*c)->columns_BIOM + (*c)->columns_BIOM_size - buffer_col_rows_2 - 1, "\", \"metadata\": null}", buffer_col_rows_2+1); } } } } time(&timer); tm_info = localtime(&timer); strftime(buffer_date, 20, "%Y-%m-%dT%H:%M:%S", tm_info); fprintf(biomFile, "{\"id\": \"None\",\"format\": \"Biological Observation Matrix 1.0.0\"," "\"format_url\": \"http://biom-format.org\",\"type\": \"OTU table\"," "\"generated_by\": \"SUMACLUST %s\",\"date\": \"%s\",\"matrix_type\": \"sparse\"," "\"matrix_element_type\": \"int\",\"shape\": [%d, %d],", VERSION, buffer_date, numberOfCenters, n); // print data row_number = 0; n = 0; fprintf(biomFile, "\"data\": ["); for (i=0; icluster_center) // center sequence { for (j=0; j<(*seq)->cluster_weight_unique_ids; j++) { if ((row_number == (numberOfCenters - 1)) && (j == ((*seq)->cluster_weight_unique_ids - 1))) // last seq to print fprintf(biomFile, "[%d,%d,1]],", row_number, n); else fprintf(biomFile, "[%d,%d,1],", row_number, n); n++; } row_number++; } } // end data // Print rows first_center = TRUE; for (i=0; icluster_center) // center sequence { if (first_center) { fprintf(biomFile, "\"rows\": [{\"id\": \"%s\", \"metadata\": null}", (*seq)->accession_id); first_center = FALSE; } else fprintf(biomFile, ",{\"id\": \"%s\", \"metadata\": null}", (*seq)->accession_id); } } // Print columns fprintf(biomFile, "],\"columns\": ["); for (i=0; icluster_center) // center sequence fprintf(biomFile, (*seq)->columns_BIOM); } fprintf(biomFile, "]}"); fclose(biomFile); } void printInOTUtableFormat(fastaSeqPtr* uniqSeqs, int count, char* OTUtableFile_name) { int i, j; FILE* OTUtableFile; fastaSeqPtr* c; fastaSeqPtr* seq; int id_len; OTUtableFile = fopen(OTUtableFile_name, "w"); if (OTUtableFile == NULL) fprintf(stderr, "\nCan't open OTU table output file.\n"); //, %s outputFilename); for (i=0; iaccession_id); j=0; if ((*seq)->cluster_center) // center sequence { (*seq)->line_OTU_table_size = id_len*2 + 2; (*seq)->line_OTU_table = (char*) malloc(((*seq)->line_OTU_table_size)*sizeof(char)); strcpy((*seq)->line_OTU_table, (*seq)->accession_id); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - id_len - 2, "\t", 1); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - id_len - 1, (*seq)->accession_id, id_len); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - 1, "\0", 1); if ((*seq)->next != NULL) // not last sequence { for (j=1; ((((*seq)+j)->next != NULL) && (((*seq)+j)->uniqHead == FALSE)); j++) // identical sequences { id_len = strlen((*(seq)+j)->accession_id); (*seq)->line_OTU_table_size = (*seq)->line_OTU_table_size + id_len + 1; (*seq)->line_OTU_table = realloc((*seq)->line_OTU_table, ((*seq)->line_OTU_table_size) * sizeof(char)); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - id_len - 2, "\t", 1); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - id_len - 1, (*(seq)+j)->accession_id, id_len); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - 1, "\0", 1); } if ((((*seq)+j)->next == NULL) && (((*seq)+j)->uniqHead == FALSE)) // last sequence { id_len = strlen((*(seq)+j)->accession_id); (*seq)->line_OTU_table_size = (*seq)->line_OTU_table_size + id_len + 1; (*seq)->line_OTU_table = realloc((*seq)->line_OTU_table, ((*seq)->line_OTU_table_size) * sizeof(char)); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - id_len - 2, "\t", 1); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - id_len - 1, (*(seq)+j)->accession_id, id_len); memcpy((*seq)->line_OTU_table + (*seq)->line_OTU_table_size - 1, "\0", 1); } } } else // not a center sequence { c = (*seq)->center; (*c)->line_OTU_table_size = (*c)->line_OTU_table_size + id_len + 1; (*c)->line_OTU_table = realloc((*c)->line_OTU_table, ((*c)->line_OTU_table_size) * sizeof(char)); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - id_len - 2, "\t", 1); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - id_len - 1, (*seq)->accession_id, id_len); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - 1, "\0", 1); if ((*seq)->next != NULL) // not last sequence { for (j=1; ((((*seq)+j)->next != NULL) && (((*seq)+j)->uniqHead == FALSE)); j++) // identical sequences { id_len = strlen((*(seq)+j)->accession_id); (*c)->line_OTU_table_size = (*c)->line_OTU_table_size + id_len + 1; (*c)->line_OTU_table = realloc((*c)->line_OTU_table, ((*c)->line_OTU_table_size) * sizeof(char)); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - id_len - 2, "\t", 1); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - id_len - 1, (*(seq)+j)->accession_id, id_len); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - 1, "\0", 1); } if ((((*seq)+j)->next == NULL) && (((*seq)+j)->uniqHead == FALSE)) // last sequence { id_len = strlen((*(seq)+j)->accession_id); (*c)->line_OTU_table_size = (*c)->line_OTU_table_size + id_len + 1; (*c)->line_OTU_table = realloc((*c)->line_OTU_table, ((*c)->line_OTU_table_size) * sizeof(char)); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - id_len - 2, "\t", 1); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - id_len - 1, (*(seq)+j)->accession_id, id_len); memcpy((*c)->line_OTU_table + (*c)->line_OTU_table_size - 1, "\0", 1); } } } } // Print rows for (i=0; icluster_center) // center sequence { fprintf(OTUtableFile, (*seq)->line_OTU_table); fprintf(OTUtableFile, "\n"); } } fclose(OTUtableFile); } void printSeq(fastaSeqPtr* seq, fastaSeqPtr* center, double score, FILE* output) { int i; char* score_n; char* score_v; char* cluster_n; char* cluster_v; char* center_n; char* center_true; char* center_false; int id_size; score_n = (char*) malloc(14*sizeof(char)); score_v = (char*) malloc(20*sizeof(char)); strcpy(score_n, "cluster_score"); sprintf(score_v,"%f", score); id_size = strlen((*center)->accession_id); cluster_n = (char*) malloc(8*sizeof(char)); cluster_v = (char*) malloc((id_size+1)*sizeof(char)); strcpy(cluster_n, "cluster"); strcpy(cluster_v, (*center)->accession_id); center_n = (char*) malloc(15*sizeof(char)); strcpy(center_n, "cluster_center"); center_true = (char*) malloc(5*sizeof(char)); strcpy(center_true, "True"); center_false = (char*) malloc(6*sizeof(char)); strcpy(center_false, "False"); (*seq)->header = table_header_add_field((*seq)->header, cluster_n, cluster_v); (*seq)->header = table_header_add_field((*seq)->header, score_n, score_v); if ((*seq)->cluster_center) (*seq)->header = table_header_add_field((*seq)->header, center_n, center_true); else (*seq)->header = table_header_add_field((*seq)->header, center_n, center_false); printOnlyHeaderFromTable((*seq)->header, output); printOnlySeqFromFastaSeqPtr((*seq), output); if ((*seq)->next != NULL) { for (i=1; ((((*seq)+i)->next != NULL) && (((*seq)+i)->uniqHead == FALSE)); i++) { ((*seq)+i)->header = table_header_add_field(((*seq)+i)->header, cluster_n, cluster_v); ((*seq)+i)->header = table_header_add_field(((*seq)+i)->header, score_n, score_v); ((*seq)+i)->header = table_header_add_field(((*seq)+i)->header, center_n, center_false); printOnlyHeaderFromTable(((*seq)+i)->header, output); printOnlySeqFromFastaSeqPtr(((*seq)+i), output); } if ((((*seq)+i)->next == NULL) && (((*seq)+i)->uniqHead == FALSE)) // last sequence { ((*seq)+i)->header = table_header_add_field(((*seq)+i)->header, cluster_n, cluster_v); ((*seq)+i)->header = table_header_add_field(((*seq)+i)->header, score_n, score_v); ((*seq)+i)->header = table_header_add_field(((*seq)+i)->header, center_n, center_false); printOnlyHeaderFromTable(((*seq)+i)->header, output); printOnlySeqFromFastaSeqPtr(((*seq)+i), output); } } } void putSeqInCluster(fastaSeqPtr* seq, fastaSeqPtr* center, double score) { (*seq)->center = center; (*seq)->score = score; } int compare(fastaSeqPtr* db, int n, BOOL fastOption, double threshold, BOOL normalize, int reference, BOOL lcsmode, double max_ratio) { double score; double scoremax; double worstscore; BOOL toCluster; static BOOL first=TRUE; int32_t i,j,k; int center; float p; BOOL found; int lmax, lmin; int16_t* address; int16_t* iseq1; int16_t* iseq2; int l1; int l2; char* s1; char* s2; int sizeForSeqs; int LCSmin; if (lcsmode || normalize) fprintf(stderr,"Clustering sequences when similarity >= %lf\n", threshold); else fprintf(stderr,"Clustering sequences when distance <= %lf\n", threshold); fprintf(stderr,"Aligning and clustering... \n"); int* centers = (int*) malloc(n * sizeof(int)); for (i=0; i < n; i++) centers[i] = -1; k=0; found = FALSE; calculateMaxAndMinLen(db, n, &lmax, &lmin); sizeForSeqs = prepareTablesForSumathings(lmax, lmin, threshold, normalize, reference, lcsmode, &address, &iseq1, &iseq2); if (lcsmode || normalize) worstscore = 0.0; else worstscore = lmax; for (i=0; i < n; i++) { if (i%100 == 0) { p = (i/(float)n)*100; fprintf(stderr,"\rDone : %f %% %d clusters created",p,k); } if (first) { first = FALSE; if (normalize && lcsmode) score = 1.0; else if (!lcsmode) score = 0.0; else score = (*(db+i))->length; (*(db+i))->cluster_center = TRUE; putSeqInCluster(db+i, db+i, score); centers[k] = i; k++; } else { scoremax = worstscore; center = 0; found = FALSE; toCluster = FALSE; j=0; s1 = (*(db+i))->sequence; l1 = (*(db+i))->length; while (((found == FALSE) && (centers[j] != -1) && (fastOption == TRUE)) || ((fastOption == FALSE) && (centers[j] != -1))) { score = worstscore; if ((double) ((*(db+i))->count) / (double) ((*(db+centers[j]))->count) <= max_ratio) { filters((*(db+i)), (*(db+centers[j])), threshold, normalize, reference, lcsmode, &score, &LCSmin); } if (score == -1.0) { s2 = (*(db+centers[j]))->sequence; l2 = (*(db+centers[j]))->length; score = alignForSumathings(s1, iseq1, s2, iseq2, l1, l2, normalize, reference, lcsmode, address, sizeForSeqs, LCSmin); } if (((score >= threshold) && (lcsmode || normalize) && (score > scoremax)) || ((!lcsmode && !normalize) && (score <= threshold) && (score < scoremax))) { toCluster = TRUE; scoremax = score; center = centers[j]; if (fastOption == TRUE) found = TRUE; } j++; } if (toCluster) { if (!lcsmode && normalize) scoremax = 1.0 - scoremax; (*(db+i))->cluster_center = FALSE; putSeqInCluster(db+i, db+center, scoremax); } else { if (normalize && lcsmode) score = 1.0; else if (!lcsmode) score = 0.0; else score = (*(db+i))->length; (*(db+i))->cluster_center = TRUE; putSeqInCluster(db+i, db+i, score); centers[k] = i; k++; } } } fprintf(stderr,"\rDone : 100 %% %d clusters created. \n",k); free(centers); free(iseq1-sizeForSeqs+lmax); free(iseq2-sizeForSeqs+lmax); if (normalize && reference == ALILEN) free(address); return(k); } void computeClusterWeights(fastaSeqPtr* uniqSeqs, int n) { int i,j; fastaSeqPtr* seq; fastaSeqPtr* center; char* cluster_weight_n; char* cluster_weight_v; int cluster_weight; for (i=0; icluster_center) (*seq)->cluster_weight = (*seq)->count; else { center = (*seq)->center; ((*center)->cluster_weight)+=(*seq)->count; } } for (i=0; icluster_center) cluster_weight = (*seq)->cluster_weight; else { center = (*seq)->center; cluster_weight = (*center)->cluster_weight; } cluster_weight_n = (char*) malloc(15*sizeof(char)); cluster_weight_v = (char*) malloc(20*sizeof(char)); strcpy(cluster_weight_n, "cluster_weight"); sprintf(cluster_weight_v,"%d", cluster_weight); (*seq)->header = table_header_add_field((*seq)->header, cluster_weight_n, cluster_weight_v); if ((*seq)->next != NULL) // not the last sequence { for (j=1; ((((*seq)+j)->next != NULL) && (((*seq)+j)->uniqHead == FALSE)); j++) (*(seq)+j)->header = table_header_add_field((*(seq)+j)->header, cluster_weight_n, cluster_weight_v); if ((((*seq)+j)->next == NULL) && (((*seq)+j)->uniqHead == FALSE)) // last sequence (*(seq)+j)->header = table_header_add_field((*(seq)+j)->header, cluster_weight_n, cluster_weight_v); } } } int main(int argc, char** argv) { int32_t carg = 0; int32_t errflag = 0; char* sort; double threshold = 0.97; double max_ratio = 1.0; BOOL lcsmode = TRUE; BOOL fastOption = TRUE; BOOL normalize = TRUE; BOOL reverse = FALSE; BOOL onlyATGC = TRUE; int reference = ALILEN; int ndb = 0; int nproc = 1; BOOL printBIOM = FALSE; BOOL printOTUtable = FALSE; BOOL printFASTA = TRUE; BOOL printFASTAtofile = FALSE; FILE* FASTA_output = stdout; fastaSeqCount db; int i,n; fastaSeqPtr* uniqSeqs; char* biomFile_name; char* OTUtableFile_name; char* FASTA_file_name; int numberOfCenters; sort = malloc(1024*sizeof(char)); strcpy(sort, "count"); biomFile_name = malloc(1024*sizeof(char)); OTUtableFile_name = malloc(1024*sizeof(char)); FASTA_file_name = malloc(1024*sizeof(char)); while ((carg = getopt(argc, argv, "hlLanrdet:p:s:ogB:O:R:fF:")) != -1) { switch (carg) { /* -------------------- */ case 'h': /* help */ /* -------------------- */ PrintHelp(); exit(0); break; /* -------------------------------------------------- */ case 'l': /* Normalize LCS/Error by the shortest sequence length*/ /* -------------------------------------------------- */ reference=MINLEN; break; /* -------------------------------------------------- */ case 'L': /* Normalize LCS/Error by the largest sequence length */ /* -------------------------------------------------- */ reference=MAXLEN; break; /* -------------------------------------------------- */ case 'a': /* Normalize LCS/Error by the alignment length */ /* -------------------------------------------------- */ reference=ALILEN; break; /* -------------------------------------------------- */ case 'n': /* Normalize LCS by the reference length */ /* -------------------------------------------------- */ normalize=TRUE; break; /* -------------------------------------------------- */ case 'r': /* No normalization */ /* -------------------------------------------------- */ normalize=FALSE; break; /* -------------------------------------------------- */ case 'd': /* Score is expressed in distance */ /* -------------------------------------------------- */ lcsmode=FALSE; break; /* ---------------------------------------------------------------------------------------------------------- */ case 'e': /* center with the best score > threshold is chosen, otherwise first center with a score > threshold */ /* ---------------------------------------------------------------------------------------------------------- */ fastOption=FALSE; break; /* ------------------------------------------------------------------- */ case 't': /* Clusters only pairs with similarity higher than (threshold) */ /* ------------------------------------------------------------------- */ sscanf(optarg,"%lf",&threshold); break; /* ------------------------------------------------------------------- */ case 'R': /* maximum ratio between counts of two sequences connected by an edge */ /* ------------------------------------------------------------------- */ sscanf(optarg,"%lf",&max_ratio); break; /* -------------------------------------------------- */ case 'p': /* number of processors to use */ /* -------------------------------------------------- */ sscanf(optarg,"%d",&nproc); break; /* -------------------------------------------------- */ case 's': /* Sorting option */ /* -------------------------------------------------- */ sscanf(optarg, "%s", sort); sortingKey = sort; break; /* -------------------------------------------------- */ case 'o': /* reverse sorting */ /* -------------------------------------------------- */ reverse=TRUE; break; /* -------------------------------------------------- */ case 'g': /* replace n's with a's in sequences */ /* -------------------------------------------------- */ onlyATGC=FALSE; break; /* -------------------------------------------------- */ case 'B': /* file name to print results in BIOM format */ /* -------------------------------------------------- */ sscanf(optarg, "%s", biomFile_name); printBIOM=TRUE; break; /* -------------------------------------------------- */ case 'O': /* file name to print results in OTU table format */ /* -------------------------------------------------- */ sscanf(optarg, "%s", OTUtableFile_name); printOTUtable=TRUE; break; /* -------------------------------------------------- */ case 'f': /* don't print results in FASTA format */ /* -------------------------------------------------- */ printFASTA=FALSE; break; /* ---------------------------------------------- */ case 'F': /* file name to print results in FASTA format */ /* ---------------------------------------------- */ sscanf(optarg, "%s", FASTA_file_name); printFASTAtofile=TRUE; break; case '?': /* invalid option */ errflag++; break; } } ndb = argc - optind; if (ndb != 1) errflag++; if (errflag) ExitUsage(errflag); fprintf(stderr,"===========================================================\n"); fprintf(stderr," SUMACLUST version %s\n",VERSION); #ifdef __SSE2__ fprintf(stderr," Alignment using SSE2 instructions.\n"); #else fprintf(stderr," Alignment using standard code, SSE2 unavailable.\n"); #endif fprintf(stderr,"===========================================================\n"); if ((threshold == 0.0) || (normalize && (threshold > 1.0))) { fprintf(stderr, "\nERROR: Please specify a threshold > 0, and < 1 when scores are normalized.\n\n"); exit(1); } fprintf(stderr,"Reading dataset..."); db = seq_readAllSeq2(argv[optind], TRUE, onlyATGC); fprintf(stderr,"\n%d sequences\n",db.count); if (db.count == 0) { fprintf(stderr, "\nNo valid sequences. Exiting program.\n\n"); exit(1); } if (!onlyATGC) (void)cleanDB(db); if (!lcsmode && normalize) threshold = 1.0 - threshold; if (threshold > 0) (void)hashDB(db); addCounts(&db); // first sorting of sequences to have good unique heads if ((strcmp(sortingKey, "None") != 0) && (strcmp(sortingKey, "none") != 0)) { if (reverse == FALSE) qsort((void*) db.fastaSeqs, db.count, sizeof(fastaSeq), uniqSeqsDoubleSortFunction); else qsort((void*) db.fastaSeqs, db.count, sizeof(fastaSeq), uniqSeqsDoubleReverseSortFunction); } // getting the vector of unique seqs uniqSeqs = (fastaSeqPtr*) malloc((db.count)*sizeof(fastaSeqPtr)); n = uniqSeqsVector(&db, &uniqSeqs); uniqSeqs = realloc(uniqSeqs, n*sizeof(fastaSeqPtr)); // putting a flag on the last sequence for (i=0; i<(db.count-1); i++) ((db.fastaSeqs)+i)->next = (db.fastaSeqs)+i-1; ((db.fastaSeqs)+(db.count)-1)->next = NULL; // sorting unique sequences if (strcmp(sortingKey, "count") == 0) { fprintf(stderr,"Sorting sequences by count...\n", n); if (reverse == FALSE) qsort((void*) uniqSeqs, n, sizeof(fastaSeqPtr), sortSeqsWithCounts); else qsort((void*) uniqSeqs, n, sizeof(fastaSeqPtr), reverseSortSeqsWithCounts); } else if ((strcmp(sortingKey, "None") != 0) && (strcmp(sortingKey, "none") != 0)) { fprintf(stderr,"Sorting sequences by %s...\n", sortingKey); if (reverse == FALSE) qsort((void*) uniqSeqs, n, sizeof(fastaSeqPtr), sortSeqsP); else qsort((void*) uniqSeqs, n, sizeof(fastaSeqPtr), reverseSortSeqsP); } if (max_ratio > 0) fprintf(stderr,"Maximum ratio between the counts of two sequences to connect them: %lf\n", max_ratio); // Computing if (nproc==1) numberOfCenters = compare(uniqSeqs, n, fastOption, threshold, normalize, reference, lcsmode, max_ratio); else numberOfCenters = mt_compare_sumaclust(uniqSeqs, n, fastOption, threshold, normalize, reference, lcsmode, nproc, max_ratio); // Computing cluster weights computeClusterWeights(uniqSeqs, n); // Printing results // FASTA file if (printFASTA) { if (printFASTAtofile) { FASTA_output = fopen(FASTA_file_name, "w"); if (FASTA_output == NULL) fprintf(stderr, "\nCan't open FASTA output file.\n"); //, %s outputFilename); } for (i=0; icenter, (*(uniqSeqs+i))->score, FASTA_output); } fprintf(stderr,"Done.\n"); } // BIOM file if (printBIOM) { fprintf(stderr,"Printing results in BIOM format...\n"); printInBIOMformat(uniqSeqs, n, numberOfCenters, biomFile_name); fprintf(stderr,"Done.\n"); } // OTU table file if (printOTUtable) { fprintf(stderr,"Printing results in OTU table format...\n"); printInOTUtableFormat(uniqSeqs, n, OTUtableFile_name); fprintf(stderr,"Done.\n"); } // Freeing for (i=0; i < db.count; i++) { free(((db.fastaSeqs)[i]).table); free_header_table(((db.fastaSeqs)[i]).header); } free(db.fastaSeqs); free(sort); free(uniqSeqs); return(0); } sumaclust_v1.0.10/sumaclust.h000666 000765 000024 00000001152 12551664362 020240 0ustar00celinemercierstaff000000 000000 /* * sumaclust.h * * Created on: april 2, 2012 * Author: mercier */ #ifndef SUMACLUST_H_ #define SUMACLUST_H_ typedef struct { int32_t next; int32_t threads_number; int* potential_nexts_list; fastaSeqPtr* db; int n; int normalize; int reference; BOOL lcsmode; BOOL fast; double threshold; BOOL stop; int sizeForSeqs; int16_t** addresses; int16_t** iseqs1; int16_t** iseqs2; int seeds_counter; double worstscore; double max_ratio; int64_t elapsedtime; } thread_control_t; #endif /* SUMACLUST_H_ */ sumaclust_v1.0.10/sumaclust_user_manual.md000644 000765 000024 00000024047 12560645137 023007 0ustar00celinemercierstaff000000 000000 # Sumaclust: fast and exact clustering of sequences [metabarcoding.org/sumaclust](metabarcoding.org/sumaclust) ## Introduction With the development of next-generation sequencing, efficient tools are needed to handle millions of sequences in reasonable amounts of time. Sumaclust is a program developed by the [LECA](http://www-leca.ujf-grenoble.fr/?lang=en). Sumaclust aims to cluster sequences in a way that is fast and exact at the same time. This tool has been developed to be adapted to the type of data generated by DNA metabarcoding, i.e. entirely sequenced, short markers. Sumaclust clusters sequences using the same clustering algorithm as UCLUST and CD-HIT. This algorithm is mainly useful to detect the 'erroneous' sequences created during amplification and sequencing protocols, deriving from 'true' sequences. Currently, Sumaclust is available as a program that you can download and install on Unix-like machines. ## Download and installation of Sumaclust ### Download Sumaclust can be downloaded from the metabarcoding.org GitLab. The archive of the latest tagged version can be downloaded on the GitLab wiki page: [https://git.metabarcoding.org/obitools/sumaclust/wikis/home](https://git.metabarcoding.org/obitools/sumaclust/wikis/home) The versions downloaded this way are for Unix-like systems compatible with SIMD SSE2 instructions and POSIX threads. Pre-compiled versions of GCC for OS X can be found [here](http://hpc.sourceforge.net/), that might be helpful if you encounter problems compiling the programs. Send an email at for other versions, or if you have any inquiries. ### Installation Untar the archive, go into the newly created directory and compile: ``` tar –zxvf sumaclust_v[x.x.xx].tar.gz cd sumaclust_v[x.x.xx] make ``` You can compile Sumaclust with `clang`, which deactivates `OpenMP`, with: ``` make CC=clang ``` ## Documentation Sumaclust clusters sequences using the same clustering algorithm as UCLUST and CD-HIT. This algorithm is mainly useful to detect the "erroneous" sequences created during amplification and sequencing protocols, deriving from "true" sequences. ### Using Sumaclust #### Input Input file must be in FASTA format. #### Usage ``` sumaclust [-l|L|a|n|r|d|e|o|g|f] [-t threshold_value] [-s sorting_key] [-R maximum_ratio] [-p number_of_threads] [-B file_name_for_BIOM-formatted_output] [-O file_name_for_OTU_table-formatted_output] [-F file_name_for_FASTA-formatted_output] dataset ``` Argument: the sequence dataset to cluster. For help : ``` sumaclust -h ``` #### Examples ``` sumaclust -t 0.97 my_dataset.fasta > clusters_of_seqs_with_similarity_>_97%.fasta ``` ``` sumaclust -d -r -t 2 my_dataset.fasta > clusters_of_seqs_with_distance_<=_2_differences.fasta ``` #### Options ``` -h : [H]elp - print the help -l : Reference sequence length is the shortest. -L : Reference sequence length is the largest. -a : Reference sequence length is the alignment length (default). -n : Score is normalized by reference sequence length (default). -r : Raw score, not normalized. -d : Score is expressed in distance (default : score is expressed in similarity). -t ##.## : Score threshold for clustering. If the score is normalized and expressed in similarity (default), it is an identity, e.g. 0.95 for an identity of 95%. If the score is normalized and expressed in distance, it is (1.0 - identity), e.g. 0.05 for an identity of 95%. If the score is not normalized and expressed in similarity, it is the length of the Longest Common Subsequence. If the score is not normalized and expressed in distance, it is (reference length - LCS length). Only sequences with a similarity above ##.## with the representative sequence of a cluster are assigned to that cluster. Default: 0.97. -e : Exact option : A sequence is assigned to the cluster with the representative sequence presenting the highest similarity score > threshold, as opposed to the default 'fast' option where a sequence is assigned to the first cluster found with a representative sequence presenting a score > threshold. -R ## : Maximum ratio between the counts of two sequences so that the less abundant one can be considered as a variant of the more abundant one. Default: 1.0. -p ## : Multithreading with ## threads using openMP. -s #### : Sorting by ####. Must be 'None' for no sorting, or a key in the fasta header of each sequence, except for the count that can be computed (default : sorting by count). -o : Sorting is in ascending order (default: descending). -g : n's are replaced with a's (default: sequences with n's are discarded). -B ### : Output of the OTU table in BIOM format is activated, and written to file ###. -O ### : Output of the OTU map (observation map) is activated, and written to file ###. -F ### : Output in FASTA format is written to file ### instead of standard output. -f : Output in FASTA format is deactivated. ``` #### Output Sumaclust's default output is in fasta format. There are four fields added in the headers of all sequences. Those fields are of the form [key=value;]. The four keys are `cluster`, `cluster_score`, `cluster_center` and `cluster_weight` and their values correspond respectively to the identifier of the center of the sequence's cluster, the similarity score of the sequence with this center, a boolean indicating whether the sequence is the center of its cluster, and the total number of sequences in the cluster to which the sequence belongs. Example where `seq_1` is a cluster center and `seq_2` is clustered with `seq_1`: ``` >seq_1 species=Heracleum maximum; count=3; cluster=seq_1; cluster_score=1.0; cluster_center=True; cluster_weight=5; atcctattttccaaaaacaaacaaaggcccagaaggtgaaaaaag >seq_2 species=Cnidium cnidiifolium; count=2; cluster=seq_1; cluster_score=0.955556; cluster_center=False; cluster_weight=5; atcctattttccaaaaacaacaaaggcccataaggtgaaaaaag ``` There is a possibility to print the clusters in BIOM format with the `–B` option, and/or in OTU map (observation map) format with the `–O` option. The FASTA output can then be deactivated with the `–f` option. The FASTA output is written to the standard output by default, but can be written to a file using the `–F` option. In the following examples, the first one prints results in FASTA and BIOM formats, and the second one prints results in BIOM and OTU map formats: ``` sumaclust -B clusters_of_seqs_with_similarity_>_97%.biom my_dataset.fasta > clusters_of_seqs_with_similarity_>_97%.fasta ``` ``` sumaclust -F -B clusters_of_seqs_with_similarity_>_97%.biom -O clusters_of_seqs_with_similarity_>_97%.txt my_dataset.fasta ``` ### How SUMACLUST works #### Clustering algorithm Sumaclust clusters sequences using the same clustering algorithm as UCLUST and CD-HIT. The problem is defined as follows: Sumaclust browses through the dataset, in the order in which the sequences have been sorted with the -s option. By default, sequences are sorted by decreasing abundance, because this enables to identify 'true' and 'erroneous' sequences the best, as 'true' sequences tend to end up as cluster centers. The first sequence of the ordered list is considered the center of the first cluster. Each sequence, following the ordered list, is compared with the centers of the existing clusters, respecting the initial list's order. If the similarity of the query sequence with a center is above a chosen threshold, and their abundance ratio is below the maximum ratio chosen, the sequence is grouped in the cluster of this center. Otherwise, a new cluster is created with the query sequence as the center. #### About the abundance ratio An edge is created between a query sequence and a center sequence only if their abundance ratio, i.e. the query sequence’s count divided by the center sequence’s count, is below the maximum ratio chosen with the `–R` option. This can prevent sequences that are very abundant, and therefore likely true sequences, to be considered a variant of another true sequence that is only a little more abundant and very close to them. #### Similarity computation ##### Similarity indice A good way to evaluate the similarities between full-length sequences is to use indices based on the length of the Longest Common Subsequence (LCS), and in particular, a good similarity indice is the length of the LCS divided by the length of the shortest alignment representing this LCS, giving an identity percentage. This is the similarity indice used by Sumatra by default. Other similarity indices are available through the options. ##### Fast computation of the similarity *Lossless k-mer filter.* Since we are usually interested in higly similar sequences, Sumatra uses similarity thresholds under which similarities are not reported. A lossless filtering step enables to only align couples of sequences that potentially have an identity greater than the chosen threshold. This filter is based on the number of overlapping k-mers that the sequences must share in order to have an identity at least equal to the threshold. With typical DNA metabarcoding datasets (a few millions sequences of 50-300 bp and threshold around 90-95% id), we empirically determined that the most efficient filtering was achieved with 4-mers and 5-mers. *Alignment within a diagonal band.* Alignments are computed using a Needleman-Wunsch algorithm. In the scoring system used, matches are rewarded by one point, and mismatches and insertions/deletions are not penalised. The computation of the length of the LCS and the length of the alignment by the NWS algorithm has a quadratic complexity in time. It is responsible for most of the computation time. At high identity thresholds, the alignment computation can be done only in a diagonal band of the alignment matrix, gaining a considerable amount of time depending on the threshold. *Parallelization.* There are two levels of parallelization implemented in Sumatra. Both the filtering and the alignments steps are optimized with the use of Simple Instruction Multiple Data instructions (SIMD). Since 4-mers enable to work easily with SIMD instructions, we implemented a 4-mer filter. Moreover, the program can be run on multiple threads. sumaclust_v1.0.10/sumaclust_user_manual.pdf000644 000765 000024 00000233777 12560645264 023175 0ustar00celinemercierstaff000000 000000 %PDF-1.3 %Äåòåë§ó ÐÄÆ 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xí›ÛŽÇ†ïç)ú.\CÍy†¾Šc‰%±¡5À0™–,ÇKÉ"%YòSæ ü,©žéÿë&g–KZÈ] œ­îª®sWŸ^¹/Ý+W¸¶È›¶ª*×®[×7eÞ6ýàvOÝ×î…{ðé¾t›½+ÇûõïוÛNíëÆeиI Þ¸çî™+òÿF íš¼íÖµ+‹>ïKOJ¡Ì»¡î«Ìˆ+òºí†µAê¼Y×½ŸWCYyH•—]·Ž««|¨ë²f´j©è ÌÚD® ÃD=BÎh©WY×y_wž¯ÖæEWGâeÝåe=t‘ ^èÀª`£ˆA Á¢Ðe=G âÀ¸zž5˜y òCmºiëÚ›X•7Ea&m»2ošõà¤gƒf‹¶’™Ôé¦é+`FËäoÛ¢L0Ñó êxð´dҾʺé<­«ó¢\—‘:Rƒ F ^e Cj©'‰£enù‘ù亯Úf],~žjfï†6õTA¢Gx¿œz×]Ux=ÛÐmÙ8oƺ5ùä@7lòÔu3´]Ä4ß­ê²Y$PO “WzOU/Yv¢5aš÷ëuÙû^uƒCeŠ—)HU › qBbL”#$FOÐñ¨áÊë¸--´Û63¤n誾u¦cK@ùPCaZ'w?ýÓgšÍÖýéÚ™2ÇVû­W¶½»Þº××eVºëgî·Ú>½òÈ•[½¾2šöûD€ïôd·y)Ø÷úøñ*›ð_òƒ>ò@¤MBÓþ:oÃ(Ùjs#{cî[wýW÷Ùµe_’I×µ¹…\cÉp=äUÙXšv“%°&ï{3e’ˆ:Ë”öÜ<µÉ«u¿ŽØ[W–}n)¡fΑÀÀNpŪÎ;˲`eß[*Ž,z‚€ÀM0óÁhÊ3lŸ-Ù¾²lloSÒdû¯ƒ~”¾åÏpWæv‰oЀ׸@ å-_ÁžÙ GøYD÷Ã}Ä„(ƒô, %¦À` w½£Ñ6ï½Ãㄆ",q³‡à+É€—>…Š‚³{ˆ3Å„'9³Õo›6Ȉeñ¥¿áœqµWßÏÐUôiá#X8[CÜJØ3&Ô€ß0t([á8D=ô…½E‹ôღ—U˜fc¹+….‡‘åÛã0:ícvÍVpµA<øC:IòQÜ~.(mdlÔ¾(Òw´’­ð_†—á0Õà˜DN=ƒY2ŸäGþý˜q”êÝm©Þ†Èp*´7È .H';%Ì,ÊõUw\íÌr•[ÈU¡wâ²"ˆÞß "½àø e=ðAŸ\}%•Îó– >hžo».oJ«ä­RÈŽ]õ‘rÖgŸêë“„×´V±Vž·½/óÆeFc¥ê`e|ìÆ 6ö«ú®±™õ7À>pÞêŠ*_uãe™…ÝIÿ &¿³”¸+ X•Íê(«fÜà“¸ë•3¹ò’[Ø# ‡Ù©÷,Ï$¡Kobø¢PÈ=˦.B iM$€Piä|Ê`{œ…0Þ‰£‰g«Ž¢š~‚âno¢=ÓÒ>;\Ú×-ꦥ=Ë»ó ®IõRìy³ùg¦ÈK§%êÂ=Æ&ÍVø‰˜“FQ6jTåü=‰xžhÇl¸c6²¸I‚cÁi´>tfLSŠ2ñzu^êéöNÓûí4Ûÿ0O˜•}_)´©ú BÓãë+ÛHÃ>øj²vÁ÷?Y¿'Ùu~'mYx$3Ýÿ‹¸ý<$Ï«•¸«Ãœ­ >Vx&À]‰ÀÓ– q?·Üåf:U+¯CuÎfÌ´½Pî†s’Y !ÂA“M`M’±á‡Ã*‚03ĤGW$†æé*ªð¶1›Ñ°‹«5R8[(0ÿ{ÁYâ™gðÄwêáMœðŠ™¤A±6@;p¶KL&:²˜e€íÏ33‚þÛ†nâƒ6‚®&ÒI.¢5úªr¶E¡ÉŽA¡8“‡²'Q,Nm#žñ½ý½Ëã'Ms¶‹]óu-GçB†·|-I3Í –( Z^'év˜±¦.ÑCÎÔvp•Ä1ó¾´ÃI*dÌ]tY¤g(ùý•ó³[™²ÊÚó+‚)Ê}РeÑIaøé[¾è4Q%ÒtuFßy¢ .‡[.ìòH-d$†P‹¿ÇOƒž#[1 Q·°ð9°Y4Ó—½WúÀè¢G ØÖ%) LñŸø4Å|§‚ê˜qX„ÃvâC\"HÀŽªúJ“4tñˆw÷¡,Ö¿"mSž6£;D‰ºËªæÅ5gÛþΪ9[¡3qÂSpxÒ÷’µ.ùPHôÁLøáD#œÈl ”°7Eù­ ?wÙÂ/™†‰Ø<ä:¤Š‡ƒâýÏ¡ Nð:dŸGr54ŠEÖh$±céìTìÌ£ií¨®ëìPzÁE®_·+¾v:!EÜl– è@ÖšΩª,†”Y±¦¹êdN § `>@ž9”q¢t×k`az¾Ú7WÛ~^Ÿ[-I ç0wAl%K·«Â$'- ã'Û7ê±àÛÓœ{·'Ül…¸ÔO|‰>“åÜÈôñUe…‡ẼȊµ®,f‹"BZÒ/<ï³q÷ Dš~ñOä®â~)eÇ G ’ ÷ªòÀv)K ÒÄ`3NC—dÞ‹ÌüZÄé³2áò ˆ£˜õJ ž%×+j;~é »Ã°u5…¿¥%˜ø¤°¢h×éõ ßÏÃìŽÃs;Ê«ñDì­³Ë>ëÚ®U¥`â.íxÊîUv­EüØõŠ¦Ë‡*…ÙýŠ(àB±lí¬)E6‚v”VÖþ¦•1‚),LQ#½¾2¡+ÛòÖ.ÙÙ\Õ´æïu%0Lq¡hWϽ²xý§k|1˜ùë?ì^Ÿ˜Ê¦|g«y¾OæuÊöß›vC‚N–¢Ô¦Ç ±ÀD’! u¶J€Ä•”kö%.ìèmÊC\Ûîß3 #X< Œ eÛÕ|J\¤ ©%[‘7 )Iæy@TPšº>þ<Èø·‡š¦ÇŸUÇ0¸`Σ¶•q0"»CôF¥M£ (Mfño3]ö:ã„v~ÓÍßne-›n;}ñàë&ñäÚÿ 3åD߀»à†Vùkªö±÷ý%K¢„c{%E†hŠ6¿Cœƒh zÍVò]R}Áê! Lš³ŠRWu^!˜TðÌb7yÒ?Y’X8~Ð툦·[Ô•Ý¢6™m“Ä“·lä§ö79ý|h×1íî÷ÚÏ‹–Ü[,dÙ´@ÖËNÑÚÁßõN0}à݈ֆ±‚ÍJ¬Ô×Ã;{ÁÃeÀ#Oö Õ¢žñ®µj9îK"B_¢ -ø> Nn7°Y"*Žºªá`Ã&Úç®T±\¡ÚüNªêƒk4Æu`7™ú¤°¸±¬q_‘º…°ž:=  ÀåJÀR”X›ÛC=X †ÏVñ`y;Kz‘–ÑÓ «wr';Ëä…cäSgÈLÒŒ;NÑèÿƒuKSõvã©qÝ‚kÄÝZøLìæ?ÄËCÆUÉnáRçîc^·³‘ØOkv„Çq€\´zÉ8+‹ùÞ õX[9ß5V"VµIß”þ±J³¶' ë±ä6B2ß§lŠÖ§¶/À¬â_÷y××mĵ×¥Ý)+†d{m`)Å\(^PýÎã¼³Uĺ+ì~÷‚IågÊ2QAšÁ€ÜO»T—¿+õå|ãã¬rÀJ’{Gù†IE8©¤”Ôi. î«&².ùQšH¡ÒÎV IÓüÊ4}âÁ£ Þl¼ô—N—<½ÍirÏìÅü–—U‘­©MÀœ\#âœÜé;6“k°TÜFG#hML`Té^ ÇÜEbЀoV¤/VFËÇ¡ÓüY’ã±f€”;FCqð%É'ݸ, £,-~>NCпÑãyMòdŽGGáÐôNçÿ‘‚^ôj|0÷õGö’1¾‘ ¯ŸZ{þÔÚE«­èµW‡GO/ݤð5ua5ØÆÞj…×JµÍÎö›B…^MÛ«×Ovî?¿¾{ûÌíßlŸlnÞì_ÿëí7ïrû÷îÛÜZó~½r×ÿž^ Ý•0Â,qëð6ñM©CÃo¾_×xQ†ºu@{ð6mÏhÀíH&y.xu:š ;ã©PHš•½4µ÷í×öl{mÙÚ[Ó± ÎVþàx,é¶Z¾A,¡Œ]Ôu¯†×+ ŸqÂÕAË#Kã¯:‚ÞM„“E <¼Vg ·s½ªfË-ãˆâÀ’ô–ÅÆ¿m uÓ%nVy/?Tvi÷ø&7 Ú^퟾zóôÅæ©©H¦·Ó+y°T<øÇñý[iï]«²µR'¯`Écà®´çm•Ç÷oY»h%*— / íñ¹LU*Vå3nõù‘6_[‰4½”eayL0š{Éêi‰Úð9ÐFcR¥ÝÍÚÈ€%Úð0Û<m¸v‘6B1-L4j£éŽ#È­ oñ³Ùêwü["Ò’\›¹éq;à? c TE…~iXÐüDL£‹½g\–&b‘£Ô®wERð¼1úHÊìaõ¨uû5lmÉrI_þòâæåÓé®!´r8 Ü3ÜîÜQ¢ Ê±@ÍpŽŽïþò¿*¦ endstream endobj 5 0 obj 3803 endobj 2 0 obj << /Type /Page /Parent 3 0 R /Resources 6 0 R /Contents 4 0 R /MediaBox [0 0 595 842] /Annots 10 0 R >> endobj 6 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT3 16 0 R /TT2 9 0 R /TT1 8 0 R >> >> endobj 10 0 obj [ 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R ] endobj 17 0 obj << /Length 18 0 R /N 3 /Alternate /DeviceRGB /Filter /FlateDecode >> stream x–wTSهϽ7½Ð" %ôz Ò;HQ‰I€P†„&vDF)VdTÀG‡"cE ƒ‚b× òPÆÁQDEåÝŒk ï­5óÞšýÇYßÙç·×Ùgï}׺Pü‚ÂtX€4¡XîëÁ\ËÄ÷XÀáffGøDÔü½=™™¨HƳöî.€d»Û,¿P&sÖÿ‘"7C$ EÕ6<~&å”S³Å2ÿÊô•)2†12¡ ¢¬"ãįlö§æ+»É˜—&ä¡Yμ4žŒ»PÞš%ᣌ¡\˜%àg£|e½TIšå÷(ÓÓøœL0™_Ìç&¡l‰2Eî‰ò”Ä9¼r‹ù9hžx¦g䊉Ib¦טiåèÈfúñ³Sùb1+”ÃMáˆxLÏô´ Ž0€¯o–E%Ym™h‘í­ííYÖæhù¿Ùß~Sý=ÈzûUñ&ìÏžAŒžYßlì¬/½ö$Z›³¾•U´m@åá¬Oï ò´Þœó†l^’Äâ ' ‹ììlsŸk.+è7ûŸ‚oÊ¿†9÷™ËîûV;¦?#I3eE妧¦KDÌÌ —Ïdý÷ÿãÀ9iÍÉÃ,œŸÀñ…èUQè” „‰h»…Ø A1ØvƒjpÔzÐN‚6p\WÀ p €G@ †ÁK0Þi‚ð¢Aª¤™BÖZyCAP8ÅC‰’@ùÐ&¨*ƒª¡CP=ô#tº]ƒú Ð 4ý}„˜Óa ض€Ù°;GÂËàDxœÀÛáJ¸>·Âáð,…_“@ÈÑFXñDBX$!k‘"¤©Eš¤¹H‘q䇡a˜Æã‡YŒábVaÖbJ0Õ˜c˜VLæ6f3ù‚¥bÕ±¦X'¬?v 6›-ÄV``[°—±Øaì;ÇÀâp~¸\2n5®·׌»€ëà á&ñx¼*Þï‚Ásðb|!¾ ߯¿' Zk‚!– $l$Tçý„Â4Q¨Ot"†yÄ\b)±ŽØA¼I&N“I†$R$)™´TIj"]&=&½!“É:dGrY@^O®$Ÿ _%’?P”(&OJEBÙN9J¹@y@yC¥R ¨nÔXª˜ºZO½D}J}/G“3—ó—ãÉ­“«‘k•ë—{%O”×—w—_.Ÿ'_!Jþ¦ü¸QÁ@ÁS£°V¡Fá´Â=…IEš¢•bˆbšb‰bƒâ5ÅQ%¼’’·O©@é°Ò%¥!BÓ¥yÒ¸´M´:ÚeÚ0G7¤ûÓ“éÅôè½ô e%e[å(ååå³ÊRÂ0`ø3R¥Œ“Œ»Œó4æ¹ÏãÏÛ6¯i^ÿ¼)•ù*n*|•"•f••ªLUoÕÕªmªOÔ0j&jajÙjûÕ.«Ï§ÏwžÏ_4ÿäü‡ê°º‰z¸újõÃê=ꓚ¾U—4Æ5šnšÉšåšç4Ç´hZ µZåZçµ^0•™îÌTf%³‹9¡­®í§-Ñ>¤Ý«=­c¨³Xg£N³Î]’.[7A·\·SwBOK/X/_¯Qï¡>QŸ­Ÿ¤¿G¿[ÊÀÐ Ú`‹A›Á¨¡Š¡¿aža£ác#ª‘«Ñ*£Z£;Æ8c¶qŠñ>ã[&°‰I’IÉMSØÔÞT`ºÏ´Ï kæh&4«5»Ç¢°ÜYY¬FÖ 9Ã<È|£y›ù+ =‹X‹Ý_,í,S-ë,Y)YXm´ê°úÃÚÄšk]c}džjãc³Î¦Ýæµ­©-ßv¿í};š]°Ý»N»Ïöö"û&û1=‡x‡½÷Øtv(»„}Õëèá¸ÎñŒã'{'±ÓI§ßYÎ)ΠΣ ðÔ-rÑqá¸r‘.d.Œ_xp¡ÔUÛ•ãZëúÌM×çvÄmÄÝØ=Ùý¸û+K‘G‹Ç”§“çÏ ^ˆ—¯W‘W¯·’÷bïjï§>:>‰>>¾v¾«}/øaýývúÝó×ðçú×ûO8¬ è ¤FV> 2 uÃÁÁ»‚/Ò_$\ÔBüCv…< 5 ]ús.,4¬&ìy¸Ux~xw-bEDCÄ»HÈÒÈG‹KwFÉGÅEÕGME{E—EK—X,Y³äFŒZŒ ¦={$vr©÷ÒÝK‡ãìâ ãî.3\–³ìÚrµå©ËÏ®_ÁYq*ßÿ‰©åL®ô_¹wåד»‡û’çÆ+çñ]øeü‘—„²„ÑD—Ä]‰cI®IIãOAµàu²_òä©””£)3©Ñ©Íi„´ø´ÓB%aа+]3='½/Ã4£0CºÊiÕîU¢@Ñ‘L(sYf»˜ŽþLõHŒ$›%ƒY ³j²ÞgGeŸÊQÌæôäšänËÉóÉû~5f5wug¾vþ†üÁ5îk­…Ö®\Û¹Nw]Áºáõ¾ëm mHÙðËFËeßnŠÞÔQ Q°¾`h³ïæÆB¹BQá½-Î[lÅllíÝf³­jÛ—"^ÑõbËâŠâO%Ü’ëßY}WùÝÌö„í½¥ö¥ûwàvwÜÝéºóX™bY^ÙЮà]­åÌò¢ò·»Wì¾Va[q`id´2¨²½J¯jGÕ§ê¤êšæ½ê{·íÚÇÛ׿ßmÓÅ>¼È÷Pk­AmÅaÜá¬ÃÏë¢êº¿g_DíHñ‘ÏG…G¥ÇÂuÕ;Ô×7¨7”6’ƱãqÇoýàõC{«éP3£¹ø8!9ñâÇøïž <ÙyŠ}ªé'ýŸö¶ÐZŠZ¡ÖÜÖ‰¶¤6i{L{ßé€ÓÎ-?›ÿ|ôŒö™š³ÊgKϑΜ›9Ÿw~òBÆ…ñ‹‰‡:Wt>º´äÒ®°®ÞË—¯^ñ¹r©Û½ûüU—«g®9];}}½í†ýÖ»ž–_ì~iéµïm½ép³ý–ã­Ž¾}çú]û/Þöº}åŽÿ‹úî.¾{ÿ^Ü=é}ÞýÑ©^?Ìz8ýhýcìã¢' O*žª?­ýÕø×f©½ôì ×`ϳˆg†¸C/ÿ•ù¯OÃÏ©Ï+F´FêG­GÏŒùŒÝz±ôÅðËŒ—Óã…¿)þ¶÷•Ñ«Ÿ~wû½gbÉÄðkÑë™?JÞ¨¾9úÖömçdèäÓwi獵ŠÞ«¾?öý¡ûcôÇ‘éìOøO•Ÿ?w| üòx&mfæß÷„óû endstream endobj 18 0 obj 2612 endobj 7 0 obj [ /ICCBased 17 0 R ] endobj 20 0 obj << /Length 21 0 R /Filter /FlateDecode >> stream x­[io$Eý^¿"…´R1EÝÇjAâÔÎ 4Ëb„Vµšv›ñâ¶gºÛ’+¿e_fÆ‹Èêò nƒ¢y•wFD¥_»¯ÜkW¸¶È›¶ª*׎­ë›2o›~p»ûÖݸ÷?Ù—n½weøg¿Æú~¬Ü6.Ưkÿ+S×)Ák÷Ò]º"ô_h»&o»±ÆVc^¶Ýà‰)VyÝ´c²†õyQŽ%:oƺw}ÝæcS·@ª¼ìºÑµ««|¨ë²T ´jUtU²®†ÐuÞê yp ¥«Ú1»¾÷´ëʼ›6¡vê¾(ˆx¹É«`AFJÄu&5©"<€¯— 5ÑbæµÈjpÛô­7NŠ]  Ì›f ³í ¤…A¨|Þ@=M_)Ru·mQ&o&ªsO|x²Ô-6ìºÒ“RA¦ ¦IˆSJcº÷:$«\å%¤@ÄLf z‚DÀ\ó]øåØWm3þ ÞZç}7øÀH¼•9ó\‹Â) E[6®ƒÁá "©v‹Þ:6CÛÙ›ðߪ.ø/©B©AKWÑÁóåͺϛ®„JøF ^wyß4« ’z«¬oñM“šÔD£H4­Y K³Â8ïx@’š¢Ê‹¢ëƒÿJ¶hŠ"ïúq z Y Ǽ+š:S½ñ‘KS,è"fÅ4–I=Ká´ñMê›Î{°b=ø*`fè5Roúœö™² ¸RN EÇ âÒxoH™H¦ûO2ÀDƒ’š¢WC4¨X•÷U=€‹1™êYãJHÍ ¤f PŒBZ:§<$ÖhººA"-Z¨é$d+R79j>ɪ$(FMƒ–P'┇Ss@6Ñ´Ä»î˜äo¹²•+DŒG†¾óY!Z#S$ÕW_Qªë4º•:Óh1¨…­˜š¢ÌKÒc•PGT5àP­; ’z+±(c”ˆ˜F¼R'bþ¥šÖàÒP—m^ú>ÉuÑäu1„C*g•bÍïs$‹Öû´xyM$Ñ«bA!JAKÞÔHVê "<€ã½®P{ø¸"‚8ïqÊ ŽV%¿TÈ}u…œ@¯‰$ZUÌ’hÉ›Œyê 8˜ä€‰ÅÃêë œôž¾j§Í‹ g=sÄ5(©%@[j F©½iRbÇ@}‚Ì´ª¡Is€×jU"/õ¨gr=ˆÔÆg@¹$€¬1iI5AdoõÈÙùŸYMžÿ Kì«/ÐãÁe—ÃA»à¡>N‚w´uéÚ ˆé$X9`Iä{ËŒ1 ZBˆiÅÄRÌ5Nƒ¦BáŒU!îC$õE‡ºK=±ÔC‰%qï£$¬£Ì %Ô‰˜g¨–ŽûªÁÙÙ4IØgU5†ò=8­ý‚åV¾‚jP¾÷¦TEL© %«,ìb _ B=A„Ð’°Ïª>†B1 |WµPÅPµÆÀGd¡øë“’JS+hÉ* |ÐLÃ\©'ˆð†~–*Q< Ù>”ïiäWå»?$ZTÕŒ(S>ç鯫 DžþŠ©÷(u"™ò`qjè¡­Cö¤ß¡>Ïû §Q§ªÉƒ)ß+Q:€Ä &ßÔXSêD .áA}s–’^ Í©¢c0Æ¢%C£àíV×h¥½·†£ÒÛ¶@‡•x+SNðа*Iú¦†·ROõ bfÈ@+þÞÏüyþÁ3^j "©·K’€¾©!¯ÔD£ˆ RkLéá_Žó±Ÿ4eßåeïƒM¿ìë«üÙŸ•=¬Ð#‡Ñ¶NS«aIÐuÞJÞ‹,€þª„Kq eßCÉÙŸU¨ešÒ«Y•JÄ”êtUš¸Ž2ƒV$N¯ ip J (û¹ m•ß bPŽ ¸ …Ô¨"©™AhÆ¿@8dÔâ@9AdÿÄU O-10)¾‰CC”±Ì”¸Ê¨(’†?5áåcBÌBRW@ƒÂÃ#ô䰟hY0å,š1Æ?¸‹p61þaƮ쇔¯ˆ¤ª7¶_åµ£JŒ‘<ÀSÏ&HðJhš~b3ƒPaÉ´*ÖþÞçÛ¾÷%Šš1"i§ÊUÁ‘D ÅL9}¤ž¨Kã'F?æ‚…/ú1q̇¢ 4|z–þo‰ÃãÇÁ­·ÙÇç•~Xâ»ëÁMåηîýós?Œ<¿tß¹ÅÏÜX"©,nÏ<¥Ê-îøÃa'ëÕYÝÌé[ÛW|vÅ×ü±áH1[|­{lW|¶ÖåúpÈÉ/\,{d ®xÉ'Xú½;ÿ—ûìÃY+Dú]¢™³“~¨sôO%†€ Öçãè@¨¼«JKHýXäõˆR¼ÂDË0ï²rD~&ÌU×ÀºcAŒ¦ˆ•c ˜ÉBÛ€¸ÿ:S¤Gs3 Žótä-¤©ÂÏ0¼‰IÞD釯#äK‰‡rUTßF¥Ä¼BáLž–PO¨À@‹«¨Á`‰øâ0äÃPD/Ä¡ÔP´˜— RÆ*WE/3¡I=A‚Aêi¹Ó!w˜ âKÄ9œÌ²¨/‡ËÍ(risiséb}½ºùñÌÿ/æžÇ¦i¿U²A©PÙ ¡Ø–¬ß{S>Ôô§Éw­“îS¤¦c˽L£úúÏúŒô­½;ËNH±5Ì5ŽhYèÂH í„Û–I@Ô°êXôÿ3Žj8–)à‹,œô˜+†ø¯}S\%©uœ­Á8Isl‚0Ú ’¸ò¤ôEfB#Îli,[äÔ²’‰Ãe&²W%0´éÀóäê§,’p‘f–$Љ–I-U³íÕœõÆ—¨™@ªfb©š‰Q[ %9œ2‡&ZÃ4O$/6ÌÔÖ¦fºC¢fB^À¹×DÌÌøªfáÀkÙk°+ÖS FŒìG z,R­ßCrx8f0¡°"T!ú ż K|õëkÐ’$íÝ Ýʨ0R7ÄT¨˜©P H)©–ăӇTUèY€¬V‰Ez‚Æâ›¦R7„ô„T›­·oLµO¡Ö*ê¤leª}ñjsóå¿O̵²*Yäu“¼Þ@k}…¯”³yñžûåêðòï¶ÛWÙk´CÒÀ¼í«¦Tüñë'¿;ú7ÃPƒ_5­©!’65ŠÁ,ljÓv…_5­©éßòU|Ù›¨0þªi]MÊ!|çLúoÅbã%â:ÓŽP·®†ŸÈ!ãK÷í»¸ ‘°"Û´è§Z [1æpàÖéUŠ W)|KsR+täcµ4EµÃ8ÅûÑA¾]ý´qŸ|òÁÑþÈ»Of0-P¼C'|ÙùÿÔ¾ ½•tpóÞJÏõöØðí{ÍšAßÛ’ö‚k]­tõ^ ]Ž)6“(#B{ÉC ¥§üh1²=cÛ˜Yߪm£.Þ½•(´î¡ºRNµÉ5:3¦·dVéˆ6²Å7”øþø‚?ôÑ×çg˜å½[Ìè¨æ.¨z.QzŸ’Þ³ò×s±¥§‹«<‹ü¨t<í«ÖUEjE•D;ó7käN|›vâ'TÃÙQ fS‹9³6HÐg7Ô—òÿ5gª>r) ÒGúV|É$Tw µyeM÷Pêk"ÇÄTÿº”TßQd·Ó-Õôá-¥TÆ÷ïÄÛYâPI"%K¨ ¬wºz%Ñ'*>· I ÝM}‰oé6JR\‘³ß1Œ¾É‡Ú{®¤iÙ=[Ìx>QUº©:ä±®èwŸ4Èûe]Ìò¾ÎÖÌ(½ ½Ö_ªµý{äÔƒJ­¶3Ãüœˆ$>2Q¶`ŒšöÞ!C;õCÝdæÙ⡃åhŸŸ¬\©öŽrIÕ³\ò\_=Sµ-’XäS¿«ŠUF>Úªøz ñÑtâÙKsÕóÏÏ\‹*È->ò'¾×Œø°>Ó£‚fQØY6¤Y&ô¥ŒÖh¼“î?JUûÄ;9Žwm0xÑ™8±XuÊ­ÞÓÑâov'·Œâ]1O‹3ø'ÞÉÁM*|nB Zü˜£˜Té¡‚åºD;¼ñcúÂ÷{·. —¦¬½.,ÄÄl×ÑeàÓ*Øy—4©`KÜ3¯fƒ´¿Û®Ö×wûƒûîÙõý÷«û›ûÝýÅýæþöþÇûËïÜáån³y{}±üyu}·ñàÞíow‡«›—?m~óÀÜvõëÕön{–=e°•ÌÐŽXîXÝ’åånu¸ºõ{¾r7wÛ6»åíåÒó¸ºØ{øcwyu½YÞ¬¶›ååínùñó_>ÃíêpØ\,oï¯î~á YøW³<´G9yqþÍò°úázó ;Ÿñý9Bù£V^¬øÐò—j¹)Ž{›ý {<²£ñ·×á°ÙÉ-×QòmÔMËŒŸŸ>Úé!£‰ÓŠ|MÉÌbèÂCÏÀôx8®bg©õ”s=[X/ÃôÈœÕ Ødó¸µÑÄLªìZ’¯mz\¨;æùIîþ¥ÆÊ³ÒLШ²¸#óÊTO=9!í‚]¬ø™œ.§Ýú s‚‰õî–ækE’³E±d:BÌf!öÖ—§Ï-½»¥§›"ÉÉ¢X2!f“?¸õ5=Yøº;ždêdÁgb›d~$6MÓ->TN¿rØÉòì%<%M%zBÊ=Ÿ´ ˜\6â·ÿîù¤…ÞéIŒ®˜– o¾ç“z+‰éM5»G¾ç“º*1»b¦Ð ·ˆ$Þóy  °×ß2“ü|ÂHì Š®ßlö>Wo[ú J~¹ÚVîC*ŽÍnïîýæõ~é§ËýÕöêzµ»:ü¶üp9ö‹Ëí¤›¤‹'ß W}ÂíMz$IŠ¥¾s|G´äŠyoË$ÅècîˆàÊÜÑŒ¡H’1K\G1: hÉ "É«ãaª½-žƒïþ  þ]Zf—vZ):Ia†>Mêâ7&Œ ÷lçPxâ¯ßë<Wp­›õfù–Õòâêòr³3×9å,|c)Úé •¥èîÅM'îêƿӿ×Ó«n¾™4#îÛ%·ô󖇫ø¿ëëð1¢ÛÁ€ä59bèVð% °OªÇüm |õÖ~æïÕû 3nÝE[ÕzèSNWPÄË?Pž@œßj‚*-û•ºTíª¾Q@B»Ù‚ZV_‚šŸ¤ÝìHXü댡bÒ¸¹[è'ôuúË„‰¯þF9 endstream endobj 21 0 obj 4228 endobj 19 0 obj << /Type /Page /Parent 3 0 R /Resources 22 0 R /Contents 20 0 R /MediaBox [0 0 595 842] >> endobj 22 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT3 16 0 R /TT2 9 0 R /TT1 8 0 R >> >> endobj 24 0 obj << /Length 25 0 R /Filter /FlateDecode >> stream xµ[ÛŽ#·}ï¯ °VcÌ´ûƾl¶c#ÖÙØ«À^Ãè‘zVŠu™Ukö’Í·äÉ*R-iGÈ^ÓSMO*V±IÎ;õ£z§¥“¸ÐY–)ÝhUi¬‹ªV›Ný¬VêËoúTMz•šýí«&SKÛO zŠDÇ"T¸P3u§’¸–ÿ¡@—E¬Ë&W:ÍbÖF˲\ÇE^×ÔzY§iÚ@’ÇE“W*Ëó8ÉK¨(³8-ËÆK&*Ïâ:ÏÓTdЕè¤Ì‚v9ŒÎÓÓi$ƒ‚.nUÕM¬›ª$]"k’¸ÉŠÂk'fdxú…¬uéW2Ê™€_#±°bM^âÆƒ†™×±Ã˜X^ÅI‘†1‘•qªuži\M .œMºLÀ¾Î½Vࢨ2‘‘•y¬u’=Ű,wÚ‰Å@Œ1ûU]ÅMcó¢:®ëD{åL«‡ ¢ÎAe™1ÑÄ2ONU;ížr Ápx÷b°©2]4‰мÌDfWe­w#ÓÉd@ëDÓŽüVÔY HQÕ¤qÚÀÕKBnXf"³)j]bV¹žˆÕ,O‹ºœv–(Á]®•ø ÁÈ0Åt`Lc£=¢SçUêý#’ FEfm$‹ ßõ$ÉjèrÚYâ1P´‚iÊ+òr'hd²ŒÍe2=%'‘IAëÌõ=…’óÈ´ºŒ`Ü€LO‰»t€Lgãa2½váK¦*‘ùóÈÁb„ £1²F"ÔºŠó2‹ÉŽˆh¤÷¸N’:©´Ý„¿fY¥ã¤)Õd©¾£e’$i4ž¨4·ñ³hTZW¹/Õ—ãq†"0¾S£›™z¡~ùû¯Ýâ^ݨûÍ|µUÛY§f$PWjüõí82ÕåÌáÕá‘)Ã/0üOÝ]·éV“NõÝ»ó°èVo·35ï ˜~¶Þl»~ "ŠKÌøó9€¨Aq/£—§ Z´›·{€NñPzè <z¨=P»˜¿]-;xÏQ÷f4íîÚ‡ÅöÍÑGÚeÂhCN8r”¯'k„/œ¶Zo–@ôßnªn?aýqÌ¿,Ȳ‚Ü•íÌ'½Ìmu7º.â̺:sÒÔ}¼ßt}–æ+5÷Û–&‚¦(1ºÓ´Ÿ/çˆÀùö9÷i¾ÝÍ Y’”ƒ‰À“ÿ©1 GÈôŒ­zö,~öL(ÙÎ@Çl½˜ª»õFMý¶CFz«ïïl"8`íj*ì< ›.÷'c–Å ‚Œ§<ýÞWo®®Uðß|KNkWj>Åœ„£®UÃ,R´1.xuiÐe>­ÖwªÑ:™Åp¼VÖ–7£4NP"¬A—Æ\ …¶p†u&DÀÙgL §4ºüaÁ‘R…Ý©¥ƒà`樜º¤ GÐo/×+ªê›õr¹^©×·\ø>º0Íi– ›\}”±#àó¹3ëF½üæµ³ñÍÕ¥AçÃZ«W«Å'Y,ôêÃk…Vó²½]¿ï\v1o‰öMGéó±ÝÎñ–9G,]²V séLµ(‘mߣ\#ïo׈vË/cõ7[´_P¦¨\Eо?5 €YZUƒ¸é~¿ýØN¶j}¿#_¨¯<7”ÅvÀvŒÕ²~€×K“‰/ÏÝy&ŽsîD…0Ój6;£iÄ­ŸÅkWY®a ½_SÕ5ìwjÚ]r–êd³SÏïÚ~ûœyþ0ê—–½¸¾›o`‡ÎÝúùÌFû¥!çÃRwtº¬¼©ÈÁ1}3\0b3=,g7?abS­}¡~h?ΗKµÁŒ^«Ûnû¡ëV&& j O#á~X ŽêÝ„³I¹Gtß>¬.Íe5¬fÓ óõ s5ì?Ö«…tƒ ÿCh¶ê=v¦¹­KZRHÖasÄ¥!7Ãb†/‡ %ßø߀gd H>A¬©òtïçžü gbH$òM×NiF›0Ç +éÕCOÒõ}·úá_ÿ¢ÉòlXenzÀ²‹S|}ÒØø”!I ¤˜”pãó§ÏÍÚd… ³Í®-UÔïÝ'ZÕSœÑ¬oñE}aŸåŰʴ) ù®Ì$汊ú8éî·&Á1SÀ¨ìp8.ï¶ÆOcÎ¥1—Ãúch5Ì·ŒÝp85ØùšÎòš¾jvö;Öˆ´×ΡH¸pQÛOº• ¹õ†^ 2ð»§hýº(’a•¸y p«çȘóX­,Ú œbó=¤0®níÃ}ð 9iaÄp/ì¹"ˆ›¯i:˜<üêa‹2ÙöjüoµmoØ X©¯¿õ…ÞáFn‚µW‹XC!¦Z†Ø-¥ìµº›/. ¹–Z>{BFæv›hSí@F+Êld¯>Ã̲½‡'×Xòo@-¸ ysõ9—æ¦&|¸ë G'{éþ»!9ˆ’ï¾z=þ*“ݸ0ÈLØh§e´S2E «5Þ…©Ñé°lŸ2XÃއڦ†Ì¦¾›Fø˜"¥»‰Lì3ýÎÛGvy5-Üî1Æp|TfœMé»Ç¿¨Ñë‡+…­èL–-?Müר—ýö l Õsú™ªQí%#˜rÛŽîÜÑ熈F¢—µ±’5÷4ÜâþÈ›hÄ}çÜB ‰dů¸í4؅Ļ착@Cdu ae:sŸ±S6ã†ÂÉFž¸­(ÛeQF#ZXÙpïÿ‰>áT!<ÈSv£´‘î"aÍÇɳVG£}ë¸ïþ›‚ 3yœ–{±“ÝÃú¤·)ܤwú¢Ñ;&]Ø’¡$&"êá»_Õøg¬ŒLª‚SŸTc‡Xèá²çyr?XÖìÛ!y¤Bl硹‡ Û,Ù%¿8 ~—NŸþò~ßûTÿÙuüÕüŒFûSÄN™3P¹A¢‘D€j?Øw(ò.öÇËò„èãchÐ嵎Ӻ.TªkœË§tÂËpâš—eJG»Ò·"Ê7ò÷’¦ŠÒRÛSë¼Îâ ÇÈJ$ÐÛ nxteM\$¸ íò¬ŽéÊt±v'A‡Ž¯m+`Å‘-®*./Ëâ"Ãa"kRƹFN@V3R'"­9PÅÚjŽ<<¾;n£iU8Ý>ôtˆå(d™µ…,»1ÁÚ……{k„b¶æO6I“´bÖC†½oöü'»X ]Â1ÇGH2Ë<§¢]xw kfxÈëªÜÓ"v2p£“áÖG…û#yÇei"·S4>? ²=)X& ]! ðÂËÈò&®5ÎZ¥IÒ7HBÚ£@â0‹Ü*dQdEœá.P –7%¶8='!\Ä¢ÁÊ2b‘-b¯µÒE"óÇ\8oI…£ùÁ¾ˆ_\i‰•bMK,©|@ïöþÜIü™ÆX|aŠÏ܆u ?ùâ3ºFrç£bIoA¢ÝI(pÑ¥lp9)Hy^æ]ÈlRŠpu'.qOMòV[RYSÙ ÃxÚ”Ú·‚ÇMႸáù‘7E\55åJÎx^"ó­‚!í$/‰vžìÁ `´ •!Ö8 Û‹ÄéR)KÀ”· ¢Ç÷„.)+,óÚ¡/dLÇ1£rÀ%‡ ‹-ž`' ˜ãºày³ÆPŽ™w{ Ï ¼·ïcèò sn#ó†#±Çn÷¬„éŽ:Ö8tÝ¡E’ì|+—ëHÒE?ÎX‘E…ÎÊ)&Ú÷ãÐÛ!ÓÎÛÆFfš#À[ÍÚI0q‰ |“bmÆ+Ë|\øvœžÈãÆŸOpR³!@פAò Gk™ø6–‹;ÛÆ°Ð”Ø@‘´G¼8 óg6c¬Œ“ŽåÏÉ85©–äEsŌΒIäA²Œ"„-a™·–Ó^ ‘ùó´µΰB’³0Ÿö²þÀSœ† ÌŠ‹“߇wt°³ÈŸ˜çäÚ`q‡”çXGÑHî Å%<Iðö¤l7Êö­ìcs“ã{œ²-›†{Û—ÑhûR¶'~SÔo(ör!o¶h´·‘~¨›ì¦N¹à|ïÞ§$Ÿ†fʨÃÇvS£‘è|‚AhÝÃâ÷¤…½p›Ùoªžä~÷G ¡û)Æäo ¼çÈ1sÔÈoàÐG#±+ÀìÎx£ûtÚxŸ^y¬°w<†³4w„&Á&giñ•ÒØQ#|Øì(  ŒdSzqðRžäDfÐFÞ±FÄ–=|ÁלøˆeíòêëÎ;˜a\Õt‰FÉ6É é"GLGãFqsÌ ŽFäxËØ„yîÅ|q"ÖÍœ3ÿg0s*ün/Å`æDöW,–i!ó]^M &¯\¯hô–-cnÅ B®ÆZöß`Úà:Þ„õŸ0Ñ¢‘åÝÈýÅÉÜŸÓ¢òZD1wãK"Af徂 > endobj 26 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT3 16 0 R /TT2 9 0 R /TT1 8 0 R >> >> endobj 28 0 obj << /Length 29 0 R /Filter /FlateDecode >> stream x½]]ב}ï_Ñ/‹¥‚¨ÍþîÞÀb¯'H`d3A60¡GÒlf¬˜%οÌK^ó[öÜsªÈî‘ÒìÚ°EUß®[uªnUÝ/òûò7å÷å¶ì·U×7MSös_Ž]]õÝ8•û›ò÷åwåg_êrw(ëøïa‡öãÜ”÷©1>Ý…O…xÜy†wåÛòu¹­&ýýÐUý0·åXOÕØ u`FÚ0ŽU7u}¶FªºGPÚª›Û±ƾÚNM JSÕÃ0eW¶M5µm]‹^-”Úk×BévßÌÜ%ÉP‚[ý\Í.ðm¨«fîzã>BœvÜÖ&ƒ(Aï,+iQǬi¦õHîÂ2@®·Ž[F±( øÙ€¢hSÕl딺êºy>YÏ~ØÂ"}+JÍ;àÓhàÕ¶Ußok÷¦Ã:sw”$CàE‹ŒýTµC”ËÑæªqŒ»ô” ¤€—d%-ê˜5MZJäî(Ið‚sþž9MßÍÛÕOÑ_Ûj& ﯤ™_ïLíç„YÛjÛ×]l]Þ¤ Å£“iÉ_çnê{Ü´u7ƒ’¹%Ëü•­hÛÄ+½9ŒC˜ë*±ƒhš0&d Qœ³ŠvWHѤrbíþª”1^EßÁ9»É€¾Š ‘ À²ê¶ }SWm3Z(Dq€Šæ€hÆâN xeÀ‹ƒ=ùÝ0„a`´ºšæ¶³ì;#¨R`–Q’‚‚yô“¤¡Æhäì(aŒCtÛÐ>†= IM_ÅðçÆ~ß`4wCocŸ*BÀ<öI ^ı/šû¢QÇ’Ü GÉ2xc`ìϬz8îÔÍnèåÂDˆòw7ôÙÊ}Ñ ›Ì=Ú ¡•E¸xäg˜cˆÍƒ\ý%3Æ#k_»Ÿ„™…扦ƇEµŠ~šF§hÒâî(ò £Ñw#¯4ðƒ‡Où6ö¥nFsT1Qbˆ¥¬l•tŒ¡Œí¢ó&­É]ß.b!vuø—Ý4…|>ûñßÛj;öÿÝ€Bá0F XtÃX †«(ÎåD‹X¤€´B£˜Üm\K?þ·C5×Mô_ÿ-’^;·ÐOÜûí\Å(m>NФùiÐ1—G}æEÉ2G(fËuc |Bµ"Ç J¡rë@ÉÙRj&_FþÅÅÒB&aþ'͆r DîR<‹‰Æûa¡ÞΕÑP~Ͱ·˜É„´ÅR| È´¨bVHoJé@‰Ü%ɹKÿ…•>ýáÌ(@É|ØŽ€"榔þQOÊËV(¹3åL‹Þš£Ûq|ƒWæN xÉ+D“"¯ºaÛIQ žß-(´†(Î[EsQ@4ŽyðÊÜIñΔÆÌ`[QÌ9ªi»0Ì#é¥ÿk‹µº¶ØÝ—_\•(žÂ[/ñ'äDÄêÊ«ûò³««0¹z]þw¹ùê‡ë%x4åæþ/ütÇ7/Šô¬|nÑæo|ò–nøa¯OhüÇòê—åWW˜#Éœcˆª{øT?Œå8µ€S{O«9îΓ%šf*꾫š íÇy[µóÔ¡ ꤣ€}ñ>Œ^5zš&t™ß,êc¿nÁkJÜÑF”$B`EÒˆ*xÚ –ÑF”«˜Ìs”ˆóàMR‚Ö•´ "Ê4¨Hl0ÛÜ ”Á†b=ˆñŧÃÎñZÙÜ<ÐÖçR®Sé=ÐN#MÚ^§¨z¤'Ù_@›…–V<µµš^â&Í€ÎÜ=\´ÿÛh¡…×±¯¢ÓHóŠ6"¹Õ#ص˜XOS9b1NÝè= SŽ0Ì´àam5´[ô™ßŒÎ:×Èü#,¸G/Ì”ì™ ÃD;Â0“&Ì^¶ÉYsèÝÏãàœ•!iC*”iP‘J£2 Ü=\†a˜5Æ/ f¨l¶X¸‚8ÖênÀšÁ4ûàÖ¤à¶9Ü|ÿª~Q^ýO D8ë=Lýè{°ðɸxË(x åú4tîUß«ñC« {¾¾é»ÔºØ<ÞX!<·-7ß²‹Ëbq[ÃN –\,v4ŽEGʱ¸EÞÁ“*Òd°‹Ú!%CJHB¢ÝÖWcß G†âfìBõe‘Øt"QlÄ)J2.F†ëžÔ“´ó³.$Q]°ÊÌIÁÔxcA´ˆ½áñ|³XE˜Ü‚´„õ¹+Alzˆ)¼‡˜´°"æà$uÔFÑÃ(9EbÙniá0QÄ ¶b’L]D“ÝI€8 Íê«o'è%…OèeZŽÁ¨qDQÔäbD>‚Oñ·ÁãzkGlôî•âoá(@¶rŠ”#¤1g5/e¬õ’– L ‘æÀÉÑÝQ8t>¢˜,w÷ŠÉÕøÛv(\›ÖG~›O¿í:˜ü9áÑ6—®OE[Y/ ÝÙ-üªò]­VðºOøù§¾³ÐŠõGchu¤<°ôPXl`€,»¬$ˆ‚¡ÑÕ0Oݺ|Wv˜þ ìML†P0Ãeâ ëDÈþQˆbƒÉH9úcëž”]ab’‘¨ I¦.Ü£p(ç…V{Ó \£e}0ãu4*´KSPq¦V‚˜íVÀʘPp:AýÎP7Ã,l·°0ILÆQ°¢.$™ºbn®ha!4Ûö˜­0´fÿL4 ŸÐË´ZCm;¸ÒÖäbÉzŸBk‡e›ºAõ¦Ðíjl’¨´u”äÁÛÕJ¡Õ‘rh5æ æ¥™X B¶J^š"ÍCîWÄ0¦§‹K[„Ö0O_ ­Xó@qßÄÐZ¤i»­—V¶¹+W;Ç•±-¦$aa ÷Cëæ?,p‡mN-K<µ‹ÓÒN¡}–ðæGì‖câ2xåý-Ј»QžØÅI¼â2Nñ‰»8ˆ¨wqâªj\É}jç÷?Âf°„å»e¥£;²SuW'ÛÆ—Í“Žœ©ó¤6/ÿ`m tj‡¼üC?úiœ"•‡¿ÜìnoŸ}³¿ÞÝݼ¿/ﯸ½ÿ“r÷îýwŸ·øp÷þðp³ÿ<¾¡¿¾:ìÞío>¯«m&½(.šn‰§v'"÷ý‰ëßì_ín¾ ’\íßߘ »¹}óöáóþ'åõÃn÷pý€v»ëðOøøïÍ›(o‡ü?üó¦|nGޤ#Œaüåw·ßÞá]øóöõ»;üZD˜©³3&XhèŸ[d,Á‡—ArëŸ_ßÎÛ°~ ÖÏ,2¶NDŽÆ<ŽYgÍØ—,¬.£hXX…Y¸°Zpaõ*OíU.ªÖy ÅFšìïµ"BÙV Øêˆ-¤bBDjñ@³•nWïk»S~”¶ó„Í!¬ï†úûÞÓpÐcÀŠ"žÚa×¶ÃåÓΚ„M§aêŠe&v Œ6ˆz̉G¬û²U`…uã ÑZô=†c@Cf^¹3Šx±jº¹;òm S1ì%ˆ{ èv/Ê)A.ÉJZP1+D’éŒ:,0‡ŠD‹"œ¹ÀíðË8£‚]ró8ç>×Ä"ÎÔÐãLá=Τ9…–ðK˜¢T´VÄ>ðb;™_8gû£ q¦GxœÙÊáL’á æÂ9‹+ØÐ®ž¶8Ì”1̾šh´HÂ0Ó°ï6b :˜¶ë±(‚=ˆ8ÑÍΊù')rV,ˆÂ>Ž‘‚õ=Î 0P`ÿ%ûeÀ4¡£Í=– Åz(Ѳ« 2E®$%-A˜ô!Íaƒãl`}5£¥!ôÌ ,arµí|Šaañ/,ß}äÚ6¶/&h|ÓÖ C¦Âªs‰b¨š(Qü8i2Q@V‹¼äRl>ËMÅD‹à⯗Èî›üÎUþów\$gËÚ‚õY@¥$_¸©RLòž§»§°œ£|PšØÿ5km‹GÒHÊ.T;’<í¾þáÕzs“^ÿ”Twf7ô”ÖKu ŽOm›p.´ûÐ-‡Ñp8ÓípèÕÑ,nõ ´˜í…é\›òŽÔVCØä&ã´Ù"6á jnXm±ý>aûX4œÓÄ9ÖÂó²aZ†¹p4ÅÑp4¨FP3æ âN;ÔàE2%ˆ%QI R!ÒLgž Ü¡¢ÐÊ2œ›êÜ› g¤:G3¬j´"¦ŽhJï&m ¯T‘T¬•³¿ÐO&r@Ó²4=ÂÍVhÒ 2 Y‚˜êëkÂê#_Ía(Z˜€aÛ5ضßb6Saæä¬5Ž‘Bg­C^Ë­¢‡µXxÅR™hÁÆm‡t„V;vQÑ”­\»œ­p γU2=&ò¤Áþ([%q±%Ts)ÏEfÑ”˜­2™"‡0š;jÇleÜDÌV  C¦¹¢›YI R#ÒLkf+GÑðyæ©Ù¶6Âe%+,I}b²ŠSDÓ)‡R‚KO) ç¹…[S4¿$=%f9=Ÿ–žJŸžÒªC·fBZúSÜ·uGÆwþ™SÍJžb ÁÃ~ø@¹Cé*µ(66QþnÊMz´‰¨Ç÷z 4#v@N]Ö81C¼cۄ˰!Ž×¶Q0œÀÀM×L?ü°ÿ€+„¤Eü° — फø»+mÙ#£æûÅôÛ!iØOÀ L×Yó ÷TãBƒD %»iU4¨H…Dƒã›Ä¥¨(;Ï\` ÐnqÅúxcõȪŸXà¦Ð„Ëœ­gÿ4‡ýEžÓ*Z@M©ÜÔãk"ÌYÊ åúv¥D:\„r%‚õ[+y7Q­§ q-Kþ¯}.lqTJH.u@D”é­tQcÎ…UçØþïAyL°PBµ>EÅäÊ%ÚÓ+ʪ’Ç0ÉŒÚX-m‘{eµ9clb=ÙcJßTÒ;2rqÁ½¿ €‚¹ i¾`.pÃÉÖãwKK:0’hË&ÙØ¦àÓÆNld¾ucgG%j}jl[ zÌH…Õ…kNÒ|³¾[bܹçPl¤]{1”×|ÇÅd¿ø½<0†X‹Û=ù’:¯ýaC-\Æ5¦Pç^þÍ7‘±ಈ.ú"‹ðj¾h ä+¼a4\-&¼² à¥VXÖÍ—ç I {pŽ;¯õ2Ý!cBÅpµ¢.*“–t<÷ò¯¿<ÿ¶<>5¦nxj¬Ã±Án ·_;5\2ÜÄ£#Xí7‡³Øáý=މá8Xùò ž ;¼z÷úΆ^ýíöáí«ÃíýíÝõþöáï¯~újÿ­úÓí;œ*ûû«o¯®7ÕëëÃÃuùÓüúóÂ%ÙÓCXûÉå±äìÏ<}uÕ.ªÒ/ì2«÷aÔøñ‚«÷aÒÌQ Å‹±¤€×G^]-uU>,ŠóaÑœ‹¦‘»¸ºZèúl¨þ}Ø^GÏáäãÿã²åã>üóKÝøå7k^ÿÜ><Ö'"¯ «‡£êØ‹9÷,'M7È[¬1f‘­ ý­*¦˜róÔ‰0f´9ãú†ò¦åøï9ûWǺìühwëÄ@­¹ àV.\š &¦m_¾W‘A÷‹Z‘ê»U­@©ñJéÄHY]}+5Qc|Bßkñ hü±àÅíK²‡ó„p¦d0´Wýáw4Ï—üð+~У°†{^n,Kèy|Ýf•Ç"ûÓ¡ÌÖ‚ÈGõc¸!/Iÿ“’¾üšŸÒ©Ø‰q®oS]° ˜Œ¨zkŸmVl´ð¦IÜâÞ×Ygi»Ü ur‹3¾NzªöÔ È*ÿ¥1$‘ÔhÕâNᢄ”ÃJC9¬ÖG5å§èŠJóT×…¥{4.©›LCk¹oD°$Ó˜+6 öšŽÆ¬±³ÅˆU$c a¯!ÌwD0©øèÇÑGm:#»Ë¶dÏ7$™ŒÎòY[W›3NqÉØêá–a'ûú°4¦kÎ.ÄJ,i¹’Ô§àûk~Ïà’ ˆ£>ˆ5E>È­÷”^6”íØX`È |Gb±©=8]ñ`‹—‡çЏt:z¤•‚Ê¢Ÿ³õÅé–G¹¶åqZ(`°ÇäÍ6“]ø€¶ Ü–Š µâ2½ÍÜ *ÍYlœ9ó—§,Ì)?yBÏúȪۧ “̯Nr8YËâ¼¢õ)zâ'¹ì‰"–AL`h 9ª\8‡Â5ì%—:•q5¢N"iX‰Êx±kõ$èeéKñÔ6%¤ÂîBü{ˆ‰Èßl¹—²â†&ë©—JPHdi“ô,6”Pòì-—è-=Ô•2à&žYq­dÎ^-Î+%aå’›z§mdX=QB=u¼Œ6cù2å}Ú$Ñj|Å«t8$‡Ur(7.ì°û¢XBš–-l)£(~òe9‚`àlAa šì[ƒT©ÖÌ$5­q¶éþP­V©OY2­Š?ÿã ËiBñ†ËR £Œ§‹l¦$a“Xiò•W`7¶Ð«kŒlybÂr£P¥‚EV!gE³¥:“u,Úç.\¤´´èþ1½,¤<Ô_’VrÉõ8~™™Þ¥–Ú/q] Qàÿ=:ž:ãWËpÕON%“¾æ'§Ñ†jJï,qavÕ£eY¦ÞpH0ˆð[bu/4« [l`.–V$ᥞ›3ÿ¤Ø§0Y *h;(ü²8·ÿð„¿.AdŸ™ÌK‹ —3»Ê|ÉÜKƒN0ÑèÔ…ïH‚EGâöƒ!Á·D‘ oXÝi I}í{”ãAùAÍq²6•€¹ý³éã ž*QØ"_V Kn)‚Úb¸'5™Ä—ÖXsÚõPl~‘u>Ç‚·Gj4|Ú"GI»{}’æ*_–ëm*ÿ/vD›s>Q¡íÅ58ælºL6ˆhƳÆhp>7äù®qÓp Éu•m¼"¹‰|K£ÀâÜÒ‹«óìànÖiXH¶¦\n¼‰¦i†,¬üã“âIâ¨'5M]®_&‚Bàˆ PýŽYE¨±ú6CPß½QóÜ©ƒ‹m%Îs­„/Ê?HRL(äluw&„’QvYH/³…í/X´¾×‘L-v? ‡;å@–V€H°Ç:uˆ‹ &9?1°Ÿ0©™)IZlûmR(·Y&ùC¹Ÿ|X™õ,—ℌ$÷Ö¸þ`,—LŠæÛ†âYGë9¤Ü|“‡-3ÓÒ‘öËhÖ>5rT¢%’D»gIF}³\0xtM^±HE#z(SõžrjX„=qn’Âô â/4Ùåâ¸2æ?áúçæ´¨«€ÌA(†”SòaÁŒ‹lÊ—¤„Ÿ½<‹‘Ü#8 ”?SÿTGýgÓ¸¯Gl{©ÑsDrFO®² ×DCî ¾ógJ#Cp®ù?)Pª×ŒäÊ:ŽšP°³ÌO'¶ñ„>2£±fgÊ+j£\¨ºN†ü`ÈüzE!@jÊœÊêZ¦Wc¥ƒ¥äçäÑã é&UÆrˆ ]Lq-Ý8C8úàW ¯O¤ÜÑõã,|ÂtŸ‰þ÷²;¬ÚQ7›C/M@½é_2‰,úW}Ò3¡( »ÊÆv ÝìÀ{|tÁL-ÇàK*[äVëÿÿ|Q`‡ÿRTŽýI;ÖnÑXÞ-L4žTy(l%ªçWmŽ1y¤¶Ìtµ¶LSÆRïìtQ[úƒªB>µvõ°šÐ~` dp`ä)/4Ä÷i#ë}Ÿv80àðº#Øy{Ixr}힌háýqd;1¨· oñ­ú÷ž†Ëøhœþtíp2¿í¦bÄ©0üÎáü[s|øÙ(ܾÁ¯–'Ôp&sÜb$«N¨á;Û÷gIÃñ8œù _oXãä\àž~ª-Q² àÅV¸¡°§ø%FÃ7òŒáö¸ÏPmî§ÖdzSVÑ #5"­Ö¸G¹’áÌ{3Æk iqsH[ŸK¹Ò;¤)}8³K¤E[ÁkªCºÆ™dЛf#r7;.¬íf«àMÔH4!Mî/yÀÛðæ4⛌á)毤yEÃ}'ÜÞîZãGk¦°â—˜†ì®3®gˆ’@Ä×)uF‹ Îø±ÀY´àb ®WbpÎz&X‘æ14Ú€ÑÓà‡~p:2zã—p—’GDÉQE‹&…H *›ÄÝ£å0¼ø«OsrçŽí[ýñk(-~³wh,éjíY$úÈSA° .×á q·‹ Њؚ?sꨬ&Š×§uÌU.t”nõ®Íj]µ• EPÏ6[³å0õ™2ÍD?6'«@¡žZ2éP@=0ùˆ‚bªJVÍ•¦—j5vЦ¤zZ,[Š ¥¡àRÉJU ,¯eÕ¥R*&dÆ?ç×ÝΑÔe§+‡ (ת­ò”G‚ +ͦ«‡/Hûî¤fÌõ8G¹õ0å”Vå¤Dã«i%ìbgS+å†Èž3³o±µõ¥Åé³H²Óª|°|UM©÷²T½Ë&—˜ôÌCh]ÈU%ñ©ŽrB\©"+Èc啙Š5?ŠÀ?Õba÷ûÜ#Fùâ™ä¾p´g÷gçÄEì¤Ûb”3æÀÁ²º…;l.plБ7ûB“çUø=ÔÇF•ì*Àî«Ôm/묜ÆÉ-~ÿ¾Ä‚†ÁŒï¥ÊݶúÚ¯¹ÎÝâa\LâŸÔý·¿c‹_ÿŒŸtäùW±q±Q›p6ûèu²#{¬Œ¥¹ÓŸùÁï%\v·oÈÚ¡Ú)T¡dÁ¯—…©»…‹F±PâŸè4‰ñ ˜%ü<¶#Å?ßä](""O#S¬®Ç† ÉéF-î_:-y¬køæÕ«û¿Ô–t ç³eŒ§#q¨ó8Òë R<ø.±À˜Š¼ÕvT™“½ W½ó@\ŽÆÓoþ§ˆ- endstream endobj 29 0 obj 7509 endobj 27 0 obj << /Type /Page /Parent 3 0 R /Resources 30 0 R /Contents 28 0 R /MediaBox [0 0 595 842] >> endobj 30 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT3 16 0 R /TT2 9 0 R /TT1 8 0 R >> >> endobj 32 0 obj << /Length 33 0 R /Filter /FlateDecode >> stream x½œÛn׆ïç)öM Ñ<Šâ¥’´€ Ûm ¾¨zÑ0vDtbRq£¥aO®—Óqš-fi6› &³«´y—Þ¦éÅ×ÛQZmÓhÿg»ÊÔóÅ8­÷´»§»ÝS% w…´»ô!½Ï?ïþdƬhp5^ ç³ýÐEùãd>»ŒYÕºúj™FÓ†$ÿ=¹Êÿ Çi¹N/–ËË÷驾>K³é`žêt–SýÃYÊ"óÃÏþP5#ßkD´ÿÖÀ¿ôð ©{‡”f¢ªß‰ô3LwúULI \.¿Ú[ùA,bû£¦Ö<¡ ›«j©‚‰[)ýN™H¼;3° ù(&IyoÐà-VñpaO\ˆ!@Ò R°E÷'éþõ°Y+¨ñ‘. gEºà„+•HÁtˆ©¬ÜðB #é ½L‡&‹A7Å ÚÌ`¨aìI‘¥ü3-ÿšþ¼ljý¨L=%8žVÝÄ%† ü’ UýJñEF×…ä·•<ÉÿÚ¹-ëu$êBM„<0§%šDÞºØrs{vn’Κ'p.ä ‰tüÒ8YÕHÙ˜V¸FN8µäA«¤‰ÂC‚½jNU}LsJ4'ú+¶ãð÷ª$¦¼²e"ST›°è–‰,7)RhTõ1¹}b…U«u_…M/Ã"÷J‰îY&-2U 4Ÿy"jxΈØ)soI 0‹çx@«)b&¥Ž´Y¶ÖªÞ" !”F†&A!`öJ4ž\#‡!%˜Ø@Beú7”ÀOT˜A½Dèá!Ý{2áœnÓÚõfÄaÝÀ‰¬.’ H¬Ò °`Þxy9XF° Xɪý®õÉ+Ùå•×YÕl&—%‰†? ŽÈUc*¶âA*N€!Øž©ÄùN¦[âÒA£)BËÅFT,È.áã`J"7}žtF”C’|:lýK¸·Ò†ùæ´¯k¢pÚ"Ž,( lO.1×j5\¤=ÖÛocäîPYRWT®%*îˆàpº"%”[ø#¹ ßéB¬¶Lá®À.Á+$“ŽìY‘ƒW¤\y—sâb»~¾äœGß—Ú%ç ©ªñÈw‚X)8)‚¡Áð‹ZމßQ¤ÐEªVÕ Gp¢ Ÿ‘,#ƒ*í7QEmÀ m0KfCåwÄ^¨1ré<š)<°ìGµ¤H…÷*:'?D_–ç†÷œŠïC@t¦¥ýŒ+àJÊh§ãM ó@$rQÛàé^qÁ# H±/û›u?OuMf¡ºÐNá¯qÃ|®j|Æhk‚7žÏÒ8¨/:& bMJ¢[[Q"® P¢ô¿~&Ü„R¾å8eË“| _^^šEÙ¨Å@O_Eš™ÊßãlHgÌ'*òèHn¡ÛŠÕÃ#Ì"šÁª®ê¢ÝJ5´ å!_3O›Ä!HYbE I L¾˜¤0Ãrbùô¾›góP>ÒÒXêV4 …‡¿·{ÙVÌ­îUÕoíç€8 \s³µ~ˆÕ¶Š»q}£“â=\w7\~4lÜ/Žô²ñ½>a;9gUï×Ð"HP3àÍUSt‡Û|,°Œ—_êXˆ½´(z.óÉQ,¦Æ0¥nOÌR´~”]=dËVY6S(†z¸˜4OUÍâ"Ä_3@ˆyy:½FâmÈt8ßÝ=´oCô¤ ð”Àêž‹ŸÂ‘Î9!ȆBþ‚!pý“ˆ„ñ&Ë7[»ºªjˆàŠ›5Ð#Pï¬S‹ÐÎά”<Ð>ÑLÁÉÀÆ—ìb~Ù&v¢¬šqÊNçB¨(ü…ãáŽÝär>u­€9D­«Zû/¿8ƒ'ã×Ýx†-‘Á7Š”íA‹WèðU2À‡h¼‘íd—Й*©.N^€úOG£áî¢ý ˆ÷âMôÑðí¹ú&óË{>Ý@þ¡Ë»Ý1n”ÿ×:õoUÈm#nØéÞLÇ`¥3D!!ú ¾ Km› Á'É£çB'€ÁÉéožÇÓù`r9ì±%Èškìý.æùV´§{(¥cFyë–_Þ½ÙÙv¸çôÞb7Ò¼™ÆDÃV€UÜoTbøÀšÀÀ¦ò;ä êâíYÍwŸRas[µ ÿÎÊG|l%[¼Ñ NZîzÐÚÔ¥ú¥Ð)kvâÄ…ú@/¹Ü½¶h÷’­ÇÒǤºýmû@×õµ Fß‘óÎÉã!wq$ÎEß!xvÒ%uÏ ƒdôwr‘å—h‰‰%ZËäžcÒy'îX‡ø`“÷|EòDœº²¯Xr-nd!Â?n_X$±tºUç+ùAyÅ (¸xD7Ê1''Íó”ÄUüÂ’àâúcÀ3G`È/ígz¯=ä¨ch¬&@©rÌ†âæƒ%àºÇ É(l² ªXcT‘N RÄlzûœ¨üú%õ}iÖH-ŽžXæR,"˜¢0¿ŠÏv´_©ó™”¯~]<Ã:’üª˜B/«r¹PÛNGžÉ¶40Q˜ …‡ây£54/ûïn4CrvŒúYÒŠŽ¦¼±x¦º§a©Rlì®Þåâi&RÅ?îb¥ÝG_A‚ )õŒ’D,¨M’KH‹^õ Ó8^ÚÏ ‹{ +@xïÜÒÆ¨}Lо«ªIžè”ìTÇ@ w­£`û bqKš¼&˜€(Š ¹öžÐ‹¯àÍ[GKªAí0à×¢•Q”Ì”žˆ2 ‰€®Œ¡•‡“ ¨ÿâr<Ž_UJÙ‚ƒDŽŒÀðº?ÄQÕU‡4<@@ñx0ÔhðöÕ#ÛN™ƒR  “ÔB‚¦‹™ä¯5EÞ5·A hÈíÐÆ¼,únMõ`'bd.iÕðIñ²/Z…Â!y8 kªD‹ÜSŠ»ñé€ýOʇ¸=öÅé·óNEVÄ[Ì!™ëY¶šã©.Hü»& ´žß¦?o1‰@\¾„?€…H²¹÷¾Méà­JFLbí¬óêo´—5 ãb–!›ˆ›c$ÍŒ[E‹C‘xå ± îŠÕ– ÐÄ—Ás¥Ã•^Ìú}ÙßÉ,ØC±›c È~G€Üd*b6x†ûÿÑx1Nó €éøjvðNji…æDÅÁW|̃ü"MÉ'úø$ 7_ëvCÉf ön#MSñ(n¢.FýÑxt¯´åܾÿA2~yµY xîCCÎɺIuëÃ=3LpË÷TçÜo}­üŠ–7*Ý(&°NF=~ïo‡ÚD脟‚ÛãötbK·±»;ïÉpr{ˆñÄvL-£ØA,n¤'4(UÑøŽ‰Á%8°K×M©þè 6+7E›äZE4L UÖ¿53öv‹òŪ‹¢ Mо´Tj`Ü |%CÙ 6™õ.âêÜ–¤†ðcf}£ƒ7“¤ÑÜ-nwÁŒˆ.%·õ._cÈíÙ SÕ4(ì^\ŸX1ýWГ±¾S÷MÐT˜´ÞK ú7Æ€Ô{¡k¨xYÎàµùÉU–hò=ÑgÓŽ$òSJCadø›ìtøÅ IÜ|j´»7íØjƒUPřĈó‹ذLþ1S4‹Æ?€¤S­ÂeŒ5ùØ  ïP­$­ê×7Ì`ÈßåòoÎ[ü~™Ê\¤È*ú¥z@÷%±¼ðªŽý§þ=QLfí÷¼Uþ§þO8“¦ÚÛ›ÅËs|ˆ¤|õÙÈo™$áC>Hdâ!ñµŸì[®äsMé‰=E«ð¥ý–„ËýoI˜G¶ Oxó¼ëaû­JŽOs­¬lý~‚Í)RRä-K¾ƒi_E¯4lKÍI²È«Ãþï{ÄÞçEe?$ž úÝmÿRˆù¥6Úÿ+wU¶xïAÙþoGN€Â¥ìî1¿ç"&ÿd1Ñ[˜Æ¥]òÿÅ”èVA¸WÖb‡ &Ø–&­°4ΈGNJ¨Æßkà>góÞ}V"Í`‘€A¿K6³¬uá÷í@t6s endstream endobj 33 0 obj 3424 endobj 31 0 obj << /Type /Page /Parent 3 0 R /Resources 34 0 R /Contents 32 0 R /MediaBox [0 0 595 842] >> endobj 34 0 obj << /ProcSet [ /PDF /Text ] /ColorSpace << /Cs1 7 0 R >> /Font << /TT4 35 0 R /TT3 16 0 R /TT1 8 0 R >> >> endobj 3 0 obj << /Type /Pages /MediaBox [0 0 595 842] /Count 5 /Kids [ 2 0 R 19 0 R 23 0 R 27 0 R 31 0 R ] >> endobj 36 0 obj << /Type /Catalog /Pages 3 0 R >> endobj 15 0 obj << /A 37 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [341.9448 236.2396 517.3217 249.0525] >> endobj 37 0 obj << /Type /Action /S /URI /URI 38 0 R >> endobj 38 0 obj (mailto:celine.mercier@metabarcoding.org) endobj 14 0 obj << /A 39 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [379.5828 253.8573 402.8062 266.6703] >> endobj 39 0 obj << /Type /Action /S /URI /URI 40 0 R >> endobj 40 0 obj (http://hpc.sourceforge.net/) endobj 13 0 obj << /A 41 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [30.43069 301.105 326.7295 313.9179] >> endobj 41 0 obj << /Type /Action /S /URI /URI 42 0 R >> endobj 42 0 obj (https://git.metabarcoding.org/obitools/sumaclust/wikis/home) endobj 12 0 obj << /A 43 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [453.2571 569.3755 482.8869 582.1884] >> endobj 43 0 obj << /Type /Action /S /URI /URI 44 0 R >> endobj 44 0 obj (http://www-leca.ujf-grenoble.fr/?lang=en) endobj 11 0 obj << /A 45 0 R /Border [ 0 0 0 ] /Type /Annot /Subtype /Link /Rect [30.43069 663.8708 177.7793 676.6837] >> endobj 45 0 obj << /Type /Action /S /URI /URI 46 0 R >> endobj 46 0 obj (file:///Users/celinemercier/Documents/workspace/sumaclust/metabarcoding.org/sumaclust) endobj 9 0 obj << /Type /Font /Subtype /TrueType /BaseFont /CUDBDW+Courier /FontDescriptor 47 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 208 /Widths [ 600 0 0 600 0 600 0 600 600 600 0 0 600 600 600 0 600 600 600 600 0 600 600 600 0 600 600 600 600 600 600 0 0 600 600 600 600 600 600 0 600 600 0 0 600 600 600 600 600 0 600 600 600 600 0 0 0 0 0 600 0 600 0 600 0 600 600 600 600 600 600 600 600 600 0 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 0 600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 600 ] >> endobj 47 0 obj << /Type /FontDescriptor /FontName /CUDBDW+Courier /Flags 32 /FontBBox [-655 -409 764 1089] /ItalicAngle 0 /Ascent 754 /Descent -246 /CapHeight 595 /StemV 76 /XHeight 462 /StemH 67 /MaxWidth 823 /FontFile2 48 0 R >> endobj 48 0 obj << /Length 49 0 R /Length1 23768 /Filter /FlateDecode >> stream xÕ¼y`UÅÙ?>sιK’»¯¹¹û¾&wÉFàÂ"DDöÈŽ  " "Z´J1¢—"P V âVƒÖ·PëÔÒbÅ6uyóò*UŠáæû™¹7òöýýÿž9³9gžyö™s—ß¼bQ“»ˆH&LŸsÓBÂÿM™IˆìŽyKæÜ”/ëR„ÐÛçݲܓ/—œ%DxxáM×,É—5÷ãÚvÍâ•…û „4O¸vÁœùùvÒƒk͵¨È—i®k—,¿-_Ö–büÒÅ7Î+´ëŸGýCKæÜVx>9‰²ç†9KäûOÁøÄsÓË–çË“ÄuÏM7/(ô§S )~ŠPÔŽ¤"r;‘èH–è Q|Uü Ì—òvôùÚùMn–¶ñŸT¯äÃ=w׿N³Ìû/YNž{§ç5¹Kù ŠrÞŸ5à¹2‡ÎòÇϽsî7r×…ÖÊþlêî¢MÄHDš%*¤CHé`žÖ“!Èב×â5µ<_CZQSMGZÅë+y}†ÌGMŠ×”ó4A¸ÊhŒ—¢dÚ#¤i˜çCü™AÞÊzŠÔÏGõP7ñá>¯cy‘ºx_'u+ÑâäýX^¤v2iÏÛø¥ÔŠ«Œ§"µ·yÉÄÛŒüù2 ÷詎œC?=oay‘jy^ÅÓžÓ"âD/–ŠTI¾#Å()±N"Uÿ#ÉpmFIÎûËx*úI¼$òT।} ›éE½«Î®¬ÏyP»_ƒË‹ Iô&?òösä_äN´Ÿã%–ÉYb@úùžl@˼åò‘PóO2u¬EDzêþIÎ`<oÉ?›zAkêøœx›Èó"9MÌ¸ë¿øxÝäR‚»ºy‰åEÒE¾ VÔuñºÿä=þÁK,/’¯‰ éWdÒ/IÒ/È߉÷°;EžI'y‘áW†¿ñô¯ŒÂÈç< í"ùŒçÿÂÓ?óôOÄ„úä#'xË‹äÞò1¯ùˆì'Mý#^:ÎÓcù5#Çø °õɇ¼å<ý€”¡æ÷|”£<„×ÿŽü[kò;^by‘¼O~‹~2\ÙÛ³¼HÞ#ïò:–Šä0£tÒÁ8„¼C~Ã[Þ!AVêe«ô›ÂüY‹È)U$o×Ƀõ >ê|5_'‡È4Ô±)[ÍC5„:Ö""ekÉjDr°0ïƒ$ƒR;ÇË«|´Wxz€Ïëe¬?/óÚ—{ÿ€XHö‘½üöñ–}üö’—ø;°íì^"{ø;°%ö{ sb-"Ï‹t‰€ê›YJ^àkúk>òó<ýOwƒ:D²“çÉÓ<ÝFžc|ÊS‘le|J~AZ>KžaòW†_–ÉÓüž§ÈN,Éf² µ2žŠd#ïñoÙ‰Y– |¼G™”!?çí‡9M³T$ëï’‡H‰¢÷Cœ+Y^.ØÚ¯ãé<]KîGoYËŸÀò"¹·üŒSöN÷’{P'ã©H~ÊÛïÆ»ˆÀ+$YM~BF¢}5ÙË‹d%¿ÿ6>î­üŽ[È þþ·ðË‹d)ÏßÀÓ%d1Ñb”%¤-,/âéì¯'9¬¿H®#×B–ÉpeœÆò"¹†Ô"]H¦sÞ\ȤYÀŸ:ŸLâ½çóU˜Gæc22Èò"dÎlèj®å(±¼H®Æ{3>a©HfÆÁïbÏA=ì¦FŸÊ1;…¸¹<œÂÛ&óç_Uèq¯cï"bÕÙ½I _¯‰¼taÏçÔ>Žß?–§-dîÃ[/cz‹ŒæùQ\&Œä2k¯Î¥Ø°ÂØÃÈmèÛÄÇÎb]™äÊòû‡JCù¬E$ƒyÚÈÇiài=Oëx:8.Åýƒ8&k O`u"Ï‹¤ŠUÉ{gxšæiŠß‘$ ô¬à5\ߢÌðçiŒ÷‰j"ð¹‡9¯„X¯¦Ç!‰˜ à©l}œVý|O½<嚘¯†|H¼¯‹S…X‰£Pçà½íÀw£Ùy‰åEb+<ÁÆëØÓDhö¾žrí KÄÀ5KEXA:`ZÆS”«¦—áÊøŸåEÐVž{Õ| ÖŸqKEà¾cËx*biñ[r¹¤X° £É*Ðñ~”·çÉa¡˜>N>¢Cé«äQº–¾MçÓµ¼÷Q `“ }[R ]¸ãÔ­…,>Jÿ& í¶‘?‹›ÉJq(ZV’ètqì¼¥’‰—·¡ÏG„HubyœÓCôý3]GvÐ÷(ž.N%ßb¼µâñÞr­d#ߊ•¢€'=Žgìäc`\Ôoº•~J»Éb¥ é TEv ñÌ[é9ÈðÇÉZZN!С™s¥gQw7ä!û;§l$môw˜wàmq,ú¿€Ù¥v¼ÇQ²Ÿ.%óE%½öbŽž5¢•]xþ%…{(| Á KŠa  )‘¾—¶æÿPpoÝxfñJÝìO¦!+;Þ}PÛ&7É'Ó÷„rú*}˜ž/X…6º6 !6:ŸÝ%£ß#Âxq5i?l°HÚ0‡»é*i«°MXˆ’ 3YO7 Óq×ãBdö*¹I*þøjÛØL…Ѳ£²Á2'æü¸¸…®·7¨œØp]Ež—¯În¥»½;þÉR`m¾ô,ÞôFü-¬ÂXS¡ãNC£Ý(*¡Ž²·Å[[©b†)Œ±˜ò’U²¥°µ– ’e<}ØZ ½ûÞÿV÷â6BC§² ¹LÂB’„G·G^6OöŠ©žßNó–'=:…g™°G½Òójoï„©’]6m̱G *÷HAÿçÿ[ãç剖 S=¯Òá#š ÃŽ˜ÝŒÊ+§â øÏªñ¸Íåx3é(Y`W9à¨tTPJGéÀfÀÔ±ëÖ|•peù€çóuä\ßÏ÷áý›Qfc“Žöæp˜›¯#3 ù7p­¨^ÀÀT@`=€õŒqÙ»z»Q¾ÀÆŸ `}ÙsÖæv®,<›å§ð.üØ|öؽ£QôëÂu"€½Ë{˜?«;ÔäýfŠ“ÓÅ({`›ÂéÂ? $H~9«€VPBKÀ‡æPA§h-ä2@'™à YP"ÐX¥ÐdeÐl”œÐ…쟣{a³ù‘@£†H˜×ç“.Q@ ‡Ž.‡ÎN’IÃ6¯D]<ÒØƒà#Õ“Ò»a »¢‰ #ÃÑ£ðá߈ÂKú€‹SôȸÓB£p‡°Sø­˜ï’tÒVY™ìg².ùÕò ònÅ0ŽŠ?*¯Wv-/:U|K‰T²¹ä+ÕÕõ]êßki¾ÒîÖÅtÏëºõýhýqÃÏŒr㫦‰¦¿˜·Z&YŽXŸ¶~_Úe{ÖÖ]¶Ó>×~Êñ…óv—Áõ´{¶ç6¯Ëû'ïiý@æ—ʶaÕÄš-’@J™ ‘ä‘“GÒDwüÈñ#)£Þ«zõÞ…éY&Ú{þž{\¡9ûíÍr¶tCÞ»Gz_v+Ƹ’¬ËNóT'¢’ß5Zšt…Z£¨‰¹^M?õ¶ Gj^j&-ŠI%5’F\[åÄ+Æ52;tHMu&EC·«Ôj¡D£.†8ñ 7kí†áb½]4LÒï<Þ©7ÔÕé­uHÓ­Dב9ÞØØ•aiGkÖÌz¬u)ZYë§ê÷…ª«jjùk¥·ÖË+*½Æ!´2c1›ä ±²ž×Å©"ßè÷ŠýÆ Ÿ|2ý“Ü ¥ÍàJ†ÏÝ^Ÿ‹OÏ}ïöú´r+<Aøù'Ûv½;.Š>tù|®sÓϺ|^wî³­Š2ƒ'*Š|"˜zz~g1û’JN·8wËáðÒìNY,åæÓÃf‹ß&WÉsó=v‡§Çíp8s nîe’HÌI§ÁVpP-xâÆlVò–Äo¼É— –ÚµoÚßnzËüfCÑ›Á·“o‰oVlx£9¼¥.9Q% ª!rU¢Ø¥Ì )V©"ÊAÍ@tPÝÙ¥ëqtÝD×u¦ë «üþ‹nP\§¯«kMQ“¥2SS]òûäb¿¼ìvû­AUM©¾Ø//T¶¶Œ9slKë×3Ç²ÌØ™Âd…Vns[ çg+ÕòRdöo¿ë'Û·­^½ãkd¶mûÉ]Û©ªùª«šG\9Ixdø¤+YæŒ(ºlz·"÷OQô”ê]ÊÜßWlܸbŦM☛7³ £Y*(Å%ÂaÙtH±@Ö¬QÉD‰¼¢ÜgÐkŠ”"‘«É ;Þee“îéd¤ä …EPQÍXœ”„0Ýf‘Ü¥ÖYÖR·d±‰Kl!ºTUj³•ªrëC6<ƒnÉÝ(¦¥Ã…Þ¬^,Ò¾gßçRãÃr*×›]¿µ3ÃP‡€ å‚Ùd±º((´ ÕU†ZŽE1=\ß\—JÛ¦uî±™E×O™V?7¤3JÍë¢ÏäÎ>tÏ?o¶Ïl±5ÞD'´ï¢•ÏšÍßaó…w¨ÌúŠDû{Ú}.[‘M´mÖhQTŒ£Vå3üŒ*‚—j<ÓÕÊ8«§“½ø¦Æ€µ WPÌkgµÌ&AÁ9‚nn6 ¯OgÊ&›tÞ¼Õ´iCZC:SîiÓÚè³´¨í®î¶Ïb²5Ú˜{¡}WîÈÃsg–qüÓ%¹7Är::£<[VjЗHšbbÓˆGm¬Ö'J…Íl»°G²…BÙ0¦Í“U’âÕi-=­,sÿYk¤Ü7ŠR¨PŽÔéjõUE2â|‡Ö ˆe ƒª¤Hm·½RHB—y³¨“DIñ!ùƒN«T©DÔéŽwðÅ?Ãßè &*½lí±6‡MV«Il-sé›åz£Åb¼ÞÀŒrJ·ö~+Æédð£)[$/:¦’Û‰ ÓÀBŸéJû=ݺdÊ´ÅK¦N]¼müü¹&Ì Yz´÷3(_ ççÅÙòvi7¼¡ú¨´¡¤AQE«d-%-ŠfÚ,›¡Ÿ¡žd\¤_¤žo|²äIźA¶«d—bÝ!k/iW dïÒweŸè?QÿÑøGë—ú/Õ_¿²ŠfQ¡u”âuðVXéΰ4(Ôg¨Ì`µÑ'èu,¯× ÂÂewݵlù]w-?ô駇ýå/ÒêÜé³ÿÊýÕÿë,Õý8›Î£Õ´ŠÎËmÉÅß“ùõ•`Hœ“)¡û›²¯®±[Qý†[ßQZì)5˜uÄVä––˜KŒ–g§¥"‘ó»#‘Ô´RZüÎÒ@ÑQô»~|× à_Ä)~È,¡­xϿߕdMv^@»ZݾÚDMÎh°ÃùqÙV©n—­RþÌ·VzFù¤l³´Ùþ¸û)Û6í6ÃnùnÅnånÙné×¶íÁvåËÁׯÉ_³’ÉÉDe*I)}A…G,V$oÇg¹ç§T¬¢ïKa¯7¡ç*—7ís8ªèÈÇ­©J(ÃCЄ—}¼¥#÷Ú·ÄË!Q+Žs3‹’½Ÿ‰gŸ4y"»œ8ÍþöTˆ†Îv³¶]%ÿ(ñ†9#•›Ê'&jfèææi®ÓݸI³Ê´ÊµJ·.Û†ô†ÀÏ+6ÈÑl¯Ø–ÞFŸÕlW?Ø£ÙGö§÷Òý{o*½fbó(’ÅM"gGoŠ QÍclE®ŒîLGkGëñV+Ô ×ù]g:˜fÊã,Eûf^@åuQ⳺ª¶â3Ç‚òç’CVÜ}öðÆoânýG3o}ìšéöĤ‰óøÙ·Ì˜ô’ÅË.ÚKÛµ˜Ò'†ö Zª-Švø>.ú(¾ÈºØ¸H¹Êz‡qƒíaý6Û³ú"Ÿ+ê'fEH ILœ7ªV«ÕluÅ[`î­ fØôñ+æþ}k®£5¯›™Tä,!]˜æ•ÌjôyáÅôŠ—®vSå‹_çrïïü[ÌQòÑŒŸýòéÛ¦ÿÚà²E+é¹T*S‘k5¥Öïö¿yvFSYtÜ/Vß±}z¢ž~ëu†ÃÁh^F‰=\FÈœìݧ2Ðb†Ÿˆíf_»ý óGAÉoòO²L)Ió…ù–UÊUÒra¹åÞ²{M÷êvøur…Ëg •Âà-uug:{:uÝ}Äôò6Æ%öE¸îýLBd³‰qˆ@×ÿtáìU«çÏYm©¹wüÓŸ~üËÃßЫ©{Î[Æ'Ÿ>L׬zòç·Ü¾ñçGŽì~áÀÒ:*£“èSŽpV E®\/§õz»Å.¬£³Êº¬n‹TæS!À­Su”},ô_W²†¬SmVm.yŽìRí#¯©ÚKŠ­–2ѨöÙU%2ØÐ.¥Ú¥œm¤F?[¸Ž‚8ƒ*ÉËÙ,¢¾ŽÙ¦A yÔzûìË¡l ZF!¬PjŒúQ&«(Òµ9I ø}^J‹!ÄǜöâS©F§Qj‹¥x²Ü(.–¦;\6,EØËlò÷ |[ ¯kIö R$š´ß ì3ˆŸ8Ú‹,íÚŠÞ–(áXXíÖIÞöÅóó½‹ì‹Š—;—{WÙW¯S®“Ð<©|R³Ëº»Øbó…ÊëV|r¾^]gz:Ù¼`Â$ä ’û¢´æúƒpF¬1¹‰´)Ž©ù)–飧s¿Èý©uð­—W<}XvÏÂ9·ýdÞœ»„™#š¿ùõäçzr»r×8BYQ(rÂq=y[ÈMbŽy]‹ˆ ³}=Y]ÑqQ{Ü|Lü®Ô ·«H)l™.f_ñ÷c¦ÌÓ“ñ—`Ž‹Z¸O G ê8¾ —a¯¼-†ñ,†Ï¦l°Ïb j>}Ç߉GQeÎ.r›9 pÛmAÝñžã]LŸåg¨Ù/ V ôØ¿±b˜“Òÿ;.*u~ ÖâÉ)e‘8 <&Æñž7Ü0mêâ3^ƒªH„ió¥Nƒ¬ÜP"—ˆÆÏŸwùåóæB.5“6i²t5ìÏl6¡4•š§ÉXRLáê)¨õSÅIWœL ÂeÚëZʤ –™¦k7a ‚Z[‹.HÙ0í­}B–XXø4ò»5>wÏß%ùÌéJI´ÛC·?”Væ^0GË\b-]FÅX&‘ºD]âsÚ£,’(…t´P¼Ñ;‰fK5GÌŸ)Ž¿8,f­F© Di‚¶_ϼIÞÕÓ•2rî‡Dã\tii‡x·Ëëuõ¬v{½î~yÁöB¡@ D/! ‚Ü^A4¡MštWťłÓ\À••*>µžtÈ,"ŒÔ.(¹Ð¢ –IÌb†Ÿp)®.Ëö2—Pô‚—žV„ü.mÐ!Ú%åô©ÅpVUêò‡*„•tzìø_š‡/¾núÄôm7´ÍºáÆ«WM¿zÚ¬»¹%»Æõ·?uù-¡ðƒ‹g<žrÀõÿïý›4Qz+u[vª2¡,fèéWé×é·?©.µÃ¾/õšù`àlùÙ„z¹c¿C Æ"•h;쎨¾6vˆ_U싼œf$²†ÌËK—›ÖE·•ï//ÒYä$í+²¨ã©4s#:ºò¦,\ ¦Åße¶¬¡Ö¥}2ÂRÍ|ZXeÇä f›å¥0÷& ô9ŠâÖâ€/è’<Ña&…d|xÎKŸØ[[½ýj“;žÌNÚ}õ¹7èȆ­•î¶[ƒæî*Iz¯vh[fåÎÿéO¹ó^¯fxÔåªÔVÑVª£j:ßÃdÌÜÞihB…(ã´l}‘UÕî;bfÒáêTÛ•v)®ŒK ÊéW¾]á×”¯IÅZW©Y²¼D®TÚ U5ÑZ2ålñ3™3]×¼«+s¼K—k<œ º0¥B,D¡/ðÁ…o3DÇ5ï<ßêêúþï_œO¦ÍO—ƒñFƒ®±<Ž?ýé¿häª+Z>ÙešÕ&Š'¿é>!ˆl¡Ã.q'ôçÞÌýךÎÉãGIXãa õ:Ìk0y0;!R‘Œ{n³®¨²®¦^AÝî/ãÝ$IO'i²ËYÔnû‡®3­è¨ùO2Øà0ëŠTRJžt8ãH›I˜žÓpÊ¥­3W«%erˆ®§SíAhm©®;ƒÿ}ÞDG7#s@ëÒÎ Ê1Ë«®çÞ[ª2Oâ§N f êSÄóÆ:w§ÿgÍÁd —Ͷ”Cåb½ÏÏ8ý|•;~»#°çÎ &ÆùoýýÑpWU$1n}îÅêšXù˜ƒ-±ÔnÄÖq‰h]O \Í®fWƒàëµT'k2‘PÜQªw‡¾Ìt“zº†Ötôíž”vjH‡BAÂA›ßQjÐ(%] •Hu8]áO;$RAOWЊڠÖa.ÑÕéNvd:8– 8–¸8àR©~.ú¡ªI,Ñ'…þrtò¿¢J¸: |9£/Nz‡øÄ>¿ßsÿœ*Óî 8rgÛ¼0èzD."¢á\2…á¨ì²L(–Ë„2—9s#€›¹ÀÍõÀÍH²2;Ú×>â‹Ê€GÔ·ÇK;‡WkqH§QQYÞX#U¥†Ž¥ˆ_[Tjt*OHH"ÙÈ f¿¶.UUå”y‰¶Ê¬ªÒeF!ˆ”9ÒÓØ™Ñufr¸äɇ9øy`¨ÛŠ&–t3‘ÉðQ°‹/ÒŽ¯¦CÈêBMᎼÂÁ^zëð†TlÔŸûsÔ‡â5-åô³æºtùÔ÷ÊÁXM©®1ûÁ‰ªËÒ9o›'u_d0w4âÉm£3}Ð*¨õö¬êÓ/ôY&Wß®4À•ÔfÝ]»•Q‹\£´ê%m‰§LN$§XçÕšJê´~ÝI0P'¬)® xH£+“ þrIß„ôâããâñqç‘ „ãþú×–ŠP¨\˜Æ(oùk›3ÂÞ 1 ,kÐDÝ=lSïV‡w»ï!²1e‰œÅ ¹ÝÑ)†%AwÈç°Õ’I‡_ˆ¤åõ6]HkŠêNvu@¦éà°ôÑnžpß…:CØ»`A;)#MïÿÏ›{ÅÏ\1˜X¾žµÉ@ >öÎ;Ç0¹FßÁTÊÇîLôÑ–*r¯øÃÿf2šHocMdsöFY“›Hæ¦$ 6U;«ƒˆ5Ue›ˆ55g/·’7o÷b#*p9›¨Â;Ø[SÒ>Xê¬ ÙEuG¹)à"MTæ –fN²QÕàÐꇪcÙPPSßXÓ <$¤M­vƒÚ•é<ÓÙ©ûB÷E7»B¸åm¥<¥fÞ5°8d+ÅŽAÁ†S㥜LKò!«pÉ@ó§° Án´ ×~¢IWlóx£µ:‡µ Z>÷e},3*n~W›HÄš÷ Œ–r_g›,N]mÌçÙV‘VÓ.áæ€Çï 9{nvFÀݨ†™çߎa(ahÏ6O0âáˆ}Èòú=FÞÞÓÒZà´¶À ·Ú»Ð{]ƒ©¯ò6xdeÆgh9:u¤£VYïiðZ†«ÃüádU¥lXC¸R]åÐ55êz;;˜Ÿžãx©«#ɶÆn¶ñ¬ÀŠ|“‡Ø¬c¦"Ûüƒi¨ëš–&­Á>tåýÞ ü]™âau+½ 0/°7‚aJ'WŽ©©ˆ_vôm0Ú&5TÖELWWmôlxTM:6ü¿R¼NeO§­öó]~fü…éÌñžÍ¢ÅÏ™<âéÑ;-%âcàŒéý\ºGz‡ûƒ³ U‡hè(Ú'¾\0¬q}\Ý ®2VYô̾·ø^A¥U“f³ZžbÔ3ý¨:â÷å­By"©J÷äþðÍ?rЊîohêüßv¾ýöÎ]o¾-LÌuç~Ag#xi¢­¹gÏ«(ýë_)ííü+GàÝpšë+%¸ùêì`ÚNz+…¥ßi)êІ|¡À Å q‘b‘¸J±JTºmd5j‹”BÈ#ÇÑ3µ_&Zÿ‡Ñ ‡*‡Žbû9aÔg­~ÜŠè/BªÜn1^¢’˜ªq¼ì¯=µå©-–t„iõA½Ü=r*ôýໞsÿ|Q2äRËW,[޳ʈx‚PIyÍsè•Wæ>Àœ0§½ C%öp™Â&0³‘MaaÅ-ŠòFi¬ZÇ\‡ê† CËH»·3i-ê¨ÑÕ¤*#v«Þ+ÙLq¥0´.©ŒP]±o¨¤&•2uD=æyÄe²%›˜áÜ©ëæƱùi3ŠeÔ ©†i£›œhë@®IÒˆ´‚íA+4º.¸6ŒlaFö!G¼”Íû+ìü¶ lykAÀøƒ¹+VÐ8¥÷}ð`Ûk?j®OÅês{|H…·¾¾%á÷Ó›ž¨>®í'eQãûÞA1¿oi:)ßj7tdÏ-^0Áž›?s%þ#ìó9ýå®Z¶Ý£8rGÜ!p´\¢þiUyù¿¾÷˜T‰=§áäìÃÑúQ km?kx´a“mƒnKúéÔ3Éí¾_ ßQ×>ü冃¶ý>},â+y±ØPj«—šÜå_W•|m€íßTÕüʽ¯éåfËб™™™ºù®ùÕóëY—»–W/¯[e]e\¡[£[g¼·ñ^×½Õ¦EéUéuiQKõ¥¶_Z^‰šåEÔëòÙ“óÙG6ýÁévZÊÒûÃcbæLÍmsÆNÕ™¬¿|hçï|\3;s)h<½Ø¡;IëÕv³¡HNäŽR1åhWw–»:BáòdÌrú5½h7«‹‹D9±§Í£ý£œPÌ£ÚØ¨d†mÅB/wž¹À·}è)Ø•™w3Ü­K)4 c>’˜ª©fûÙÌÿ6šò®HÑ«/à‹§÷´à.÷û…b!„´D…".¡8÷ùfncžÿ€Û˜›sŸ‹š–h0àÖÑ1A¯7˜;`ðЀ?ÚB%Æê}Ffž#Þ†ùgÈÙqÍæfÛ$ó$Û|ó|ÛrÓróͶ¢2}"#kG2f‡iÙîSt&_®ŒÅa¿?îs¸Ë´E:ÌJâTWÅUƒtÚ¸T¥$Mð¼/èŸ>4°+³Y˜Êö²XHƒ»å©Ö>e{QôQÐÿ°#¹¢©> fÖQfÆÍ¥þ;Ç®¿§z|ulا©@0Q¯9ñ§Ãÿ°¿ô3ñüÉÄ7?ÿ–PëŽr{Ìs~ßwß}÷{è[ìý¶aïw+"“õYÊ¢-!ÿ­øÖòßÚÎR­²Ä¢cÓ3½…f¾¼‘J¶œ_F¶!Œg3JÉúÉ›‹1ü8Fït|ÎÜwîXÌMÕN_À¹ó¬Çîô‡²G!/¬ÿKßaHÖÇÞAAðßâM.¾…ô £QbñRDû˜¨äñJö ­,¤›·öA™¹õWÝkvºü^Uyb1OÚNì49œÞãÜŽßépÚÛsJŸåE¼HŸ•S.$lƒa¢Ç;RÔì­–>ûQ›{ô–[˜>¾¯÷Ké>q?lÀjrOvÊí²u2캙SüJ¶M±-ø«ÈnóËů¹êÕeN[µ:]DT1[TóVì.s5΂ÖÕÖ<{åÏÀ}¥Â¦$súÃbsí5•›÷Þ8yõ åÄ·>öÊw'ëorÃòño¹¡OŸß³?= ”O9rzР¿vjóÔ5£?3~Çš§_ÐêËn˜” 6LÜ÷b®Á Ùç^šqJììN– šs¢é*Èw5NÛ¨qÊÓ‚³ÿjœ'´à»væ7…GøÓ"ÏN³ÓX§pJ+H ZäÈkñ-Œßx$ðmßÏ8pº—ð¥8}.P²‘³í8Ýõ2®/ãªÄ¹­(ú:q£Î“Zœ cã³síœÃJàl—\…žW¢ÏDô¸‚¤ávvb‡³»«Œ¾x¤¬»3o¹¯ÑYk°/x .2ÉNÌ&XU¡0s /8y}¾¨QØÒ¶gßë^zé׃v^ÿ>Uå¾y÷º-£å•p¨¢ÙllÎDÂ]öu{Z·߃îî9&÷ß¿=œëÓ2Á^ÊŒd‰x°!l2cÖ³A{å ½Y•¹Æ±^»ÉÿŒöIÍ&öÄkÚƒþý‰be ÂÑ¢^º¼dVÉ%óË«Kž)y±d›c«Øe=(ÑŸ’b?Ž•7š-“ “,»B»"C#J‰¤½ŠI¦Hx2‹!a “£«‘Dlåq…9—„FxÀŒ)4ÐÛEáÛ|Øæá²GCpC!{Ø‘Z;mË;¯=:|eÑÓt‡sí<‘ûŒzþ8v“8[òºS-ƒAwúŠ+_ýùc¯ƒ*[uØ}ùvjùè•䂽‰ùo@CŸ4Mi±’ZИ ßY(AgZЙ §Ž• 5-RÖ_Ó€ <ŒM@ §°½ ­•¢öê@ùJ½ žуÙYÍ ”I¸NÂu7hz7¨ç ®qU‚ªØiÀNzù ™nF¿8žFý´\:àdâdFe8™ÔÓÓŒsûxLÍ6Š ¤Ç) 1ØÁÜ9Ãá†@kŸ*€Gfî;WpÉ‘¦GÍúÆý×½ÞKu¿»f[Cõ”Êhø¨Ë^žN„<={ö®}`ïKëÚ^0»&¶\IÕ¿ý€/EW»£Œ¤~Üä `ƒéíö¼Ò¶nÿŽã…Àñtœˆv€›^oïHdäÀ² óÛ…µ8€2û>q«©Øk'w)`=Æ:ÅǃªAÛèu kÆ“; wvowauv᎗Q>ˆòA”¢\ÌOiâ›MŒjÀ»×¤¥ð9œœ›'“@•oøÏvú:»zØn4C)è”c¼†ÊGp9FÁ±`Õ —ËMjRî{rNS¸"±Šù]ާ¾¯QKòZíùÂ:í®UkЭ?ugÈáLYÓUTqâSjè%…î¹õöQ(Þöì©™öÔú¦J¬>û"ÃyçEîrìO;ÞZ‹:J,T@]/(€Þä¨Ó!c=ÀA1ÊìÄi%¶aÅha\]àù0jÂÀQ1v;2Ì]êé8ÞÑß_bq<(¸`W`«/ŽSЇh)ÏÂ,¶ç A}8Yô“•¼zqs4 Ÿ¿™¥»·EËc‘§ÿÅM‹*†µé¥séÜh<ÊíX@P'€D˜‡mª@óËÏeªÝ‘ÒY7ÔA„Ï?Åð"5¹¥ÒñiðM-ù¦iø5†/?<àÙb|ÑäÁ©í¹×çÏ!׃ ½}ȳXxçk“°ðoH‰ø©¡5 ç@ŒÎØ72§Ðf LÒÿ€x²„j3pÝ *„ë$\å솞ØU9ˆëA\‹0z gk’xVžå†+ñ´õ(¿“€ÿ0h8HÁ è:ÓÊÜTl’s½Œm¥NÄÖ»q°1÷\™_@™gÍUrUˆœë§—!'ó Î}2Ç¥/ð@…1÷ìØqÏOùKšrøýÇÚ›¯«ôÛorn¸cð†Ù¯ý³çà¸G[ìÎ'"‘̃¨Üz÷êçž[½zÛùòW$ÆŒK¤ÜIíýÛWŽö¯7ß:_W?Úlòû#Ì~>èsäfy¿i4h- ŠSAŽQà8ŠbócöA]_èè€C%(4œ²/jf€oÊ~ìB¾÷%PË0Wœ±o~j€C†3îpC¿ú±Ê¥„FôšÂ×3Œ¶+Qž¾Ñk©‡þ…„+œÓƒl/zX båcá×n¦‹ Fuªö-3¹È¬ â2”#UŸßÐùêÊnc3DäF»ë²õãžøu2“ˆDrß'½Ñ:ÿõ ®yÒßó&s߇ÃÉæ¶¼êµs ÍM‡väÌÀ°vÒgW¬z`an6‹ú3Íh}p¡«s'"©¼AÈ´·Åx¾ò[ÏêÂéíÆbAU'Vã6Â0.¯=¬BœˆB‰}‰c'ÓšÜÀ$ª gz/Pažî”hQ ‰Ñ¤„?ªcT<tG¬g::Zó§FΕŒè¸^}Z„ó_¥Wðïž“Ž†éL¯z&y"3Kmù)0$OZxåg¾„íq9-kº_õ"áåß5hf"ç´v9$¿o=š¥òˆYs"$W=VJÐOù ÿcŒ ÑóGø~Ü3ô‰õ…m6 ÐHVäøj#ŒùŽ@¿ÑxV9ôBhÉ»÷ †öf_6²“¯rh1‚^óÎD_¾—µ£ži¸Yh­Ei&°:æyL€ˆ}¶› îtÝyγ2J~o’Eœ’\æ! ȶëú>Ð3TË%B9ƒ©¾póRIw!€Í£ù\Dæ£Q}‚’{,â‰Ê!c¦G}þÕqwsCy‹=Øó¥ ƒÉf“ade$²Ék¢W7Œœa‰Ý0êî[uCbÿÊHH(o›w×M¹ÙìÄjd˜“îß2¥ºêü &ýÁˆS¸Ûñû­ÁDlð¡;åÝÅ"yù±¾Lù i $‚r@‰ŽCϲ¯7™¥~͵ÖSÕL`-Ø/0}T‰ueò2ì;`CÙpo%_55Æa¿ÄÐý à XLê‚VÊ{}3Ñ{ ú³Š£-¯•LÐJƒ°^,P9°½„«˜˜È탣›úi&„uœ…óý| Š•ßB3Å’ÉÙUS²ñÓl VÍ´p 4S`äšhš‰a6èµ›ûSØëŠ…]SÌųž{~™¸Ôi%#²Uä”V~ÊüƒöXi³¢¹¤EÖB'ác—²t·~·q»u»ú þ ñeëËjQÍ/Š&—òx7¯ùAìþ>0eÞoÞÕ#ÂÂ͇ßÝ´ép‡ðËÜɯ¿Ê¤¯¾¢Áeï<ñÄáÃOlü þqî4Õ}ü1ÕæØ¯ŸdìÃ{`F€ó¿4M „a:aaØNpO6q\åÀ,t F ÔBmtâ&:Œt¢ "" Ôü€õo×0׸n‡M¾tó2®pUBnd0¦c*!é´À“…Læ%ðTrÌòaÚÅyaB;ó8¯ Õlï˜Y‚Üîc$QˆèºNà.H~§ ¸öp gæin ¼æPøìÎ? “¹Q‘hå£qDe4‚`AóöYïSM/yïú½´fÝÞ}<°çÅ^‚`Oöž¤aLg2Ï92wúèá\ËHáÅu÷¿´gí{ÎÇçë¹M^EN"N³sÿfÿ0Á¼¯×߇¼’׆5Àys`\„½Ì,ö«§PÛNp×)pÞП"ð¯ Nà¿2·Àü¼b€€'0²ËÀ,l™Áaª°*iŒëD‰étb1æ=Ç€ç 0Îä€4ðÍd'Cx^…ÿïg܉àjŸý ÿ†ê™(xÔý îK%feÏžuˆÕ¬{ðEaÙ½‹çz©ö?®Þ6Òîz"J7²xM$72Œ„è{÷¿ðÒÚû_ÚÛó]?²%wø÷T;rä³ »'ž¿Å<ˆáý)~¿{ÞuqrOSÔÅ9¸¤ƒ®et‹™²¸£YFÃ}ô½˜ØØ`_Í3:eTjÂúh tš§M¨³u f#vI<æœ?ñÕó‡Ç·ò‚+¼DKÿRä– ÷ ‚DÇ2ëðüÍáH4þBóœT8ÒiwÌúý­Ón¨õZ—ÄÇÿú:œáè3qÌËo6í¾uùèº`ÝàoÃÜ÷ö~-Y1÷,Ñô~w%QõÍ`MõøF·ßæ–ì~‰ÃHÖ‚Vî…,ÿú<…öG¹ `ÇÕAžDû&´o@ûãhÔ¹ ´òkô{ýžÃ8Ï¡ß.Îëj`/ú«U7€ªËv€ôƒG^̦{À‹–¨ûÐ%Û€÷cÚ£”˃¬Ï |WÄ×ÉPufÑÿî(Ū AÛ1rÖ²-M°I«ð5¤ óãK0®câ»E>®«¹¿yâ…—é%Ø’F/x'‰Z×ĬØãe0SŸ/£ŽEàŠëjeá¢>O“+"{-hº2ÓoªŒ„Ô¿‰4©ßþÓÅϸ¸oº×Œ–êÔ±mó®¿ëš;k|üáëãž•J†à£@ß•p›ªo»âêe·¼ó‡·Žï¯{ðzF}½½‰Ð Ÿ¾¦iòÈQÝwïÏãáLfEu²ÒoHǯÌ­‘d÷µÝ·Õl³Z™½N¿ë–æJ‘g›êᕪÉrÀ½€ €md˜r4IÈøîeV×9´¸Q׎š0u¨µÇ°Š!âbÂduA^÷ÅC¸É ï¼€' ®¾/ÿîŠrwkº<Ë-ºêš9—#œn˜ûԈτMúݱPÕUKƒá„Oœïƒÿ”Û»íÚë#NoÚ´ŒñÏžï¦ã|×Ñêx43íw O£ñeô2|/Ÿ&;›=2é(‚òÓ fõº€‡2Ô°˜G€’5>`Â)]†9—ƒÂƒÈ™€-hû¢íZz|²˜ ³K­àFâ|Lâ2=„vË@Ú²³’aËðÒ‡3¶42:äcfi!"y/Ì)Ïc-o¡æ ý›é’ë—-yrmØŠ}rW¤o‚O>{íØíÛÍÍ™pô ¿.ýÉò®¥Oyý¡€7{~¢'Èüžæ1µ/¾Dôœ#…7¦$Úû©ô,ð"¿h C&hásÁ£,â&/P†‹Û °¹¼•[~`+ŒûCÀ„xe_+€)8c2šý L~þsO²°w‡IC¡3Ò@´p=€‰ñ|7¯ a9F ƒ3‘?Væwëñ­ãÕ¼ ŽÓ¢þ[WÌ¡,ÌÙ2, 7¼´.”¤õ6Ž« ÕÑêH$=Ì;`K'ãI›È5½;Œ¾•Â}8^ìfñžóáZ¯gM{»€——zr¼i(4µkÌl[‚ß ‚JÂý fËüðH,о,éTBOÛ€%0–À´$ø5pÖ€JP–½ÙÞM=îcq¡îPC×cô(¹\N‘3"§" ìT7þ3gíò› ïÂbÊŸÉ*ý@{›®•ø«"vä˜ÅW†«’=SÆð|:yàùïžÃbž 8—ÆñËywÇŽ|„+ ·³ï.ŽDÝß‹bÁpˆ–Ô„,z}¹§þù»K"á@TwçöÒøˆT ŠªÜî@æsu8ˆihO.r…2 oØp‡Ký’L:¿“î¹ÂéÜla*‚C.DÔ=Ây#«bĆ(—„ß!Ãé-ðik€¯Ì \o…>¸°žè} ¾{QÇÎü<†ÙïBÝ~\UÀˆ–A?/0;ZÓ‹³^ü:Æp𬿢1# ‡žŽ e=uX)‚ða%±«‰Œ’R¬`ÆÔ †ÙÏl¥µ’iÔyÐsj•XãôÈEÐjKPv 5£$ášEy`6@”|‹ÝÑŠóhº/Î|Q¸ô˜ì[Ü L~É|x &„ã—ax¸×4þð9v”ßÇÛØÃìÕ2ü^v— ç÷õµU2þâ‡ûû’|¤†•ò‡cb½Àqb®ÖÚKè‡ñäEÉÅmÅ0]çÌ JWçº\‘šmÎýFS_^9úhMº¶JùÉQó šT •ÜáL­#÷9½º8Kµ©Î¤bƒzÚ‚¾€/â úèXZíæŽ±/pì˜×ö‡Ý8+ýQnwí¾€7ô=£—:Øçm —$y£)dx`K{ÈÀB¾ª,†–˜ØŽLbµ]…5†]‰5fP ˆÔ¡W½ò¿p¡› ¯ÁUºÙy>0ÖÑ2]~ñ.œO`g*¹3ñå`ˆgã1Ç‚Eà _7Jzüéø— 툓qÌç‘Øw–ƒ/aÄ‹’¯° Á¿¬ ñ®Êd0>±5÷—€ÖA\j©)<¢*T÷C4œÔK`grëš>`z€ËÀB !Áx9àò=ðž ¸ S¡i";øÕLH|•¹¸X€òJ\WBF­„\‹üZä™ý¹ ùMÈ3[sòù½*0näpx>P’ÕIßÁga`Öˆ•a~K½XT³Ø“a%lX=pgà Õb«(Ÿ«ÑÛ„µdIYÊ"ô^Ì!¼üSœÁju±ÏƸˆÃø6F"´3?$Æxà efa¢’i;$ì¤ÝË…b-õæ·€ú¾GIAÛè·À¯¯jØùçÕÛ*„ÆN“ÃG Ö‘£ÊËÛª&#"´£<\‘°§*„†Ê)ð‰vGÕçeLP᫞hN)l•'A•†¬‡)èR‚ì sv ¢Rï¢+WÊ“?œ€Ž:FWá‡Sq$›Ô51l²] ¦›T4KšíT0ì( y&¡t…+avžæ ¾m ¶uÅayÍ*#.ãI“µÔ(}h±Ó³ã N›e¼ÁjMÀÿá¬Ç-ùÜ€t$Êø(OÉÿžLž‹ú~E&ÿû1X’Ìó`}ú~1†Å'ØïÃ\üm˜¾ß…™9 <<´7 1ÃËð»U-ˆŽ'—C’^ýp%¼ä« ×§`os~‰jb‡­ˆîåïFAi #Œ*ÀóïjÖ<%>üÆ7_·àæB ©K™6¤3‹wl<888 èô ( 8 @#`,`&`1àÀƒ€-€ç‡G']€ Lp€FÀXÀLÀbÀ€[ÏŽNº=ŒG@Ð ˜ X ¸ð ` àyÀ!ÀÀI@ d®8 @#`,`&`qoáD.ä)VîÒ²@98 Ìx²ÿýì—iú—ùÏÌôïqI;ö.)W (3+¶ÿx\ö/3 ýòPÿþÕÊÌÊèß^; \7 \? Ì|Žþ÷§—”(PnP6 <|@¹y@™IêþÏg\Ù¿ |Ç¥e‘•ÿ0#ò5 endstream endobj 49 0 obj 15700 endobj 8 0 obj << /Type /Font /Subtype /TrueType /BaseFont /LZMPYT+Helvetica /FontDescriptor 50 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 222 /Widths [ 278 0 355 0 0 889 0 191 333 333 0 0 278 333 278 278 556 0 556 556 556 556 0 0 0 556 278 278 0 584 0 0 1015 667 667 722 722 667 611 778 722 278 0 0 556 833 722 778 667 0 0 667 611 722 0 944 667 667 0 278 0 278 0 0 0 556 556 500 556 556 278 556 556 222 0 500 222 833 556 556 556 556 333 500 278 556 500 722 500 500 500 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 222 0 0 0 0 0 0 0 0 500 ] >> endobj 50 0 obj << /Type /FontDescriptor /FontName /LZMPYT+Helvetica /Flags 32 /FontBBox [-951 -481 1445 1122] /ItalicAngle 0 /Ascent 770 /Descent -230 /CapHeight 717 /StemV 98 /XHeight 523 /StemH 85 /AvgWidth 441 /MaxWidth 1500 /FontFile2 51 0 R >> endobj 51 0 obj << /Length 52 0 R /Length1 21268 /Filter /FlateDecode >> stream xÕ|yxEÞUÓ=gæ¾2G&“™ÉAr'$1äâA$A@îKX!+lTAäðÀ]A%JqY”UqUÕ]÷ˆº¾èîÓù}ª'DȾïûìû¼Ïó›É·ºª»§ºê[ßúŸªÎüy ¦#i%<6zœ©Dý ÙLˆxǤÙæ$˶ӄГZæ§%Ëb&!ü¬©s¦ÍN–å‡Ñù§ÍZÜõ{ÇBJßš>eÂääurÇÒé8‘,Ób3¦Ïž¿(Y¶DýîY·Mêºî`¿[7{¢®ç“PNûÉ„ÙS’÷™cÆœÛngG|GÒ6gÞ”®ûiÚ÷&¡8[O$Zr+‘GÌøŽ%DúJç'®²ëø”Õä^¼%¥ê{b‘Õò-CîSo~÷õßÿ1årLÿ€üOœÐ^¹Ÿ5YJ!Šëúº¯¨¿CRßNFä´“ jP ('ç:7i¥;Èý ÇA<™Aï%‹A«Aƒ„îÜS(¦÷îäø t1ñÒq½¼Ñî ºuúàÛíTsðÑàîÏPFï3êÙo$Úëtôqú™L‚ôI¡KH#ɤ[dÍ ŽÇ¥§ÈP+ˆWSJŸÚ( ¾D{‘ˆ@ñ›( ôùà rƒ_´stðåX»€Ã¯(ÅS‚ÇüåŸ| ´'yiwîx>ø”Vp} nÙ|ÐßNñ›’‡~üôùàì¬ÁÉêõÁÛ¹=ûƒ¸~S\,-Küçƒù±v™¢œëÌ.øm0?Ämi¨4·}þõÁ>¸ð×Åú€ŽÐÝt+ɦ[÷G_@Ý=0 «|c;ýéÆÌ‚H;]/mÌܘÕ‹d F²êc1äo:)-—n–®“ ¥)SŠJ!)U²ËVÙ,›dƒ¬“eYj§Oï¯jŽÐ=¤lÙs@ÖÈb;}'…#ôõä3‡dAæd"ÛÛ;?eÂKìítÏA3Ë!ó¼FÍiÚé3’§ž‰–Ô fŽå‘ %•92´ÑŸ·kÈ gKµ»ÚÚÏRQ_û?%ãÕ+WÒœÿùã¦þ¶ƒF4µíö7·²L§¿ùÊíî+™ÿñ8.M©ÉÉ4|ñ–93§ÖM ××Mo»·eº»­ubZÚ¾™sØ…´6>:~â¤éì8aJÛœð”Ú¶™áÚ´}-êïz\žÊ.·„k÷‘©u76훟R»¿%ÞRžPÛ|`bͼ±×‹u¾nƈšÛçC:Óêf JkËÑ6à†ÑMmiškÛ霬]@ÄcÄ,%™b+ñ ù$HHç s쨌ìüRn7‘›Íµrïr­|*ŸÍäGó{ñ=É¿Ç_â/ ¢`Bƒ0€¬f [ðÝ!ìö oŠb?q¨x“Ø*®×ò“Ä3â{šešušýšo4ßB-–n“ÖbtNAf Yþñ#Ð ´¾ü„L¢µt"ÙˆÑØN'5®ÉôðkÉìË/ã¸Þ†—ÈO!­[ÈR²šC¶w¾Ïï&g!)³Pe+Ù)Ô¿¸ £sé )êúƳ²³2cÑHF8=”•ïKõzÜ.§Ãn³ZÌFƒ^§•%(ð%½êÂõãÓÚ¢ãÛ„h¸±1—•ÃpbÂU'Æc*§µÕ_{O[ûÝ\ºæÎ8îœÚãÎxòÎx÷ÔœVEªr{¥Õ…ÓÚ~[Nk§£ohBþçµáæ´¶5?DÍ߯æÈ‡BøAZ{zmZŸV×Vß2}MÝøÚÜ^ôpìÐåöbŠ#Nô¬â6ÒÂR(XÒŸÝQ׿ ×ÖµyÂÈã©›0¹mØ Muµ©¡P3ÎáÔð&<#·×Œ6´“Ük˜ž|o{œLÏrÆ4µñšÛ¸ñ¬.KN›+\ÛæZò…ûÇâ•\ÝÚ«.¶q‘ú SÖÔ·ÅÇß æ²âxVš°¥A#ÒP-·¢¹©®èjkãL´”57i"ãg¦µiÃ5áékfŽsÉð¦ýÞ¸WU¾mdXÓ~OÜ£r{v/« ¡÷‡s¯Ë½Ž+CîeÉãïNžû;º—ÿÇAû@ÂÐζ´IêCÂhl9K¦”“5“ÊÁ'|š)º9íé߯AføH›0¡­uÄ•fL¯M6nüÌÚýZW5B5͸üsŒî7‡ÓÖ|k=>Üñ×kÏLè:£‰˜¿'ì"ènYi£®ä[˜±Œ ×ÓÝáél|[Ô1E9ì®»êÊŒ5¬ÍmvðaM¡¶´fœ€7ÙkP;ÑkÚGéºævÚ¹¢ÔúÃGåo‡Ë½˜¨Í¨ÅóQÈí…Ù!äòz¥ÕãÉõLVÒÖ¤­0yMZ}Út“Q¸0eMs>88¢ |"7â‰ñæÔîì”ææ>¨'ŸÕƒŸàö5ͨafW 8ª§ò¸©w/S>:¬é†¦¶ÖÚÔ¶xm3Fâ{lXSÛ1Hns3î*èn)Z¼t†»«Í…hsA6®%kïÒŠ*š×¬auŽh ‡ÚŽ­Y“º†Í·d¹’ž'â]'Ú »…±¼¶Ãoq‡RÕ1…ChV3ãi1DúŠDÁgÿß9\ÚÝnü² ­-U9\þâpÅ¿Ãá>ÿ‡+»[z ‡«ÐæJÆá¾ÿwîw ‡«ÿwÇ»ÛF^‡ÖÆU×ü‡8Üÿßápí¿Åáºî–^Ãáz´¹Žq¸áÿŽÃ×pxÀÿÎáÝíF#¡µUþqxÈ¿Ãá¡ÿ‡¯ïné5†6_Ï8|Ãÿ‡‡_Ãáÿ;‡oìn79­½QåðMÿ!úw8Üôoq¸¹»¥×px4ÚÜÌ8|s7‡ã©mäj=ÜÚCí’ÿ¸bsËá)‰VRÃU p>K†K~RCW‘mÜn²T‹ó»q‰ã^vp;‰wQŽÅ Ð\ûœ‘ð4#ÉgâM$Ú„8n4èIä÷ Ÿ“½š 2 åí¸÷~·M³[½gÎc÷€Æã¾îÙ-ýœDPÎf„û[AùøÍpP ‚ÿJËA8ïñ/h9=A–ãZ+Ž«Q÷rvÄîmU¡/«qõ×…r+òz<ËÊŽ ¨¿Ý£¬¹‚iˆ†ÞƒrùƒT¨r…±„EKtˆ¶dE2‘õ<JfA„HˆM-Û:C¹‰‡xI*žãWÏû¥!ÊIWKaÄ£ä¢$†ˆ Î#ð瓟D›¹ˆtóáå z(ÂébRBJIbØ Ò‘géKú[‰“ë5õïúåÿ_‡Úin]×™RôuÒFz?}›¸t®†›Ê½Ã Âhákq¹Ø&~­qj¾––HмNþV[¬ª3éêuãt+õVýtý—†*£l,5.3 4½š’™rcÊJó0ó –*Ë.ë<ëK¶©¶çmçí7Ú[ìß9†:^u–;Ÿv~çzÛî¾Ãcõó|ë]é}/U“:-âÀa"¼<ƒ‡ôOb•r~;@²¹·@¬Œ<ÿò8J8ò8j?"/àW„Ü”ójqì]Pd Yb a]ûå?ˆG/öo†\ö…;†ós¹q]ÏŠÄíœæ‚˜Å Y’GÖ*¡#€¢†^Òñ^‚TW%ª zS>¬~¹qÅÁíþÅAñhâ 7˜žWÓyNó–ø ä6Òƒ4}®1D \™©É0ͰѰÓðªá¬áƒ<]6šLõÖ”ƒ)Åê6³{§f„¾sdc¹úïŠ2D]Š©ÄåòfgpßõÎÿlÍ|çÎÈðWwç 5£M—;~ ­›Rû%ɯRÝq9‘¼ãBµX+*­ÊËYj>^ÐÛÝq|8)ÌÓõN…´g§Roº;•˜Ó¬©ÔEÎîC®Pƒ«™®æksSiEâ §¦K‰+âH¥6?’©(BØ8ù¡W2wÒ±s ‚aM8=ZR\ZÄѰµ´¤8N×8ìÎ"ëU×ÈUç5ÂéÓ÷?púôÜvù÷·.^|ÓÈÅ‹G²÷ゃÂM8ɵŸ¾Ÿ¸ÿ4wîb#?}ñÈ‘‹áV.ç·Éó¿½bç1á¦d?—WÇ7·qðDGÑz þº{pIVéH/šJ+«c2Ž› ¾Kì¤_\k·hmNÔ¡=B·AGÙ鶸)Õ7Øìq8ÿš5ÜÝ.®HÊŒ÷coÇ;]ãS]º9Ic1»œ¶pEcÑsY©÷H~à …ë?XŸUîÔ­<"¾«¼yÿ‡ÊgÊ'ß>¤üùü²Yíu=ÍüãzÊt%µh í±‘Ò¸A¶›í§ØX“°€&ieÝñ÷PõO»¤÷ޝj‡ÍZVj1Ç¢|Q€ºÔa–4|Ãcyõ¬[®‹öÎWù‚2Ž–®;KC4ôíCÔùÃíS–^˜«¼ÿÕåµ »•·h+9½œw’°I7YÖ™Ñ ©X7™Èž”IS’2Z•¸òÜ!`EAoWiöX¸¤R"í®ó¥Pnö{ã[ÎFæfKzéÜk :ðôs$ý„Äm‚H‹ëH>O½"Á¸µÓš¡ÔyyÞ Ág£f 9B#銎ۘ¿Ý‹„µ'wšÍëØ¸ÓÉì÷“C¬qlR_=îeEŽðÞ3gÎ4e¿Ç‡›©ÊMNÜ%QÝPŽã|Vž'¯cø8ïÉw¿¥P]%&çK!îôíÍJÞf¦e˜~‰w~ øÄÍÐ>27îZ%ÒzÙQ’"úJ$£µœ¿Í]®4øÍ-ÇÝït$:HuG5zƒÙZLRQñFµ1ê4¹3!}ÖLš*#gÖ ç282©CâÑù2‰E@Âfa÷T̹ËI.§Å,q¡´XÔR\f YK-Å\8³Ø]Î">~ÇøQË”?(ʲÕ-´dÍŽEÏ<¶>¿ñYqóû”ÓÊG¿R¾þô­¼°—Ö_üâtøZ©¼«|üáŠ×“<ŠCOÄG`cwć– õÂ(ñVÿOKËé*NΖG{nõÜá¹Ã÷œG$é4Eð™Ë·º*˜ncÚ «²Ê'x KTo5e­]C£Y—IeðÄlVyv”Z«iRþÂé’F #*´:ì’&…jpB4půÝY<|ãÒà Qá_³€fþðùâúçVO,ŸìåM—³SëœÛ•Œ¸uéúµƒViyKùáO/i˜2¸´`ÔÌÝ` %s¯¸ÞÄñxp€aDI¹ ²äj6Fé 9GçαùØKŒçÂq»¥Äü3£± µ$C”J Œî±ZK;VÕRtåy·qÁ¬´;ùWÔPxW åUaS.$¾4w˜oT–”æ÷öD‰VŒú#éQ á3‰À˽Á_8˜I¼w&¨vå# „RÁ³(’n2W1QºóNðŒŽ¸’"'䥰K_K%ZT¨Nã$‹¡ØÁA(; Sç/2ë­{ú¹íÖˆÍuN¹nÞæ)ë¢âþøO¨ãÃozÕÏý™òÝ?bÔuòÞê¹›=ÔBéc<—V~ÿ­óÕ,y|ÎÉß^>¼ÈÜ×ú[EaòÆÁ+ƒ nCÎHÆÄÓµœN6bN¾dÕh$NCEIn.é¸zñÞ |;u=G7å§uí´é€˜Ò`R9øý…ª¤ª‡*K…Ê50ŽKa©ù•èi‹–ZB%´È¥`ážTJ艵Üý›÷;@î« ‘Žkã×]¾åå Ö6 »ÿæy+|Î#ñœFë=A®ÂPoe›fúÈ£D °æ¦V›ÍjJI³Ú$bsé\%hXzÜkü™Éä·öI„’´~£E*÷ÞFÊÓÒBÉÿ¾ã8»£:Ñ>áÊH³i *žWHrè1öÌÐgºƒTËEù\],¦‰>Ì ­ ™D“ŠDö$çSæ*6Ül¬Ç²]5Î1¦UyL’¢BÁaçB鱄uiüÆÇ·j»"Ûlî«Äc} s‡Íx…Z/){•ÿ2ÓÙ[*§ïØøËÆ¸–çŸUæEm!å7¯+¯½‚UzŒÜ€Î÷ æóöÄó‡`Bª\÷ŠÙŸM àZ˜2‘N<ÔÉ¡Ew$„¹Ëcf6‘ /èó3ø¡s‰õªmC½°Ýí¨7DEÜOÂ)°Þ¶l³FÖ1OB*¶ê&›!"vV5s4«P÷3®Vþ/–S_}T}ª‰ÒÙï‹ïz÷Ý3ÆaÙ…¢d8÷Ú­-.ñ<#cÈ'Âm|©Ú§XÜAÓÈo¥4@¼Z‰CwÆ„˜s Û\eþ¡Š™öDÓѹn»Ô!Ø.uð¥»v)#öìaõ}Öù®T)~{ y-Þ\ZZÜXÙ8];-6³ß´šE}Oz^­Ó{r<™}ËùrSYH#W8t±šz}ƒ¥‰Œä›BS''Mgígg¯3éu]Tw“NPtT—›,YÇsr‰ÜNï?à äpÜŸ›U‰Ãs6¾a`}äâ–Z˜›çÏ+/K¢…Ñ”ò£ô>¥ÕHSà æÃûÂdÍïÈ·V|œ÷1,WuâkEuÇ;Ç;ÌïT%Ž[`ØV‰æcðž zÅD$p˜9æ0ZK€[à(†Ò`Ì¡\UǺŒÉ!º@·Òɧ¥|óÔ¤q_òÄM?}˜Š§® ׯH1•…ç=§¼¨|­,?õô/ÑI;h`aÍheËYþÈ$å¿VLœF+v¹‰Šg°X^9¸[ùÛyåè-ýõnãí·ì_{‚ön±KXÔÏ›õõ±¯¨ö“£Ê.î>5£yô°µ,Æ!é ¿ŠScûsña´‰N§ü=ü&a³î)]»¶]§É„%i4”“µZ$:"‰t-å…4»N±âœ]#ÐúT¯y­NЈTÏQ8f Õ×bùM£Õñ"J»âV£‘M˜Gé£:Á¸=´v$Ì3ô‚{H"áQ§L}-ô† ŽÜ„jªÕJõ2òU ;«±Ô6áxóª<7b*v‚Ç þxs³L›«ª$äã7–ê© Þ âÔ_÷ûŽŸqŽsG;ÍÝÏfF„Ÿt±?mWU/sø" §ž‘I6޶ÌäfgZ–p CÒc£…óËÁ!hcrÀÅé1Y(H‘Röfk‘L§'+»Þr Ô259‰ÐŸ¡æ†¨ÎB¢š©ÅÄN‚ÕíeOD•ÜB½ræ*1}7–ª> ‡,Wey&…ª¥‡>dÇ,Ê_Vÿ“5w)Ðg -¸oðReÁo¸…ðêã×g ™[>©y…òIb=?,\vßý…>¥"1zfÿ[ïL\m[n^xos~,§tüSënR1ºóœ8óÙIÙ¯L7Ñ"„庋®WÛÄ2¿Òo±84}ü¼¡Cà_ÀUš ,Þ4mÇLÛš™dÀŽ®î£ç0øp®‘aºf²ñ¹"¶¨)’Õ;µ…Äh7R«%Å,ùP _H)'ð:·¡¤X‘È^M!Ü&$Ì9¢I³™LÙ‰;á*ÉÔ…Ð.œN,f+s‘ÊŠàVªÞ7›Àa!@‹-/‡^Ùÿòýß¾ùèö¾—½îUÎv’g¿xúÚ)~¡œ;²n‡ò¦òŠ¢(¿zªù¯9ºõ·ôiZ÷ÖTû à N‚œxM‹WY6Z¹BYHáHÀ%Ë6¯×1y<Þ÷B-«“†!¡ò*§ºR§%âˆj$Q$^â$Q£3Ëè­‰Öª/¤’8˜Jd³~EXO˜ßlæ ªX쇡kÊuóVzS>ø›òØInÍß¹¡i«²2±w·#v[ó½#¨…æ]Ú,Úξ¬œùóQe¿ÚÄfBú ²74ž!AÏRiå€N/8ƒ#š\¥ÖkâåñMíT ´áJ‡T¡¾p*¦lu•*ÛÉ8Я…Ý+ä_^Ïç\~—¿ãÒËpšƒJÍnÅ´ÆG…Ý(haݬÚ®Vhn¥^½úd¾ŽÂ“?êb¥údæ;þËÃ{ùK—Osgù'ÔíMLföiRçlb¤09ï—ªYIWp¼ŸÅ•tµïù41.§'oží\æäRœ£°2Ýl جV‡Ô'wÈÆ>^m˜ ‡ù€µŠ›y¡€¯4GlÞˆ® àÉÀf²iB3ç$Ø%ï 5Hм*óà‘zªbl—jS%¡Wjˆ|‘4š†T$<„DC„BÊñ¢ ÷ ‰6(R‘C‚ƒ.¡WÅÉ;âK†e$Ç* YÂ1}˜…œLècü—›>,x%ãOŸVþô%NP‘Wй­½§ ½û5åÒ‹¿=ùÍ ‰Ÿ»]ùtûzå åŒrQ9ôGÊ=yù룷å |ê:Î=÷§ŽÙvȾ*;Õñ¬ ð'PN'É‚ш^#ÕEôÄc0µ0ž˜áJ$µ ;¨ÑzE>¸ÁÜ#@‚E–0ÒðöSÜåS§Â)€>Û¹[.öçö&nPŸw ‚ò žÇÛ%ùüì‰b$—ß»õ„OÂ/ðo‚lÂý")ˆÛ€pA”y¯D¹À öï€zfèJþD£Ð4ÀC¬EŽÐ¶ÜW—o@ußíE}° 곑×ã͵t ÕòNêáÏRÑF}¼]ŸjE›øwè‡ü;ú :A'븕œp·‰ã²t™Ær]¹±ŵpRd²QÇñV@zƒ•×È*rÄ •­q£.Èë5 åÆ Dmëó6â±3&ÂD Ï{.TTàÏ}žsTm&\lÁÛg4´ÓÝ9Œ¦Ìîýǯ‡ä-IK¯“Ç‚Þdì¼¹tÞØ¹¶–‚í–âÒ&p]–ð&ê§;è/¨÷¨ Œ}E-¾$½Î]ìÏOÊ}ká¥,álnéÇÅ—ÁpŒÏb6øÂÖZâö2Z®áL£ ´‰Áo¸j[ã.56d!‡’:^§££‚kω‚×Àü…­q–xô†.‰¹2.?°Qa¶=©dª«à ¬Zú ë óÎä‡âoÛ_¸/þ>‘ò×-ì¸Ø_xòÒÍhóy†u¾+~ÀaYïµ ‹$'èo¸“ò)¦¿ìè“§ö‘´>ÎçÓ[ xoÀ] ÷øï÷0cÝFL¼…ÄË¢.|¨áC…Ô+» >TÈð¡B†J->„„Í[Õx©øZxÈ xˆXKÌp0‰Ån ñÂÖ#î<®lPžyù™‡^Âv¹Ô¿(ûËyåÓ¿S‡Iüââo”·”Cç:ɧïÓ4ûj¾ø]ü=P²*å„òæeŸ8ãÄtý?ÀÚ7!^2Ã0úذÄ*4Ú›ìÓíKì‚$,f³ŽšR˜ÐÉœÆj´v{àu¦h¡üÎÿFù'˜ÇœÔýf°š kSq ¬T˜¨®K Å^nÃñoßûD)<Á·.ª¹]™O×®Ü)ýøäÓ‰õÂá>A…Ÿw?“©ñï ?`œØJ—• G£¥¦’PCtbt‰ia†öVÙmrE¸fÓtÓît^gꓞ‘®ãŸ{¥=??Ç×ÇÎ }r´½9I¶d¤3{÷¶¸#®r$Ó[ŒXH¾§ ðñÐÌ.KÇìGÅ ,‚ÑUŽ ëe^¢ˆE0ÜC2ó,A"sQ.šÑä{‘’›§Äløo~[0‡¤:Ü9Ô㦹BÑÆô94¢§yÈKYHV.:‘¨Ò`6«JÉCóaÞC}Ôp—a<±h>ePuqCÂȪP¾Ëd÷8ìÓôe”¤âIçŒÙ?hð'~sÃZ¤ý¤Ü|®mËèÊ·ÞØpÃZå‘¿(_oÝÊsCè¹¥CLë÷ø¢¢ÂHn¯’1‡^U~ÿ}KõíMœU˜Ö;?½rÚñ o¯½÷kË«x„if¬ëǽT 'È,&—8>" —4™9õ,Te˜Î…+q0›ÁjøÈ´|‰pJ±¼¦XÄ£{/~'š ˜lÌwÃ>3{ÂV«âa—ËͼŽpb³ÖÉ;vmÄàuÓˆÝãr?Úp½2!« {TÅT™Ó ¥ b®|Ôø|~Uóï7¼6`¥²VY»b×_#vª¨ð‚ºÉ8*E¹ª µtÕ¼ŽUy0 µØ  kK<ÅÊ\j‘4’VÖê {·ÄuVAàqšô«–šåW_‰92p¸U2èJaÐ ‹PèüâyT' µB­VNÖ‡µe5Èæc*™Å% ·|ܽŠe–ÊXƒÙÁÒÔØy6-- kayÔA¿OSÇ9eÙåeÏ¥|¤°‡´øË—úa4([-‹‘Ó“ãs2i)ƒÊ¦ñÓ„n‘|HÓ—qeb¹<]ab(A×DY’µ‚UQƒ£¬Xuz¬$O#XÄÖs¢¬G÷% Û0Šˆ•È:€!ì,Æ^Òznêù‡¤dqk U’ç9à[ŽPæ«I›B·Y÷Yç©÷[ΤØþIÒùŠÿ®ÌçþÆN¼Á&Š)ÜÌÖïô›­ÆßϾG öL!bå9žDØhŠxÑ@BhŽà½ãµZè!<¼€oq­†ãDM„²×ÈsÄ£»">˜¦îDUEß|3¼ uºÂÒº™Ã Ÿ†6k*C`klC‚‰ÇËa"r\MX”mSsÛ–ý\‡J¼{b*<¸~ÜË—×'Ú¸a<{ˆ’Ve6–‚O@”Ä}¼˜ŸdM‚hM$†£}šUÔí”]¸‚¤ Qc&À  H µÒÖ÷Þƒ|œXÿÏÓëQo¾2›îUëíO#p9xŸˆW(º*פqxÓ‡Wë®JbtUL=u)'Tͬô½êø…á8‡òß}—¶*­DS¼þ;Tßa8pe¶K:EÝ…ðq¼<»7Õ™áóùbEæÚ™f©B¶´|j¡”¡õ› þÊ./«òP%WY˜±š%QöÅÒ]¾vºêÍ”bþ<=ç/ÑWIUU>»”•½+ÃÛ/5Ë70%VîéÛïEº ÷0ÝHTv0쀙¨ó‰ãW´¢hD[LàÆbÐò:òÔõf‹+ ·f––9Ò õDhiJˆ¸1œiv,#¦“2.D¼~WX’®xBuET“36VYi_j¢êrŒãšµš~Xs€½±¨0W™ƒá_XBí‚ÁJËlÔ4oè-ÍCÓ gO,Aösî^òóÊn—ø÷_mYàŠ–ì^ѱÙNmÙwl8ú¦5oŽî5`ÇŸÆdôåO£³ä^îÜ1#gxukcãæÄ&_:ϯ0hjÂñÆ™Ïݳá—6zžÙŒ–ÎO„ˆø2ö¡ÈœxÞi§ï¬O—SœHˆË/J]À¯×Ûc²7Í›gΣYÄXbUèèØ+2vþ|WTÞÁ` Ö³Tï¶:5:§Æ¥V‡äŠR›6³à¸16!H`¬°ZìXÈáŒnøà}ËÞÊ_Ž?ùÏÎ-¹±°b7õ~þÓÃц—Å—rƒÒ¡\P”¶ÊðÕK¿zé©Ož?³iÜ>ÕâÍþ-a¨º‡fg<§‡nvï’w»ù²e«çí¿W2úmH©©.sÌJ±$eñúu1—LJץ¤¡yK»$=«ÒQQÁbò«œµƒÅ˜lƒC%&›½dx W†·„T¼Eï4F· Ѻ5Q†·„þ¼E]˜"Î$Ú"©[ ¶0qààÃIÜ{Ÿ»öšç-{z`ï{œs·goàÛ#o_¤Öw|Âж³“îÞ5ûñí­^øî+´èK¼ÖЦ”wžã;0®zâ' ã…e¦Ó(ÓNá©T1"Û¹?0q¿_²é8¿K/æÙòÌY«7¨y=àªÐ¼š«»Ÿ8”àÚ±õº}Z¡Ô­Gß|Hˆ‡‹]ªEÕÑE¯¬IWu²]»X„QºEØ¢Ãn_º}Ç’{ž¢kFôîûÌÕOßv@¹øÍ'ô–¯Îžzý7o½Æ•qþ‹ý6Lj¢¹ÿLG!þhì<'x¡C|l5Äo’öî ò¢‰Kí“5Åaâv9ËKéŸçOÐWù©ïËhß ¾þÊõUXÂrÂÊ‘ÅPFʧ?£B#IÎß'éüN}DÚäÛé;„9 Dœ)ŸèÑ$ Örý1ÑËÈ“bO4öNhGRøIª¢ÿNB]Ç…²‡˜Œí–(E©P¥¥ž„aÞñ M€‚Õl3ÛÍ6Ô¤§fDIñGiÀ¯uIQ¢w˜¢Ôh {C8%"‘Ý+¬ƒÑLÉ»èrr³s²ï¤sÇ’¹ÀiáÃB«„’+šL€$^01¿Î.ûÁ÷ÊK­æË߈÷oúù½íû¤ë †/¾nøIåÏÔýÔg|æŽ]" ·Ž¼aÖÀ'~ñÊØÒ†Êò†ùÌ0´²i]P×5ô#L7؉K|‹Câ9’_£óó4Å^á4j¬: ¨ÉhÉrY%kŠ)hâL—í·çrhÚ²¤ˆ%ÆVg1ùjG« 6­lµÎéräAd4¶„oIQÉsáꃖ —Ï£ž¶ÿàþ Äšâ1÷KŽŽ|vÝåÉü¶u»T{ÓW©ä¿‚¬Õ=q‡âCJíäÚ&¹Y{á©Ô]þ§b;r§êá:Ó³LÇué0)‚&ËïÑYýº”<)/OôñyμÜ,ÑÛÛ`ŠûEc>O~ï«&È…Ž &‰óßw!x°(ЂI€J÷^áLo@oɈ˜£á@4J2½H,zÖ¬LcÄŸ¥±Ô,è ‚Ö.CÒ¿¨á ›9%E)5XŸ‹%W¯ËJUk‘ÁF–-¯ti 8ì”»c\QÉŽª9Ê©gþj:dŒõ½ûÍx”/ݼôYå•^ µ¿üÙKõ‘õw¼|}/åŒPÓ/ÜÕåÂÓ-ç¶>Ù«zð¦‡û;À #ÍS¶ÛË–çŽî´œËUÇy9¦SœdD¼fì’\rLˆÙH dÙfälØìbñk$‡AgÌÒ!Òpd'b ¼E{ 41©SXÓe.ªTkQAÙâ¦j ÔåYf¦$c3KxùÁxѨ»þ4"÷p `ÕœçBùtC¨âÍ&nà~ÑRÖ´å½ÄI&‡Þ°#´þÛkW÷I_N ¯®1Bn³$žyG»lÉñDÕñn±SwL1Œ-þ-?„}é=ñ([ë…ß…¾³Ø_OvÆ'7s´L=&˜K3Jœ&.Ö,’V‰‡ùSü9ìÎ{,KZž[Î=¡ä¹ ,ó"^¤Ò̶‚k²„WªDV$x×è$Nã5b@ÑÃIÞšx˜:“^ cXâ”/‘TÁ?®VÝcx,Ì©Dpñk9âRó1³\%«k6PóЕ¤o,Y­ÏÐ7¾T¦Ò}_*û7=ƒ m=¡Ü–˜ÈùÖ(?Qû·dkY<ÉŠc»öqYpúñ*–ý¸0›tõV<˜ÜÿšˆÐ€©+â•’,™4).Ùer¥ÄäTh£ç&ý4½!ÑyýaŽ\‘ßå7"tÓ¤ú"¼M— eaÉÂÒ8ÝïÍbï5Çacò"˜žXf;5^-DçÍ:.\q@7xìÀ:ù•M5I‰rtI”ëŠÇÁRÍÑ5¶?^Ü<·uh¯Œª'¦¼?4ûÈ­Cf>|È›5gê΃Bþæë3úVgÔß4bÛëeÜW·[·#ñwdvá Gßd’§Êß=Ãv펋ÒœÐp‚Æ®‰Ù[4ó%Ñnàìn3<)¢qëu^Éë%†,­×GóÜYâI…;{ÍôHš”¤¿~u°mÉ)ÂÂÇU]as: ¦Àí–ï¼{úùa½ù{/‹g ,ÏM=Hw¢ýã†?6ê 6W&VM6:kJæÎH¼‰Æb¤+±·'?É î8¾?^´YÞh~Øù¤°KÞa~ÊÙ.Ÿ”Ï _˜þd7ô‘5~·dð[õÉãqp±oª6æðxSÛ©ÞR—5L@ÝžRRýa;uToÓÂrY¸(•\ȉFätvC”P3Ù çˆ7!QmK؆¯ +Cl®l¶„Ã’tˆ>]Ñ{ð OnÜø ¼Ø{YùûÇÊejý£f>MÙ±qÜC—÷ï9ÏŸSþ ÷0¡ùæ„DÑa£{us]<üôìwn~qÝèé} †Æë³=6~¯º‡î{ëƒÇ¹Ân¹:¿á´âhhÁáÏótÇL´VÇ#‚³ÂÅkL:‹—@T“E&G ^tÙ‰Uiø°]Qb6Ÿ#ì22'ΫF’y®l¾#ªScýh scw=¿gOÔQ` ؃ýcËF?ð€8Zyw}¢®Ü¦§Ü:­|ç4î•õuŽ´v~νÅÞ ïÓn?iç´6Ùî±y왚…üY8D4éˆÆ¨¡£Ý’ÛÐ3O—eÐ{½4‹5öí+^º€‰·¿Z]Å"‰©]ƒü†ËÔø€¹%B˽½ï~±6rp7.ž¶þ‹¹lI:Q1¼xü®Ñp¦Kgí›}ãÃÃWsï{™¿°›ÿ³OàwÅójè+E§‘éÜt~šf•p¸“ìâdüw®N(®V‹'„“¢< óöL¶Š“¢†€ËÚ;çDÀ” îîC'ü®w’3„aèçÝɱꨤû…5Bìégp:³mš¸Õ…!çl«Ëå±±Rç¸ÎXÏ2Žê–½¹Ø ÍÿžÃFd¦tÕ-Ò¥eýh8Ïó¡Ñ»'ÖlkÝÍ äg› óÍb?“2ÿ4 R!šò€ò×g•©5ò/š[~(C Q¿‹ñ {žùƒÐcl{V¼¦LÓHF‘&:JÍ@§iŠZÌfM›Õlm` å*aÿ\–Xt’ØOòøl{·Ó©ºËê6€ð ‡Vw…Á¾¡Wêú6[F±—ÃAÙ>šbƒ|¿ÄjnÍåVúæ:žl_ŸÀìYÙͤX1Á~$õ=£4Y¦)ŒóÅÚÉ2ñ˜&u½«tÕ{ ‰ØæÔ~ôê×@Ê*Ø[ 3g VíÌ:öÈ©ÖFæo'á©8I*0‰ ñÒÔ/<äG¼ÄÀ$hÑ…ðÄÔ@–;ø/°IZèíд.d®Û伇wŰlñv‡'ÕôÆO"x_EB û/8 g;ˆÏ¿¢)ÁÓ§O\zOµEHðŸx¦)j¦gRx- +,ìmGþä޶î7Ù;ø¦É·“ï0fae†½¹øã[‹É÷“o+ö#qRKêðÿÅØ³€½±ìÖ %׫ÿUg8þSÎøÿ571Q"Íd4þÿÌì8DŽ©cÚ•ª9 ÚB2¬ùÆœÆ)³Z¦ÌŸ1i®$¯²L¨¨ 444 th-hèiЋ Ó @]†p@>P/Ph0h hèÐZÐ6ÐÓ A§Aþ º ¦@>P/Ph0h hèÐZÐ6ÐÓ A§Aþ º Áòzª@ƒAc@³@w€Ö‚¶ž½: úôWÐeØÈêª Íêìú€A¤;O1‚×–Ó{”¡¯¹?Ö£œÙ£ÌÞb½º~´ãš2C ®¾ž×£ eÍõÞ=Ê…=ÊìÍØ«ëƒnº¦\Ò£Œ7œ¯¹Þ§G™ý7ª«ëëÛ£ïQ¾®G¹¦G/\]S_mr]2›yW?¿¡G¹±GÀ5÷c¼¯)éQÚ£|}ò°å=Ê7ö(ìQÕ£ÜÔ£ÜÜ£|sòØe6³¯æÇÄåI=Ê“{”Uýv•¼Oíq}Zòôå=Ê·ö(ÏêQžÝ£ÌP¹«Û[òœå¹=Êóz”oïQžß£¼ G¹¥Gyaò¢eõÕ«øµäÚëižkË—T­ûÿ@¢ÅÙ endstream endobj 52 0 obj 14392 endobj 16 0 obj << /Type /Font /Subtype /TrueType /BaseFont /ACCWMO+Helvetica-Bold /FontDescriptor 53 0 R /Encoding /MacRomanEncoding /FirstChar 32 /LastChar 121 /Widths [ 278 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 0 0 0 0 0 0 722 0 722 722 667 611 0 722 278 0 0 611 833 0 778 0 0 0 667 611 722 0 0 0 0 0 0 0 0 0 0 0 556 611 556 611 556 333 611 611 278 0 556 278 889 611 611 611 611 389 556 333 611 0 778 556 556 ] >> endobj 53 0 obj << /Type /FontDescriptor /FontName /ACCWMO+Helvetica-Bold /Flags 32 /FontBBox [-1018 -481 1436 1159] /ItalicAngle 0 /Ascent 770 /Descent -230 /CapHeight 720 /StemV 149 /XHeight 532 /StemH 124 /AvgWidth 621 /MaxWidth 1500 /FontFile2 54 0 R >> endobj 54 0 obj << /Length 55 0 R /Length1 13688 /Filter /FlateDecode >> stream xÅ{ xTUÒè9wïÛKº;é5Kw§;éìûÖÈMHB „°˜`" & h`u`@Ð@@EgXeÆ Qgšà@#ƒ/Ç™QEý3*E%}ûÕ¹ÝDÈç7Ÿï{~óºS}Ö{Nª:uªêÜ,^tWÒ¢5ˆF ÓÛ»æ å“׉­Ÿµ ½+\޹é³–,v†Ël´o˜Óõ‹á²ðBêí¿˜¿<ò¼™A(öÎŽöÙáv4iQ'T„˸ROç‚ÅËÂå˜:HwÏ¿sV¤Ý㡆íË"ó£sPvÞѾ #Ü?O‚4¥ëÎ_.—sOAÚÕµ¨#Ò7~o! µ^´©Ð|$ éá ò—ÔÛ­¤`í×höŒ¨Ò¯‘AP†{Ü›µ†dþûÊ?¯^=7èU¯VUC?•ÒŸ4À3\ªœŠCûûêÕC-¤•|¼Ô’@5£ ÒÒ÷ Ò‹x ŠiTØÁ µã]Û?_ÂYÀƒ‹Ê¯gI-RÍZW꘵n]Mj¹ ×¢b#®B%­ìõ<ëàѽ7$£Â Õ[%$©Š=Ž`ñLÇ`q@ÀR¬ã[ÏoW¾ñ”9¾öä:Þ„~§ŠÇ:N–C{¯ãDZ€‚äuO€ÁR”ãUÏZÇŸŠS/tôz¡®×±¿’ƒŽ=ÅkO¬WjOS’Ç<¼«×ñ(I:ñ·­S¶†¼;œt­W&ºó€’Üq @={бÀ“ì˜ bIíhõÌw´x|Ž)åœÔë¨'tÔyO:jÉÔ½)•Oæ]|ËÇFA/è ‚À Œ@ Hˆ „>’Ò‰$Åpz’p°c0b”¼ž"yø_DaBãQ€C÷˜—”YËŒ£ ¾êÊùiS*Û*ÓøXȦ[q¼[íä&ÿ¾øfÉ„â›ohÿÉvTÀÓµË4.¿<­ªÃ]Õæ®êhóoZÒiõ¯™étœ48ýtrÛÌY$mïð/wwTú/»+û•ç†5O#ÍîÊýhZÕ”¦ýÓ¤ŽÊÞF©±ÊÝ^Ù| ¡ªfÂMsmš«¦êGæª"ƒÕ¹”ç†Í547¹&¹&¹¤e®ôôª¹“+Û‡ ì1”ÉnGñLŠG(tà}’Ê“C_°§ †úiÐn8‘Àùk8ýñèZ ç4Ú‡UÈúqzÇã4ô.’ÑûèmBÂoº„¿Mó)N>Eènô{ôH¨ u¡2ø^Â,2¡ôiheèÕÐw¨õ ã˜ÇÑ8>te£nøîB»±†šÚ¬¨-Í~7z õ†>ƒñ‹Ð'Ø€³™‘¡@ÀX¨ñ¡h:„]ØÓð­¡O Þ 8¶ }¡úÐxî è•& •0ÛÇØ“q:Þ…?¤ûCkB÷ÃÚâ m*šßh-Úv£ç•^3™8ÖãW¢Zh»½.¡+ tSq^F½CFÉŒdv…ŽSa¾6ô¦*<ÏÆ]øyüþ/ü ULµÓ>ú¦‹y p›Š6 ÇÐQô z }€.£~ô= bp'â•øwðÜÿPùT+µŠÚL¥¾ séžÙÄÞà 1¡wBßÎ ( „> 5¡øÎAw »Ð¯ÑzÌ£íh?ú/Àö<:E¬ÇÙ8ÅSð­øv¼=ˆ÷àñ9|_ÄŸvÑ”ƒrSÙÔ˜ïnj#õ<ÕK¦úi½˜^E÷ÑÒß0&¦•éƒïy6“]ÌÅqµü$ù·òùPfhKhðÅ _JE™h4f€Š ÐzàäF Ùn´=‹þ€zQoèö¡ãèMÀëcôº ‹ƒ¯ çáÜ€'†óñük¼0܇–GðtŸÁ×à+#¥¢2©[©vj9|w¡Ô[ }4´‹N¡3éZzrè+úyz?}…Ib¦3 ™•L³ƒy„cG±·°ÓÙ.v+{=Áþý‚àâ¹nn÷÷/ðü^Ɖ€‹'¡ÐK uÛè.({м¸: ½ÒÛ^F×Ðw¨=ã‘Ln&‡CÐàæQô'úW¨=Hý†*£÷Ò*œº c忆¾RZjŠ79ÉãNt9 ñq±v›Õb6ÅD ú(V£Uϱ Ma”Qå®nsú“ÛüL²»¦&“”ÝíPÑ~CE›ß UÕ7÷ñ;ÉsíÐtSO zÎÖS ÷”†zb½³•ff8«ÜNÿÉJ·3€§Oj‚ü}•îf§¿_É×+ù-J^ y— pVY;+~Üæ¬òW/éì©j«ÌÌÀ‡%8 ÄÌ t! ©ÉÀ~4¦}(W4†ô¨òÛÝ•U~›òÐF'UµÏö7LjªªŒu¹š33üxÌ,÷L?rWø£Ò#“ç@ &56ÁÜ™sý€?Ú¤™íž½) ¡™m$×ÞÒä§Û›ýT™Ãî·¸+ý–ŸX(^ÏUm¾¡ÑO%U·wôTû¥¶M@tRl#¥öÍPªì„a©{š›üø@Ž ¡à^Eø˜Hj›çô«ÜîΞym@sÔÐÔk—ìUî¶Êf?jlêµI6¥™qغz¤ ˆr8³<³œ¤#]ÖÕáôëÂõ§ûHj]}ü#Hk‡è‚ÉÜîq€¦ß9 &Z®%ä§£õÌ*òÁ§Ã*ç>cüˆäg“Ƶû×LŽ ÑÞYAn^e¯ÊfWÎ¥ŠfèßÖ£ „þz·³çkœu÷~sM{¤†KÒH#áÿùqûõür~&Á‘Ôiuwö-QX e·µê† (“s+ ÎŒÚR54íÇøþæÝ@•ñ‡á€¡gÜÍéDàæVÂtPÈÈ€Š4äƒj˜¨šH†³ÇÙ3nv³ÚÙ "Å$))4tô4gÁ&7YД&—_jŽÊv47€q²È8ðtïi†æEF€T©ÊB§ìŒZXUrCÓ¤&ÿšÊX¿TÙ D!îkhò÷ü67C¯œ!LãUs­œsçœ4hÏ fÍ¢¹§‡Œ9¹Éíò÷õôÄö].ƒ…<¼BŠTéB(ÀkàYHÜ®X…ä.· Ðj&4;.@`Öÿ{ á O¶… …‹& —ü û~…G az…GÎ#…Kÿsu…Gÿ{ — á HJ€m™BáòŸ‰Â?…Âc~…+‡0½‰ÂU€s%¡põŽÂco¢pÍ¿§ð¸!¼Éñ€í8…µ?…ë~ …ë…' az…'Î…þsžt…ÿ=…'á HNl'+žú3QxÚO¡ð-?‰ÂMC˜ÞDáfÀ¹‰Pxú…¥X?ºQ¯¦vÑÏ®˜o½‰ä-ÿžä­C ¬oô[’Ïø™HÞöSHÞþ“H>sÓ›H> pžIH>ûÿ#É;n 9b_A»(„,ö¡K/hØÍNCO2‡4ܾžä¹}h;çCÐ6Ê.Òù% ù•Ž…´ ÒlËù €n{#ÔÝ é&>­!u‘¶U–Òñènh¯ˆ<³ Æ×AÙ`û9âÀ?Aȉ¦“Ëÿõ‡f~øÐeÀƒåÀ«DeT)M"RCªQòb{:ÉOôÈ€Œ(ÅŽfdß!xܱàWǃŸê<](¥¦ÔuêÓš8M—æÚ Ú‹àUïB|¼cæÑhÉÅrñà;1|°žýÖª·°ZrÛÁ®)wд±Ü®r˜‹-B±#·»¢ŠlN×N×óÓy¨ïi¨7øúßî‡eö—•ö}Ùz`ÁØX\ärZÌW²7ÙH™bÌùyÅEÅ.¹œÞdnùï°/~n/¿‘=åɽÇNþþñ©Ùœ›"’Cò±ƒ©-Ì-oØØ3¯¨MþêÛo¯Îó-úJ>ýÆIÜAÛë»ÿ+aµ*ØE“¥¼¥FÌ ^Þ«i2Î3®d6Ó=Lq½ƒÙa|žÖRi&Uš™2 \±ÞnÃI&›ÕÀήÆÈb‚d1ý¨¬¬ÿú°Á($»‹`!f£IÏS©P‰_Áqg§eßwúè­·Õ—,yTî ÞC­dŽ Ž>³ä‰¿’ò7ÜB‹å³oÈý€ÑDO®äÕ(›Ü¼êC…jᆀÓ>…^„}(@Å‹Š!) Z¦6='+òÞ̇ƒÔÁ:çÚŒ9*¿Bò=òU2 &ô`ö³}0p±dáÓFE§!J%pK°]M I*›¨à8Xò³aþ)Û¹þ¬9œ þ°Û ®ÝŒ)Ou—Ëeûä ü|·Á×õ†JqbM³¥VHâíZJ„lmŸ«qù(Ú¢¬T™(‹ëß]8—’pžü×`{,øW*ïûÑÔCÁ;½±t=¯P!G20„Åvz˽w$.\¸ÿúD>e»–ÁŽ!Lòâƒò_qÞNö„môÙdbQª…(ªœh;O¾3M&è‰ò –]§Æn\@½v…=vm¬|Uáåv¸ J±Œ¨OÚ¢B¼ ¨XƒY°©R‘WHWy iÆb¾P(U•ç¡Ãrt—a#º×° m3ìEO^AW…oUq¬ ªÌ‚UÅðF;o-FPù†lã(¾L,3®0V4¾bÔEñQ"%F *±:ž¢"Oë ˆÒ ´ô ÚK£´:o”-šÐ´èi›þÜ9k°T¯”5èj£Å‡A¹@bðåæ …­þ/ Š A¹Ä˜M„3˜Y€ÈSò§ò;òeJþ÷a Qêô'é§]KgÞI{8}0ȱ®ÜPè™Ï@Ϩ•ó«\òš5f£-ÆfßngÙò8 ­.RÅQÅqѱö¡8ÚŸpÞuy˜þˆh@ªÕc,, }aÌ÷ðœ¢+ôaUbÀôù3g:{öuìüÓòqùøÓ}ô4.Å¥OŸŽ>‡uß}‹£ä+ß}'_YñÖsϽ…ïÃ[O<÷Ü ùvfˆ$‡Î²:À5 ¢ÛOHó„(¸±I¶©mQ—%yަC;7ñ“Luª>Õ”bOöŽ0•Ø›^73θ}Ùü]ô÷æï2£tÈ N´:’,BR¢NÍX³ÞN·¾WžC3åéªlë¶lƒe¢°-Åžë(2܂вl9¹œpà¥9 ¨ÍþPœ‘…ƒÆ1„™C”?@DéƒÒ!J³°À›œA WQ©œ)Æbv`ècŠŠ 1^©K­=¸ r­$mÜ}±i+vb˧xœ ¿+̯¹}éýÕ™¿‘Ÿžº^>!_”?’R“ð+y·Z³VKñ&¸ FÍyï/˜»zùž’¤¶i½v÷¨”1/¿.ù‹L ì!è— ÷<*‘4˜Kã)F §8 à¦^* ÎÄ&IÅÁqÞç"ç!X õÁ "õDdz,²ù™òXùu¹Š=&_»6†9 ‘bÐçÀb“»(_Š5k0Å•Tf³I,ÖÚ­T±Éf±þ \ÂdÅ¥œ=08Ø @…b0MLXz ñnìó”üùH‰ûÆm×Êk7Ž£&±Ç—ì¨þÕ¯ªwÐ=ƒK.¯ûòËu—éØÞ Ó#C2%Ì °á|hz@š8’*,ZŽ7bæÝœü¯‹iÿpë´,ܦDÛÓ!&Í$g%g¥‘ &VkÎáàÓDuFžzDt=ªÏQ˜6:Ù^j¯Íê m#KÿŒm@Ëü&RX".|'?ùDY V'A,Ä€= ; =":…9ØK-*ö…¨Džã]wå@°ÅäÊÂ^èéNɳ7šú0¶8Gšî­˜4¢åaúù‰‰£Z§w¤%ˆr¿jìB}`Ó&ŠŽ‹“_׊ôÈú–Å¿ýßO}²‹2L*ÞâmW>ÿ/Ä({ñ˜ü¼¤²Z¶Œû²¬)_’¢MsH’2 Ÿyøµé¹&ü6¡#…V†þÎì†óȈœ¨BJR9Õ:£ÙKJJxºì;ÅJ"Ë LÌ$"½T¡åÆǴ^påtl)Œ‹Ë¿oöv‹Sî•¿“Aß¿:‰Y«K•[ñ@Ýêeã6ÌŸv÷â#¸ä;lÃ%Oñ…e ÓÀ =¬n¢”qIÖ¯)žÒÓÈâÑóœïÕ&Úíà´—±;ìEZ[‚c‡«¦*"£„!Á  œÈv sÄ“èld¶m]¨ÃîDDP¾Î…+ÔŠ]9Ø%_µ{ñÿ’¯a|æÐêŽÑ«îZºœi¹¥ž¾—¶·7áÂ+Ø‚¥ÁE/<ðê´‚£›·ÿ öavè3ø&#øCÏJ㪅î˜íx'ØßXÅrzÖ^ËVëÇ9ïÅ÷Du;DÚL[¢ÍÑ–¡Î\ggo1·X¦ÛÏá÷™Oãÿá¼êÔÇÕú ì:=fûV)¢n†îN­ÓÅržDo1fĪÍ4•HYV&&´iÖh(ÝC9t[lnâºtál»÷Bv˜'æo+XPácÁ^ÌÂî"PÎ3ïŠèq…«@"ƒÄøÔ>¯¼uÃÙ±R´š š¹ö‘“›Š,Ø­ž¾yð”| ;>‰¡ÿjÞ».Ϲ£}Mí}{*RóbsÚg?‚58 ÇÂë#ðÁÄ×¥6±o‚¼¶<J4Ê€Ýç@Á‚œŠ j,ÐS üoý¨šêÀk²A­|OzÓàµÍ«‚7htPŽFAoø§6¬´ÁiD©_§ôíˆmQFü²þÖ~" f‹) ãMù&7H…»0Ÿèž|*/#Ùº0ýÈùÂ#»GŽîgߤéK4]èt–¾6ø }çkÕ¬˜ 8TÈÌmÀs-œÑ9hº¤ïIÈzr²y#—¤õ¤p™äŒsfX£r(‡Ñ‘äÍɈ¶çÅ­ÍTeØrónÙ°Z5ø@lA«O–õûÀ<„mG6G1ìÍ[ÎŒ* Ÿ‰ïu†"zŒ‘Âc~1u´gÝÛ| ÎÛÔ£:%l»B~êMù[.ÒÄf-ØU˜š=uÃékW>¼õ³íO>üø}µwÌßC/²¥ÿòw×¾yëöÀž'òÌÞ_Tì®®v—cïà¿p-æ_7œ«·±GeRKy©&]§Ž‰±‘Æcáõ¼(±v[´ÞkŸå%WCdK†­wðX€ø #•ÓÁ zŸ˜q`1¸9Å 3ŒÆùô˜' 3cä¼ Þ%_Àq£Ÿ˜ÎÜV]3jíCÁ5Ôö¦¢ºí›ƒ½ìÑàÕµ' î¢ÞÇžŽðh¤”X‡êp jk÷ý M\Ø{GœópÜ÷^GI „½÷2ð߉n ¦ûäó `àyé5É`¸éEÌX»})õJT5û6õ ÅDm<•ÝÈ> ܯz™}]x?/œS©ÎÊeÓÙL ›ÉÓ%\]õÒÍÜ+QüüÍÇ‘ê|¾¨n½@\z`ÔÂVÐ`®`— ,oÞàº[ñ,Ü.¯Ã›å½òµ%ò%öèàE¼KžœO¯”Ÿ!´Ú?$ÞA£$)šBXd‰ñåÅ6†bA}ØÞdÂnÞ+ÿÇÃCðüXÇnf:¼up¬¼—á5$ø5$Ì…˜Õ<ÐË!]éFH{ Ý éNHŸ8 ðà–ú»à 4…âT™ 'ÈoÈ‹F-#€^ÉŽhÞDQá(x€êQ äÀ*ˆ]“:,rì†ñà}˜ˆ p\údàújÀ5¶“A'‡|MtDÖá4».öá¬ËD 0†,$eØìËÒ‹”|.&yÎ’L‹üqŒgîŠ4 ¤©0{òúUõ£%“›æ3ÓKª}“‹ç'QG§ÔÍ,\JmlϘ81³9ØÅHLõHÅù m™™°~²oÛAW‘(^­”ÉbNŸIÝ©æ°QÏ©< üuŒha‹,Q”Ýf >ÚM;ø89UÃ~ÈN™/²‹t-^ºçŒ|Î’¶äÁ¢8ØÃÑŹMÝs™–ý'ƒ‰ÔöiYSV–w{Å)ID±€.{f7ÓÜ"QÆz)ÅBcA³A³AO[´Ö¨9ZšõXcxµG§¶ZªÈb· E›ÍÀK wa3Û1³ItgZ´0¢>•Þ£¸à›8‘ S—ï½wÕªîîUT–ü¹üø~ŽcÀ±á˜à[¯õîÙ³ÿž=½sägñÔ/?ÇÓå§>§$ å*y2³ dS R1^JµD bœò8y;'z¢Õ6 µj‹ôöDÎë°zm?j/*§±b€É6N@ YU…Frô*$±W¡ÿr-Xˆ¥KWÅc•|ãîiÙ™òElÈ*˜±ŽzäØo&,{©>3°“ò×ôøM§Ë=UÁWÙ/›:È ¸—Ê pfÝ{‚àžþnÂgqÔ·lŒæÿh΢óØÕfíˆv˜½&{¢X¯`?Ü´‚=K¨Èù®pØó#zœX…‘#Êe2³¨‹£SG휿.¡d‡4%7GËß{Tþ«Ÿ^=ù׳'ÞÿÔ3 k6Ò›Ç$ßòø÷zª¸â8këquD÷Rט8éÇF4{€ŠÒBˆt¬d‹æµœFtR9”DÑ&eЩ½[Œ)€gp5̹¾Gß;w­€:Áûm¢òÁÓ‡P}ˆÈÔêèØ4ís#]NÐWä6¬aZ0–ÏÑTWÙºàU¦â¥)c´¬½ï"µ£t°XVKUz.Ù¦¥UŒK­®ǩǺ*5©gh!>Ñ©s:c¶gdy&#E‘eñæúDÞ”É×'Ù³4(¾>*Õ§Û2³n°Æ N©øÄÅ bö!ƒ'õ'AyçæÜÖzn%®5ØâÄûNRœoP'79ߊŠáÜÎdð½g© ˜2+%E®«ë?óvü³e/l˜–Ú7uÊWƒrèkx1«¥ÎéËË˱ÙFeUU®ÙþÞ¯;GŒðæš-%)“W>~ò½½4l`°ëBŸQËØNÐ/ãê3¢š Ëx!bp‹dæQ ‡9+°&Š`T^ôðÉÀº®6ž·K/KJ þ Î7DžûËÀ'¹„àˆqöM<ƒi¶ïߟx‹6^×ýúøzÁ œ#Ÿ:ìãÂø–¯ÏC=Böiè3t¹±¨“²D³Ýœf.1Oã;xÎ'%gÖiEü!»VôÚ­j{.²Úbã~0[ˆ>1úêƒo+4'žU@í}wâKðDÎ jIø1³wÑCEðê›|™qšÇ¬šreJ6þœ©ÞÙš=y‰4—ští¥]l^tiÆÚŽPÆítpÖ¹àM ò‘·°Q±xH–³_„õ°ûIôõzNÉ‘Èk, º+‘÷hª»žÚ‡S!ìôþ³ÏËï’àâ>¦bð Úpí%Ú>xòWˆ c  bxm ÓÒvT/Å3ÑŒ]„@‡IæÒÄ"Æ'V1ãÄ©L³¸•Ù)>ÊüQ|9Ä3¯‹§™÷ÅO˜«Œ…¡­ K{ûdX+C³^#Ø£¢Ê*ªU^#„EµUT©½F˜3¼È Ž…› 5„ E¶ E‘¡8xŸ˜Ü[Ï@p¶C£}&,!‘ëŠð=E}¶õ¸þ8ì°_@uúÀÉ+%1C¸·€À”¾;]Xw+šõ/[õlwú*áÆÒPÛ­·þГ˜ qk>˜8@GøUc;^,ïÆ­{ñdyä÷ç£T e•ãÒ`ð- <1Éc~3”;²÷¤.¯8Mœ#n÷ˆo‰`¤aŽ‹ã ÚLÞ©ÅçjkùVžœ¸KùåZ­%ªHÛ­Ú Þ¡¨¹˜ ¥œרV‹O9Á ÷;$«M Ç«ƒÊˆvè£bx3ÐH§UkXsDH%MôC‚­Ãd¢Ù@ýë Ї@䊔_ý…à0P”[' —<,XËV¼œ¹à!y~Í&¾Ì?ÝÆÞ°”Q$JãÅû=iuv[:#wáQÿünszæ¯>šœ•…ï~“¢D£a¾†Y4xŽö\;%¿¾Ó\ 9”Oˆ¼Õúc/TÒ`iyà&Ñ‹RÀ#º•xWä}ãbx»¸¬®jx7¶ƒÏká-â à;6À»²h2šoàNC·À{³ÓÑ­à= 'G>ñ=ËÇŒ¹¥~bzMÇü%‹çÎjϬ¸sþlÒëú‡D ü}§>ø2Üë!uäH m]k¶< àè8ðÀ—á…SzH9@@@À€-øúN|ð%!J(òAðÊc8Åo.V.VVŽ®ž¯Ö^5¬\=¬\3¬¬˜7ŒGþWæFüꇕ'+OVž2¬> endobj 56 0 obj << /Type /FontDescriptor /FontName /MPKSYX+Helvetica-Oblique /Flags 96 /FontBBox [-933 -481 1571 1138] /ItalicAngle -6 /Ascent 770 /Descent -230 /CapHeight 717 /StemV 98 /XHeight 523 /StemH 85 /AvgWidth -441 /MaxWidth 1500 /FontFile2 57 0 R >> endobj 57 0 obj << /Length 58 0 R /Length1 11360 /Filter /FlateDecode >> stream xÕZ tTUšþï[ª*•RY+I%õŠÊ¾’H¡©ö@“È’…@Â"‘% Fl "¶"‹âQÑV‘ˆ!B%ˆ46ØÚ ÝíÆíÖjÏè8ck·#IÕ|÷UUR êaÎñô9ó^þw·÷îýï÷÷¿KjíêuuLÍ$RieuãR¯´z"ö]íÊêFO:ì¤÷Ö6­U½´r[õÊ:„¸ÒÆâ‘ѸjÍZ5I©Ÿ#œÓ¸ºÎû>+'’î"†ÜhÚKê[…à^@¤ý\§æðr\W²kF,:ö[2èÔô¢é÷«á›_ÿç?¿kéIz0 –Ôâ}Ÿ‡šTW*QCùÈ uÄŽ«ŸøÑN*Kg$³š›ÎÎ ZH9”LqPèÖô3¬‹Æ Êy‰FÊ9EyjN¤÷+:ÃNÐtOù”BFoE'©ŠfÈq^×X¥Ò0Š¡¾Š:Ùi’¨2ÝÉ^T워ENšœî¤ñ‘ôô FjfÏЯ!O@Dj`÷Ò‡!R_ì9¤:ؽm’ÎÖÉî 6Å(™ç„G›ú@óLÓþ˜ù=ãÇ],TûE·SÀ={‚=N‹ÉÌž¦D¶‘J(…=r·Ô|Òê):œŠ7N˜Ÿ‹[aÞïd´™Œs2|ó€'X‡OO˜W¦î5/ÎV˧íu ­mæQ(Ÿg 4çXÌ#ã>1g%;u é̸iæ´ì?˜ð!^SPi¢Í`6Åí6FQ|œ=y4¤‹f(hKœbîDÝ=>9µ`¯“Ýy¼$%;ÑÉ6ÚòJRö¦–$'¦N3'¦''#>ï‚v«öVímŽ6]›¢MÒZ´±Úp]¨.D7D¤Óët:­“=ß6Þ¬éb­`…™µ×it²“½€L©‹Q3œÔI:AGºp§ûƒvŒd w²Öv‘"'4jLãdG@bžuÄf–xLR BÇO˜N )ä`÷95tOdÓxãøÐq†QÅE?ö¨RK|Ïô¿Œ,αwjY¹ãp\…#‡GÜq¾×¾È†kס¨®0=}êì;Ž75.[b¯³Ú«¬ö:H•ãÞ¦z££¹FQŽ-käŠCLªª©­çau£ÑZWäXf-RŽ5©ß *^‹›¬EÇh‰}Nù±%¶º¢¶&[“ÝZ]Tq¼¦põ‚míèkkuá´UÈ+[ÍÛªQ¿ÔÖ^\ÃÛZÀÛZÀÛª±Õ¨mñÎÛÊ ×¬;{ÃTÅ‘Ræ˜<«²Ü¡TW9Ù3È,Z×-‡Ð)9…šåÊ’Ì0Ü{n¢Ë÷Üs]ŸºÏ£|¥ë¿ÝcD¢”vK;¾›î£t”4tˆºá^Ò~z•–ÁÍgíô6ųá˜&$rÒ4zÜì’{ ýﯥ³´‡ŽQ¾YI(ÝÅ î"â5´•žt'PýŠNÑ(Ôº‹¾¤çÜÇÝ6šMsé0µâû×ÈÊŽ aÒ îOÜ:š…:·¢äMsu‡RÜY)r·ÒiÔ|Y¬wi ´{”§ƒô2}A[X;«w7¹/º?t pŒ&*ý‰ÚÙ‡ì¨ø+éQ÷¿»]n34LC«U´›žBýGqwƒÕv¶œ­e»Ùf¶íÂ=R”ÜëÒÀeNÂ]B«h;µ¥sô5ý}ÅŒBˆ¸V|Eéþ»;¦¢—¼'uÔ„{î]èSiØ6‘•²Mì!Ôü'–&ÌÊ…õÂáSa†8_¼Cü“¸Fj“vÊûå@Í·®.÷y÷[î(Ì·Òjڌޥ‹ô }O"Ó0KdcX![ˆ»™`ÂAÖÁJ…nv‘þÂ>f_±kL‚„!]X+ìZ…³ÂBƒ¸G|Xü‹ø­8Näƒò_åDÍ¿ik\;\o¸Æ­ïÜ"éÈËÒ ZDÕèm#ÝD¿@/Žà> «£WÀ~L&ö%}ˆ…²–æãžÁf²%¬=Æ:qŸVuù÷B€`¢“P&Ô+…fá-H¬˜&N+Å£¸/ˆo‹×pËR˜!M’&K;i¥ôîg¤CÀæMi”GÀ:z:”Zµ+”-àºj©-N¸*ºÙ}&:pFLtȉ“«Íe>5ê‹<ÊU-+j ˆŽQç¨Â ¼_Õ2–Âû!V¥å[LæUÖ/¿˜SíÍÑ$†|K¼º+Œ#/ošø\šˆ^×­õܾMªM‘¶í~Hsh¸ÎŽpÌï¥å‡R ,63¦:) ´üc»*œÌ}“Šâ:°Þ-Dq§ZCÚG"3iĆg(Åh¹˜sEiQZ&/nQŠ•zIJTCÔµTdÁ²ràDsТ­"¶/ZWQ1õdñzð ^o©@ ˼5 T³²zñÒˆ ̵bRiù¬rGsQ¬ÃVT+€¾Ý¥åŽn0·¢oe÷i ù¢Ú£stÎNCy®§,mšQEEK ¯³¬Üjqt·´Ä¶ðñæI; ΰy3œÄ_á;Ys)¾E`µÄª6°X-P«‚cz(íc–ô?p^ŸÞø2Úæ©üLº„GßÂcú4€ðXè<†#|ó¿áqÿÓÛúô†’ ­ME¸ðgBxâ \tCÛû4€p1t¶s„'ýë.€ðäŸFxJŸÞPr*´¢"<ígBxú <㆞٧é„K¡óLŽð¬³ \öÓÏéÓJÎ…¶sT„çýLßr#—ßÂ}š@¸:Wp„oíCØë ?Ü<ÈíÒÏî˜çûAŽ•’J…Â(ì«S'£ò<l¬¡GEØi‚¬‚l‚d@¶²ó´ûóf„;4‡Gd5êØüÛPÏù<}‹øMch†ñ½;® lK¶#TèŒ7GÍôpêr#*ÿKöæi~ l`–[Â<¯Ç3º#BCqØe PõÕ0 Ç–’_‘ê3J}þÿð³;~•à^Hè}ÀRI8,.”‚¤È5Øì\ÕšGµAÚ'pzóR@xÀê€ÃzvU…8Û¼(Ÿ‚´ÔÀϤËr’Ñ…8‰.Bx:¤;Ç®oBL«ÆD”¼žíåNbY±ÄعqXt©Ä3ˆWÑAsâS†OeÄFdç,†dH¡´ËÙó‘|êû‰Niúµã`Q'»*¼#ìƒ>® ¶¾Œ9¡ç-é#²Ã,ZˇìÉ.½°ma;I캌wM껪ªžÆÞ¸À‘Ÿ«µ^¹4üÒå˨'£äfôWOŠ<_y¾ù¢Ÿþ2ÏyÞðŒžÑ…†Œ+ÅÄ–f-¢U žëÚÁÆ}xårAoWÏëB¥°£w½XûýDæt•@ßGu#Ú–9¢èÛ@ ú‘“xCoˆ÷ãÅrúÎþ|Þõ¥ðybÏ, ö5z^à©a¨Snßü“µú«âUßcÎ`O–œH­F²¢#, OKN^~ûLØsîåô×߯ºrî>/EŒ]ãZ»‚íüÕó0ùÔ• Ï»{wK7»ÄÕ¿~RÕ§Ñý>6Ü“1îÆÐ÷þú˜y§ÌìlœÃyÆp?|GòŒ‘žn;ñÍ„X@LÄGi2$2 r d)d=ddäYÈIÈyHð‚ 2N˜ˆ>… plN#Élå$3Åk–é=Ôû7ˆ°Íè1BR H9¤²²²râ„\€/àà9)#$KV'Î<-ÈNÌÉÏφ°¡L£ÅÉ€e~^’uRÖ¼„Üœ¨H­¨‰ÌÆÚ!Ì:,9)ŸIùãX>ûtQíÓ ñ‰·å6Öå/ˆ4,bÇmfC@øê÷MM‹=”ÅŒOZ²D¹[341È—‘™´À4TžôÉ]{öÅ)W¬Ë˜üÌ&Í`SÖÒ•B¸.Ø9¿lZZÙï””ìïÝg&Š÷i ­¶’e/nßó›0Σ&÷UéÏòYøÊxú‹¿Ý¼Ã¸ŸÞqÑoÈn·?CòŒ@5ƒd@~ò 8ß ä€<Gò@A2Œ%À\0V'H¤š-u˜|„0{a!L „ „0&ÂB˜@a!L „ÉG·€&qËÍ 5Ä‘OÖZ7 ìÅ-ÂŽ½}ê‹UÎŒÊs½¼qRzJÜ3âò„šûîü C µœ}ð¬|¶÷?¦Ïr}éúÆårŒ±Nß!XŸ»zâÒ¾…Çð¯#V¹/ËIÀ2âèš?–C90Cý|Œ‰g˜ü…gü°Œä‘?÷ p’ ˜j|CAƒ¡ ñ  ì¢]4°‹vÑ`(h04   †?ÖÕ`(h04¸3m$ UíæñAàá¼:"£Âr™Ue¹ŸG¹9Bá¦7ÒÓïÚ¸ý­ôÄjaHZæš#®óOšçœYuüwyÙ¬àêëßyõµß^üýóŸ‹ûâ§ qßÛS[Î2¿ÿwÆ]pÞ侌£½I°j]ñÇ9†ƒãk8Ïç(vQþë%Áu;)è|¼ÒW:ðJ^éÀ+x¥¯tà•¼ÒW:ðJ^éÀ+W:ðJð:±â§•±1¨ÙâC×t->t-@×t-@×t-@×t-@×t-@×t-@×t-hŒÔFj-Ü_ÀäaܧX‡ a¡À1RÌKVÙ+ý2QfÖž¯â—î»oéXë±ð•cjaŸ}áÝ‚|6ÿ£Õ݆D?r×VqÛ¬Sž|ê•y“Æ<0¼Ô¬8Xár×늷oáØf¸ÆH¯J…d¦L6ÎÛxe¼¶Þy¥»Ï±ùF6ίBH >° Û° Û° Û° Û° Û° Û° >° Û ‚ÑWsVTݽj@-Ÿ¼¶ÍKÛ3’âžy3}îã®W¼qR0¸ûÍE“žÛôÂ¥›G±I›qzùh%yù]g×N0¥ß%IÖ‰Ûzr^oº|àé’ä±λ2»ôŸ,޳á·-zäÅSGk·žïæ«ö­X<¿I÷ø[ô:¯áÔø™ØÏ¡{KüŸ‰}~Z£šØëë ðõÜRª¯7ÀÂC`|½ê‡á Nµ¯›=ºvËßFÄXì¸?:Ô¼­ñíáÚáuߟeõTÅc½³„§šòËy»÷ç*ú%¬Áˆ¯aSý{æ]HõÏ]þËBÌV†¥![rò£“¬àdÆI)íÚÛò©×á[5«s¨3г*þѵšwÙØ?zÁû½Ë;=ÇJïà ûÕKJ𛞘ÎSñ`¹Ì*j¡™óÈ !ëS—Y?}¿}îùTO+;ïZÕ[#˜Z\·©:î@¿×©ýÐëëì9°×í/·».´óU7ªñðBs~4‰^ôGÏ[Ïu]ëÏæ] ö#J(Ïå}õv>–gÄúe$òŒD¡¤QÑÐc‡ÆcN ‡¢|ë…(pH]¢ñõÂõK4ƒÕr‘ã¦õò(ŠÏë|i:©>‘G<Þ.mSfYr{󄄈™ÇëÞÍ4Æïëz,²rú²“Ö­'ŠݸäÕŒ íRÖþ™ 7O(žWöèœ]½ùÂçËKw=Óû€Ðµ2gêcorÎyÆÒA`ýƒc©¢ëVKýtðB4Ð]êIVqàë&¬Ò=ë¦àâK!K!K!K!K!Þ±¤õë;ï2œ & ÞíV¥ª«þ“á1ÃÚH¯ú³Â» éï¡ßò"¡5~áY`KpÅ’ÏK¨G‚Ö´– µW,ÁKpÅ\±W,Áó KpÅ’êŠCPŸÞçŠõ €>UICW¬‡+ÖÃëáŠõpÅz¸b=\±®XW¬÷¹b=\±Þ㊽dàÞ64_ Ë0!ŸÏ¡¡âeÅ”ÙùôkI uO?óA¾ë%×?¯œ9šÍûìÍ…Ô½ êiký„ muõº^`é=XÚÛ\_€ƒâàáÿÊ:¿±Ó#Ÿ6aÕ>ùxùxÀ-ÃÿMDƒ€h?"£´Ã±ŸÐpû¯hMV^Y.M)!1!ÛOFoÝ;òâiQ8ººw¿êns¿#M“¦ÒpzÏßÚa\Ë0?-ÓyF:¿|sß]}ºÏæ|»&ÁFl$ÁFl„…d)d=ddäYÈIÈyˆwº”`#N'…¡¾(µfS×ý|»f›øò]Ý®™ÐwúnBßMè» l2M&°É6™À&Ød›L`ßÀOxÖ÷ù AK–˻³úXiÆd­î‚1U³¼ÀØìC‹[Ææ [¹mKAIabÇ×ÓGëLY/¹cÈбÖ)·;GU*ñ®kW¿z8–•Vޏå–[í ‘q ÃÒ&ÿrÿK»*ëoΙ4ÃVœ—•aèþ‹ï=ÁýÇ÷WÂr%úQéÁ›³ 8»èaQó(?#øíHðÂÏ—Ÿï†)ûÑHÕ1Š˜àDo·ÕfR~˜5?—½vÂÖjnÝ4,,;8>"ÞbOÞ<>rßæäJ×[»{íaLØ ûåRá•Ý\ßoqΰÿ‡¢þü¸nŽðÎ5ýÊ_çµ¼7Z¿)¡ß#v¢!mßé‹xó`À0µà,Ä*ò¿ÎX¶õ÷ »¯½÷Ó®4צ®ÙRVO»8­§Cœtí’xsÏo¡®Êmü>P⺠{‘Xqò~ëÓ †ƒ$fÉ·hùIÌl1¾·}˜8ÎÜó™Ð2¬§y—Hw÷Êy{"?#•ò1b±~^ï—žþ‰žþŒ~7ृwÁ ­º0מÀN‹ï]†àè!fFŽÏFuÔð7>VV}n€ÓÀÊ-ŸŸ'ççåkÍn7$DZc£gç$¶Å·Ÿk;·'~O‚‰õf´g\mÿ¨]nš/¿ØÜvõ,Ýu¨qÖ믟¿†³Èý ¤?Tù¡+ZÅŸ¼&PåRÙá Jð[/þ—ø…!ÿ ÿ¡Ë<8ˆJü޲_0¬˜Z߃ÒôÒ©eåé%u+šêÖ6ÔVgάYÑp;~aÊßô]ü Û!Ü“‚8!˜¤é]Èçïðb„¤@ %rH=dd;d?äÄ ¹yò¹Û{¡ê‹3R¥3¥‡JO”ž6(]:(]=(]3(½xPZµƒŸ~K•£Ÿôo”^>(Íqõï¯úÛ\¿úù Ô¿|Õ ôêAé5ƒÒêomýêã§yþõm˜¾¦ZüUwÞ endstream endobj 58 0 obj 6273 endobj 59 0 obj (sumaclust_user_manual) endobj 60 0 obj (Mac OS X 10.10.4 Quartz PDFContext) endobj 61 0 obj (MacDown) endobj 62 0 obj (D:20150806115324Z00'00') endobj 63 0 obj () endobj 64 0 obj [ ] endobj 1 0 obj << /Title 59 0 R /Producer 60 0 R /Creator 61 0 R /CreationDate 62 0 R /ModDate 62 0 R /Keywords 63 0 R /AAPL:Keywords 64 0 R >> endobj xref 0 65 0000000000 65535 f 0000078269 00000 n 0000003919 00000 n 0000027594 00000 n 0000000022 00000 n 0000003899 00000 n 0000004038 00000 n 0000006949 00000 n 0000045695 00000 n 0000028989 00000 n 0000004158 00000 n 0000028707 00000 n 0000028470 00000 n 0000028215 00000 n 0000027991 00000 n 0000027755 00000 n 0000061142 00000 n 0000004213 00000 n 0000006928 00000 n 0000011310 00000 n 0000006985 00000 n 0000011289 00000 n 0000011417 00000 n 0000015782 00000 n 0000011538 00000 n 0000015761 00000 n 0000015889 00000 n 0000023616 00000 n 0000016010 00000 n 0000023595 00000 n 0000023723 00000 n 0000027365 00000 n 0000023844 00000 n 0000027344 00000 n 0000027472 00000 n 0000070814 00000 n 0000027705 00000 n 0000027877 00000 n 0000027933 00000 n 0000028113 00000 n 0000028169 00000 n 0000028336 00000 n 0000028392 00000 n 0000028592 00000 n 0000028648 00000 n 0000028829 00000 n 0000028885 00000 n 0000029650 00000 n 0000029882 00000 n 0000045673 00000 n 0000046387 00000 n 0000046637 00000 n 0000061120 00000 n 0000061575 00000 n 0000061833 00000 n 0000070793 00000 n 0000071424 00000 n 0000071684 00000 n 0000078048 00000 n 0000078069 00000 n 0000078109 00000 n 0000078162 00000 n 0000078188 00000 n 0000078230 00000 n 0000078249 00000 n trailer << /Size 65 /Root 36 0 R /Info 1 0 R /ID [ ] >> startxref 78413 %%EOF sumaclust_v1.0.10/sumalibs/000755 000765 000024 00000000000 12551723264 017660 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/sumalibs/global.mk000644 000765 000024 00000000136 12551723264 021451 0ustar00celinemercierstaff000000 000000 CC=gcc LDFLAGS= CFLAGS = -O3 -w default: all %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< $(LIB) sumaclust_v1.0.10/sumalibs/libfasta/000755 000765 000024 00000000000 12551723473 021447 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/sumalibs/libfile/000755 000765 000024 00000000000 12551723473 021270 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/sumalibs/liblcs/000755 000765 000024 00000000000 12551723473 021132 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/sumalibs/libsse/000755 000765 000024 00000000000 12551723264 021141 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/sumalibs/libutils/000755 000765 000024 00000000000 12551723473 021511 5ustar00celinemercierstaff000000 000000 sumaclust_v1.0.10/sumalibs/Licence_CeCILL_V2-en.txt000644 000765 000024 00000051151 12551723264 024010 0ustar00celinemercierstaff000000 000000 CeCILL FREE SOFTWARE LICENSE AGREEMENT Notice This Agreement is a Free Software license agreement that is the result of discussions between its authors in order to ensure compliance with the two main principles guiding its drafting: * firstly, compliance with the principles governing the distribution of Free Software: access to source code, broad rights granted to users, * secondly, the election of a governing law, French law, with which it is conformant, both as regards the law of torts and intellectual property law, and the protection that it offers to both authors and holders of the economic rights over software. The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) license are: Commissariat à l'Energie Atomique - CEA, a public scientific, technical and industrial research establishment, having its principal place of business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France. Centre National de la Recherche Scientifique - CNRS, a public scientific and technological establishment, having its principal place of business at 3 rue Michel-Ange, 75794 Paris cedex 16, France. Institut National de Recherche en Informatique et en Automatique - INRIA, a public scientific and technological establishment, having its principal place of business at Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex, France. Preamble The purpose of this Free Software license agreement is to grant users the right to modify and redistribute the software governed by this license within the framework of an open source distribution model. The exercising of these rights is conditional upon certain obligations for users so as to preserve this status for all subsequent redistributions. In consideration of access to the source code and the rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors only have limited liability. In this respect, the risks associated with loading, using, modifying and/or developing or reproducing the software by the user are brought to the user's attention, given its Free Software status, which may make it complicated to use, with the result that its use is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the suitability of the software as regards their requirements in conditions enabling the security of their systems and/or data to be ensured and, more generally, to use and operate it in the same conditions of security. This Agreement may be freely reproduced and published, provided it is not altered, and that no provisions are either added or removed herefrom. This Agreement may apply to any or all software for which the holder of the economic rights decides to submit the use thereof to its provisions. Article 1 - DEFINITIONS For the purpose of this Agreement, when the following expressions commence with a capital letter, they shall have the following meaning: Agreement: means this license agreement, and its possible subsequent versions and annexes. Software: means the software in its Object Code and/or Source Code form and, where applicable, its documentation, "as is" when the Licensee accepts the Agreement. Initial Software: means the Software in its Source Code and possibly its Object Code form and, where applicable, its documentation, "as is" when it is first distributed under the terms and conditions of the Agreement. Modified Software: means the Software modified by at least one Contribution. Source Code: means all the Software's instructions and program lines to which access is required so as to modify the Software. Object Code: means the binary files originating from the compilation of the Source Code. Holder: means the holder(s) of the economic rights over the Initial Software. Licensee: means the Software user(s) having accepted the Agreement. Contributor: means a Licensee having made at least one Contribution. Licensor: means the Holder, or any other individual or legal entity, who distributes the Software under the Agreement. Contribution: means any or all modifications, corrections, translations, adaptations and/or new functions integrated into the Software by any or all Contributors, as well as any or all Internal Modules. Module: means a set of sources files including their documentation that enables supplementary functions or services in addition to those offered by the Software. External Module: means any or all Modules, not derived from the Software, so that this Module and the Software run in separate address spaces, with one calling the other when they are run. Internal Module: means any or all Module, connected to the Software so that they both execute in the same address space. GNU GPL: means the GNU General Public License version 2 or any subsequent version, as published by the Free Software Foundation Inc. Parties: mean both the Licensee and the Licensor. These expressions may be used both in singular and plural form. Article 2 - PURPOSE The purpose of the Agreement is the grant by the Licensor to the Licensee of a non-exclusive, transferable and worldwide license for the Software as set forth in Article 5 hereinafter for the whole term of the protection granted by the rights over said Software. Article 3 - ACCEPTANCE 3.1 The Licensee shall be deemed as having accepted the terms and conditions of this Agreement upon the occurrence of the first of the following events: * (i) loading the Software by any or all means, notably, by downloading from a remote server, or by loading from a physical medium; * (ii) the first time the Licensee exercises any of the rights granted hereunder. 3.2 One copy of the Agreement, containing a notice relating to the characteristics of the Software, to the limited warranty, and to the fact that its use is restricted to experienced users has been provided to the Licensee prior to its acceptance as set forth in Article 3.1 hereinabove, and the Licensee hereby acknowledges that it has read and understood it. Article 4 - EFFECTIVE DATE AND TERM 4.1 EFFECTIVE DATE The Agreement shall become effective on the date when it is accepted by the Licensee as set forth in Article 3.1. 4.2 TERM The Agreement shall remain in force for the entire legal term of protection of the economic rights over the Software. Article 5 - SCOPE OF RIGHTS GRANTED The Licensor hereby grants to the Licensee, who accepts, the following rights over the Software for any or all use, and for the term of the Agreement, on the basis of the terms and conditions set forth hereinafter. Besides, if the Licensor owns or comes to own one or more patents protecting all or part of the functions of the Software or of its components, the Licensor undertakes not to enforce the rights granted by these patents against successive Licensees using, exploiting or modifying the Software. If these patents are transferred, the Licensor undertakes to have the transferees subscribe to the obligations set forth in this paragraph. 5.1 RIGHT OF USE The Licensee is authorized to use the Software, without any limitation as to its fields of application, with it being hereinafter specified that this comprises: 1. permanent or temporary reproduction of all or part of the Software by any or all means and in any or all form. 2. loading, displaying, running, or storing the Software on any or all medium. 3. entitlement to observe, study or test its operation so as to determine the ideas and principles behind any or all constituent elements of said Software. This shall apply when the Licensee carries out any or all loading, displaying, running, transmission or storage operation as regards the Software, that it is entitled to carry out hereunder. 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS The right to make Contributions includes the right to translate, adapt, arrange, or make any or all modifications to the Software, and the right to reproduce the resulting software. The Licensee is authorized to make any or all Contributions to the Software provided that it includes an explicit notice that it is the author of said Contribution and indicates the date of the creation thereof. 5.3 RIGHT OF DISTRIBUTION In particular, the right of distribution includes the right to publish, transmit and communicate the Software to the general public on any or all medium, and by any or all means, and the right to market, either in consideration of a fee, or free of charge, one or more copies of the Software by any means. The Licensee is further authorized to distribute copies of the modified or unmodified Software to third parties according to the terms and conditions set forth hereinafter. 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION The Licensee is authorized to distribute true copies of the Software in Source Code or Object Code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the Object Code of the Software is redistributed, the Licensee allows future Licensees unhindered access to the full Source Code of the Software by indicating how to access it, it being understood that the additional cost of acquiring the Source Code shall not exceed the cost of transferring the data. 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE When the Licensee makes a Contribution to the Software, the terms and conditions for the distribution of the resulting Modified Software become subject to all the provisions of this Agreement. The Licensee is authorized to distribute the Modified Software, in source code or object code form, provided that said distribution complies with all the provisions of the Agreement and is accompanied by: 1. a copy of the Agreement, 2. a notice relating to the limitation of both the Licensor's warranty and liability as set forth in Articles 8 and 9, and that, in the event that only the object code of the Modified Software is redistributed, the Licensee allows future Licensees unhindered access to the full source code of the Modified Software by indicating how to access it, it being understood that the additional cost of acquiring the source code shall not exceed the cost of transferring the data. 5.3.3 DISTRIBUTION OF EXTERNAL MODULES When the Licensee has developed an External Module, the terms and conditions of this Agreement do not apply to said External Module, that may be distributed under a separate license agreement. 5.3.4 COMPATIBILITY WITH THE GNU GPL The Licensee can include a code that is subject to the provisions of one of the versions of the GNU GPL in the Modified or unmodified Software, and distribute that entire code under the terms of the same version of the GNU GPL. The Licensee can include the Modified or unmodified Software in a code that is subject to the provisions of one of the versions of the GNU GPL, and distribute that entire code under the terms of the same version of the GNU GPL. Article 6 - INTELLECTUAL PROPERTY 6.1 OVER THE INITIAL SOFTWARE The Holder owns the economic rights over the Initial Software. Any or all use of the Initial Software is subject to compliance with the terms and conditions under which the Holder has elected to distribute its work and no one shall be entitled to modify the terms and conditions for the distribution of said Initial Software. The Holder undertakes that the Initial Software will remain ruled at least by this Agreement, for the duration set forth in Article 4.2. 6.2 OVER THE CONTRIBUTIONS The Licensee who develops a Contribution is the owner of the intellectual property rights over this Contribution as defined by applicable law. 6.3 OVER THE EXTERNAL MODULES The Licensee who develops an External Module is the owner of the intellectual property rights over this External Module as defined by applicable law and is free to choose the type of agreement that shall govern its distribution. 6.4 JOINT PROVISIONS The Licensee expressly undertakes: 1. not to remove, or modify, in any manner, the intellectual property notices attached to the Software; 2. to reproduce said notices, in an identical manner, in the copies of the Software modified or not. The Licensee undertakes not to directly or indirectly infringe the intellectual property rights of the Holder and/or Contributors on the Software and to take, where applicable, vis-à-vis its staff, any and all measures required to ensure respect of said intellectual property rights of the Holder and/or Contributors. Article 7 - RELATED SERVICES 7.1 Under no circumstances shall the Agreement oblige the Licensor to provide technical assistance or maintenance services for the Software. However, the Licensor is entitled to offer this type of services. The terms and conditions of such technical assistance, and/or such maintenance, shall be set forth in a separate instrument. Only the Licensor offering said maintenance and/or technical assistance services shall incur liability therefor. 7.2 Similarly, any Licensor is entitled to offer to its licensees, under its sole responsibility, a warranty, that shall only be binding upon itself, for the redistribution of the Software and/or the Modified Software, under terms and conditions that it is free to decide. Said warranty, and the financial terms and conditions of its application, shall be subject of a separate instrument executed between the Licensor and the Licensee. Article 8 - LIABILITY 8.1 Subject to the provisions of Article 8.2, the Licensee shall be entitled to claim compensation for any direct loss it may have suffered from the Software as a result of a fault on the part of the relevant Licensor, subject to providing evidence thereof. 8.2 The Licensor's liability is limited to the commitments made under this Agreement and shall not be incurred as a result of in particular: (i) loss due the Licensee's total or partial failure to fulfill its obligations, (ii) direct or consequential loss that is suffered by the Licensee due to the use or performance of the Software, and (iii) more generally, any consequential loss. In particular the Parties expressly agree that any or all pecuniary or business loss (i.e. loss of data, loss of profits, operating loss, loss of customers or orders, opportunity cost, any disturbance to business activities) or any or all legal proceedings instituted against the Licensee by a third party, shall constitute consequential loss and shall not provide entitlement to any or all compensation from the Licensor. Article 9 - WARRANTY 9.1 The Licensee acknowledges that the scientific and technical state-of-the-art when the Software was distributed did not enable all possible uses to be tested and verified, nor for the presence of possible defects to be detected. In this respect, the Licensee's attention has been drawn to the risks associated with loading, using, modifying and/or developing and reproducing the Software which are reserved for experienced users. The Licensee shall be responsible for verifying, by any or all means, the suitability of the product for its requirements, its good working order, and for ensuring that it shall not cause damage to either persons or properties. 9.2 The Licensor hereby represents, in good faith, that it is entitled to grant all the rights over the Software (including in particular the rights set forth in Article 5). 9.3 The Licensee acknowledges that the Software is supplied "as is" by the Licensor without any other express or tacit warranty, other than that provided for in Article 9.2 and, in particular, without any warranty as to its commercial value, its secured, safe, innovative or relevant nature. Specifically, the Licensor does not warrant that the Software is free from any error, that it will operate without interruption, that it will be compatible with the Licensee's own equipment and software configuration, nor that it will meet the Licensee's requirements. 9.4 The Licensor does not either expressly or tacitly warrant that the Software does not infringe any third party intellectual property right relating to a patent, software or any other property right. Therefore, the Licensor disclaims any and all liability towards the Licensee arising out of any or all proceedings for infringement that may be instituted in respect of the use, modification and redistribution of the Software. Nevertheless, should such proceedings be instituted against the Licensee, the Licensor shall provide it with technical and legal assistance for its defense. Such technical and legal assistance shall be decided on a case-by-case basis between the relevant Licensor and the Licensee pursuant to a memorandum of understanding. The Licensor disclaims any and all liability as regards the Licensee's use of the name of the Software. No warranty is given as regards the existence of prior rights over the name of the Software or as regards the existence of a trademark. Article 10 - TERMINATION 10.1 In the event of a breach by the Licensee of its obligations hereunder, the Licensor may automatically terminate this Agreement thirty (30) days after notice has been sent to the Licensee and has remained ineffective. 10.2 A Licensee whose Agreement is terminated shall no longer be authorized to use, modify or distribute the Software. However, any licenses that it may have granted prior to termination of the Agreement shall remain valid subject to their having been granted in compliance with the terms and conditions hereof. Article 11 - MISCELLANEOUS 11.1 EXCUSABLE EVENTS Neither Party shall be liable for any or all delay, or failure to perform the Agreement, that may be attributable to an event of force majeure, an act of God or an outside cause, such as defective functioning or interruptions of the electricity or telecommunications networks, network paralysis following a virus attack, intervention by government authorities, natural disasters, water damage, earthquakes, fire, explosions, strikes and labor unrest, war, etc. 11.2 Any failure by either Party, on one or more occasions, to invoke one or more of the provisions hereof, shall under no circumstances be interpreted as being a waiver by the interested Party of its right to invoke said provision(s) subsequently. 11.3 The Agreement cancels and replaces any or all previous agreements, whether written or oral, between the Parties and having the same purpose, and constitutes the entirety of the agreement between said Parties concerning said purpose. No supplement or modification to the terms and conditions hereof shall be effective as between the Parties unless it is made in writing and signed by their duly authorized representatives. 11.4 In the event that one or more of the provisions hereof were to conflict with a current or future applicable act or legislative text, said act or legislative text shall prevail, and the Parties shall make the necessary amendments so as to comply with said act or legislative text. All other provisions shall remain effective. Similarly, invalidity of a provision of the Agreement, for any reason whatsoever, shall not cause the Agreement as a whole to be invalid. 11.5 LANGUAGE The Agreement is drafted in both French and English and both versions are deemed authentic. Article 12 - NEW VERSIONS OF THE AGREEMENT 12.1 Any person is authorized to duplicate and distribute copies of this Agreement. 12.2 So as to ensure coherence, the wording of this Agreement is protected and may only be modified by the authors of the License, who reserve the right to periodically publish updates or new versions of the Agreement, each with a separate number. These subsequent versions may address new issues encountered by Free Software. 12.3 Any Software distributed under a given version of the Agreement may only be subsequently distributed under the same version of the Agreement or a subsequent version, subject to the provisions of Article 5.3.4. Article 13 - GOVERNING LAW AND JURISDICTION 13.1 The Agreement is governed by French law. The Parties agree to endeavor to seek an amicable solution to any disagreements or disputes that may arise during the performance of the Agreement. 13.2 Failing an amicable solution within two (2) months as from their occurrence, and unless emergency proceedings are necessary, the disagreements or disputes shall be referred to the Paris Courts having jurisdiction, by the more diligent Party. Version 2.0 dated 2006-09-05. sumaclust_v1.0.10/sumalibs/Licence_CeCILL_V2-fr.txt000644 000765 000024 00000051733 12551723264 024023 0ustar00celinemercierstaff000000 000000 CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL Avertissement Ce contrat est une licence de logiciel libre issue d'une concertation entre ses auteurs afin que le respect de deux grands principes préside à sa rédaction: * d'une part, le respect des principes de diffusion des logiciels libres: accès au code source, droits étendus conférés aux utilisateurs, * d'autre part, la désignation d'un droit applicable, le droit français, auquel elle est conforme, tant au regard du droit de la responsabilité civile que du droit de la propriété intellectuelle et de la protection qu'il offre aux auteurs et titulaires des droits patrimoniaux sur un logiciel. Les auteurs de la licence CeCILL (pour Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre]) sont: Commissariat à l'Energie Atomique - CEA, établissement public de recherche à caractère scientifique, technique et industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris. Centre National de la Recherche Scientifique - CNRS, établissement public à caractère scientifique et technologique, dont le siège est situé 3 rue Michel-Ange, 75794 Paris cedex 16. Institut National de Recherche en Informatique et en Automatique - INRIA, établissement public à caractère scientifique et technologique, dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex. Préambule Ce contrat est une licence de logiciel libre dont l'objectif est de conférer aux utilisateurs la liberté de modification et de redistribution du logiciel régi par cette licence dans le cadre d'un modèle de diffusion en logiciel libre. L'exercice de ces libertés est assorti de certains devoirs à la charge des utilisateurs afin de préserver ce statut au cours des redistributions ultérieures. L'accessibilité au code source et les droits de copie, de modification et de redistribution qui en découlent ont pour contrepartie de n'offrir aux utilisateurs qu'une garantie limitée et de ne faire peser sur l'auteur du logiciel, le titulaire des droits patrimoniaux et les concédants successifs qu'une responsabilité restreinte. A cet égard l'attention de l'utilisateur est attirée sur les risques associés au chargement, à l'utilisation, à la modification et/ou au développement et à la reproduction du logiciel par l'utilisateur étant donné sa spécificité de logiciel libre, qui peut le rendre complexe à manipuler et qui le réserve donc à des développeurs ou des professionnels avertis possédant des connaissances informatiques approfondies. Les utilisateurs sont donc invités à charger et tester l'adéquation du logiciel à leurs besoins dans des conditions permettant d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus généralement, à l'utiliser et l'exploiter dans les mêmes conditions de sécurité. Ce contrat peut être reproduit et diffusé librement, sous réserve de le conserver en l'état, sans ajout ni suppression de clauses. Ce contrat est susceptible de s'appliquer à tout logiciel dont le titulaire des droits patrimoniaux décide de soumettre l'exploitation aux dispositions qu'il contient. Article 1 - DEFINITIONS Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une lettre capitale, auront la signification suivante: Contrat: désigne le présent contrat de licence, ses éventuelles versions postérieures et annexes. Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code Source et le cas échéant sa documentation, dans leur état au moment de l'acceptation du Contrat par le Licencié. Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et éventuellement de Code Objet et le cas échéant sa documentation, dans leur état au moment de leur première diffusion sous les termes du Contrat. Logiciel Modifié: désigne le Logiciel modifié par au moins une Contribution. Code Source: désigne l'ensemble des instructions et des lignes de programme du Logiciel et auquel l'accès est nécessaire en vue de modifier le Logiciel. Code Objet: désigne les fichiers binaires issus de la compilation du Code Source. Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur sur le Logiciel Initial. Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le Contrat. Contributeur: désigne le Licencié auteur d'au moins une Contribution. Concédant: désigne le Titulaire ou toute personne physique ou morale distribuant le Logiciel sous le Contrat. Contribution: désigne l'ensemble des modifications, corrections, traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans le Logiciel par tout Contributeur, ainsi que tout Module Interne. Module: désigne un ensemble de fichiers sources y compris leur documentation qui permet de réaliser des fonctionnalités ou services supplémentaires à ceux fournis par le Logiciel. Module Externe: désigne tout Module, non dérivé du Logiciel, tel que ce Module et le Logiciel s'exécutent dans des espaces d'adressage différents, l'un appelant l'autre au moment de leur exécution. Module Interne: désigne tout Module lié au Logiciel de telle sorte qu'ils s'exécutent dans le même espace d'adressage. GNU GPL: désigne la GNU General Public License dans sa version 2 ou toute version ultérieure, telle que publiée par Free Software Foundation Inc. Parties: désigne collectivement le Licencié et le Concédant. Ces termes s'entendent au singulier comme au pluriel. Article 2 - OBJET Le Contrat a pour objet la concession par le Concédant au Licencié d'une licence non exclusive, cessible et mondiale du Logiciel telle que définie ci-après à l'article 5 pour toute la durée de protection des droits portant sur ce Logiciel. Article 3 - ACCEPTATION 3.1 L'acceptation par le Licencié des termes du Contrat est réputée acquise du fait du premier des faits suivants: * (i) le chargement du Logiciel par tout moyen notamment par téléchargement à partir d'un serveur distant ou par chargement à partir d'un support physique; * (ii) le premier exercice par le Licencié de l'un quelconque des droits concédés par le Contrat. 3.2 Un exemplaire du Contrat, contenant notamment un avertissement relatif aux spécificités du Logiciel, à la restriction de garantie et à la limitation à un usage par des utilisateurs expérimentés a été mis à disposition du Licencié préalablement à son acceptation telle que définie à l'article 3.1 ci dessus et le Licencié reconnaît en avoir pris connaissance. Article 4 - ENTREE EN VIGUEUR ET DUREE 4.1 ENTREE EN VIGUEUR Le Contrat entre en vigueur à la date de son acceptation par le Licencié telle que définie en 3.1. 4.2 DUREE Le Contrat produira ses effets pendant toute la durée légale de protection des droits patrimoniaux portant sur le Logiciel. Article 5 - ETENDUE DES DROITS CONCEDES Le Concédant concède au Licencié, qui accepte, les droits suivants sur le Logiciel pour toutes destinations et pour la durée du Contrat dans les conditions ci-après détaillées. Par ailleurs, si le Concédant détient ou venait à détenir un ou plusieurs brevets d'invention protégeant tout ou partie des fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas opposer les éventuels droits conférés par ces brevets aux Licenciés successifs qui utiliseraient, exploiteraient ou modifieraient le Logiciel. En cas de cession de ces brevets, le Concédant s'engage à faire reprendre les obligations du présent alinéa aux cessionnaires. 5.1 DROIT D'UTILISATION Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant aux domaines d'application, étant ci-après précisé que cela comporte: 1. la reproduction permanente ou provisoire du Logiciel en tout ou partie par tout moyen et sous toute forme. 2. le chargement, l'affichage, l'exécution, ou le stockage du Logiciel sur tout support. 3. la possibilité d'en observer, d'en étudier, ou d'en tester le fonctionnement afin de déterminer les idées et principes qui sont à la base de n'importe quel élément de ce Logiciel; et ceci, lorsque le Licencié effectue toute opération de chargement, d'affichage, d'exécution, de transmission ou de stockage du Logiciel qu'il est en droit d'effectuer en vertu du Contrat. 5.2 DROIT D'APPORTER DES CONTRIBUTIONS Le droit d'apporter des Contributions comporte le droit de traduire, d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel et le droit de reproduire le logiciel en résultant. Le Licencié est autorisé à apporter toute Contribution au Logiciel sous réserve de mentionner, de façon explicite, son nom en tant qu'auteur de cette Contribution et la date de création de celle-ci. 5.3 DROIT DE DISTRIBUTION Le droit de distribution comporte notamment le droit de diffuser, de transmettre et de communiquer le Logiciel au public sur tout support et par tout moyen ainsi que le droit de mettre sur le marché à titre onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé. Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou non, à des tiers dans les conditions ci-après détaillées. 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION Le Licencié est autorisé à distribuer des copies conformes du Logiciel, sous forme de Code Source ou de Code Objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le Code Objet du Logiciel est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au Code Source complet du Logiciel en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du Code Source ne devra pas excéder le simple coût de transfert des données. 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE Lorsque le Licencié apporte une Contribution au Logiciel, les conditions de distribution du Logiciel Modifié en résultant sont alors soumises à l'intégralité des dispositions du Contrat. Le Licencié est autorisé à distribuer le Logiciel Modifié, sous forme de code source ou de code objet, à condition que cette distribution respecte les dispositions du Contrat dans leur totalité et soit accompagnée: 1. d'un exemplaire du Contrat, 2. d'un avertissement relatif à la restriction de garantie et de responsabilité du Concédant telle que prévue aux articles 8 et 9, et que, dans le cas où seul le code objet du Logiciel Modifié est redistribué, le Licencié permette aux futurs Licenciés d'accéder facilement au code source complet du Logiciel Modifié en indiquant les modalités d'accès, étant entendu que le coût additionnel d'acquisition du code source ne devra pas excéder le simple coût de transfert des données. 5.3.3 DISTRIBUTION DES MODULES EXTERNES Lorsque le Licencié a développé un Module Externe les conditions du Contrat ne s'appliquent pas à ce Module Externe, qui peut être distribué sous un contrat de licence différent. 5.3.4 COMPATIBILITE AVEC LA LICENCE GNU GPL Le Licencié peut inclure un code soumis aux dispositions d'une des versions de la licence GNU GPL dans le Logiciel modifié ou non et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Le Licencié peut inclure le Logiciel modifié ou non dans un code soumis aux dispositions d'une des versions de la licence GNU GPL et distribuer l'ensemble sous les conditions de la même version de la licence GNU GPL. Article 6 - PROPRIETE INTELLECTUELLE 6.1 SUR LE LOGICIEL INITIAL Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel Initial. Toute utilisation du Logiciel Initial est soumise au respect des conditions dans lesquelles le Titulaire a choisi de diffuser son oeuvre et nul autre n'a la faculté de modifier les conditions de diffusion de ce Logiciel Initial. Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi par le Contrat et ce, pour la durée visée à l'article 4.2. 6.2 SUR LES CONTRIBUTIONS Le Licencié qui a développé une Contribution est titulaire sur celle-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable. 6.3 SUR LES MODULES EXTERNES Le Licencié qui a développé un Module Externe est titulaire sur celui-ci des droits de propriété intellectuelle dans les conditions définies par la législation applicable et reste libre du choix du contrat régissant sa diffusion. 6.4 DISPOSITIONS COMMUNES Le Licencié s'engage expressément: 1. à ne pas supprimer ou modifier de quelque manière que ce soit les mentions de propriété intellectuelle apposées sur le Logiciel; 2. à reproduire à l'identique lesdites mentions de propriété intellectuelle sur les copies du Logiciel modifié ou non. Le Licencié s'engage à ne pas porter atteinte, directement ou indirectement, aux droits de propriété intellectuelle du Titulaire et/ou des Contributeurs sur le Logiciel et à prendre, le cas échéant, à l'égard de son personnel toutes les mesures nécessaires pour assurer le respect des dits droits de propriété intellectuelle du Titulaire et/ou des Contributeurs. Article 7 - SERVICES ASSOCIES 7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de prestations d'assistance technique ou de maintenance du Logiciel. Cependant le Concédant reste libre de proposer ce type de services. Les termes et conditions d'une telle assistance technique et/ou d'une telle maintenance seront alors déterminés dans un acte séparé. Ces actes de maintenance et/ou assistance technique n'engageront que la seule responsabilité du Concédant qui les propose. 7.2 De même, tout Concédant est libre de proposer, sous sa seule responsabilité, à ses licenciés une garantie, qui n'engagera que lui, lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce, dans les conditions qu'il souhaite. Cette garantie et les modalités financières de son application feront l'objet d'un acte séparé entre le Concédant et le Licencié. Article 8 - RESPONSABILITE 8.1 Sous réserve des dispositions de l'article 8.2, le Licencié a la faculté, sous réserve de prouver la faute du Concédant concerné, de solliciter la réparation du préjudice direct qu'il subirait du fait du Logiciel et dont il apportera la preuve. 8.2 La responsabilité du Concédant est limitée aux engagements pris en application du Contrat et ne saurait être engagée en raison notamment: (i) des dommages dus à l'inexécution, totale ou partielle, de ses obligations par le Licencié, (ii) des dommages directs ou indirects découlant de l'utilisation ou des performances du Logiciel subis par le Licencié et (iii) plus généralement d'un quelconque dommage indirect. En particulier, les Parties conviennent expressément que tout préjudice financier ou commercial (par exemple perte de données, perte de bénéfices, perte d'exploitation, perte de clientèle ou de commandes, manque à gagner, trouble commercial quelconque) ou toute action dirigée contre le Licencié par un tiers, constitue un dommage indirect et n'ouvre pas droit à réparation par le Concédant. Article 9 - GARANTIE 9.1 Le Licencié reconnaît que l'état actuel des connaissances scientifiques et techniques au moment de la mise en circulation du Logiciel ne permet pas d'en tester et d'en vérifier toutes les utilisations ni de détecter l'existence d'éventuels défauts. L'attention du Licencié a été attirée sur ce point sur les risques associés au chargement, à l'utilisation, la modification et/ou au développement et à la reproduction du Logiciel qui sont réservés à des utilisateurs avertis. Il relève de la responsabilité du Licencié de contrôler, par tous moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens. 9.2 Le Concédant déclare de bonne foi être en droit de concéder l'ensemble des droits attachés au Logiciel (comprenant notamment les droits visés à l'article 5). 9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le Concédant sans autre garantie, expresse ou tacite, que celle prévue à l'article 9.2 et notamment sans aucune garantie sur sa valeur commerciale, son caractère sécurisé, innovant ou pertinent. En particulier, le Concédant ne garantit pas que le Logiciel est exempt d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible avec l'équipement du Licencié et sa configuration logicielle ni qu'il remplira les besoins du Licencié. 9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le Logiciel ne porte pas atteinte à un quelconque droit de propriété intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout autre droit de propriété. Ainsi, le Concédant exclut toute garantie au profit du Licencié contre les actions en contrefaçon qui pourraient être diligentées au titre de l'utilisation, de la modification, et de la redistribution du Logiciel. Néanmoins, si de telles actions sont exercées contre le Licencié, le Concédant lui apportera son aide technique et juridique pour sa défense. Cette aide technique et juridique est déterminée au cas par cas entre le Concédant concerné et le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage toute responsabilité quant à l'utilisation de la dénomination du Logiciel par le Licencié. Aucune garantie n'est apportée quant à l'existence de droits antérieurs sur le nom du Logiciel et sur l'existence d'une marque. Article 10 - RESILIATION 10.1 En cas de manquement par le Licencié aux obligations mises à sa charge par le Contrat, le Concédant pourra résilier de plein droit le Contrat trente (30) jours après notification adressée au Licencié et restée sans effet. 10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé à utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les licences qu'il aura concédées antérieurement à la résiliation du Contrat resteront valides sous réserve qu'elles aient été effectuées en conformité avec le Contrat. Article 11 - DISPOSITIONS DIVERSES 11.1 CAUSE EXTERIEURE Aucune des Parties ne sera responsable d'un retard ou d'une défaillance d'exécution du Contrat qui serait dû à un cas de force majeure, un cas fortuit ou une cause extérieure, telle que, notamment, le mauvais fonctionnement ou les interruptions du réseau électrique ou de télécommunication, la paralysie du réseau liée à une attaque informatique, l'intervention des autorités gouvernementales, les catastrophes naturelles, les dégâts des eaux, les tremblements de terre, le feu, les explosions, les grèves et les conflits sociaux, l'état de guerre... 11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer renonciation par la Partie intéressée à s'en prévaloir ultérieurement. 11.3 Le Contrat annule et remplace toute convention antérieure, écrite ou orale, entre les Parties sur le même objet et constitue l'accord entier entre les Parties sur cet objet. Aucune addition ou modification aux termes du Contrat n'aura d'effet à l'égard des Parties à moins d'être faite par écrit et signée par leurs représentants dûment habilités. 11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat s'avèrerait contraire à une loi ou à un texte applicable, existants ou futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les amendements nécessaires pour se conformer à cette loi ou à ce texte. Toutes les autres dispositions resteront en vigueur. De même, la nullité, pour quelque raison que ce soit, d'une des dispositions du Contrat ne saurait entraîner la nullité de l'ensemble du Contrat. 11.5 LANGUE Le Contrat est rédigé en langue française et en langue anglaise, ces deux versions faisant également foi. Article 12 - NOUVELLES VERSIONS DU CONTRAT 12.1 Toute personne est autorisée à copier et distribuer des copies de ce Contrat. 12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé et ne peut être modifié que par les auteurs de la licence, lesquels se réservent le droit de publier périodiquement des mises à jour ou de nouvelles versions du Contrat, qui posséderont chacune un numéro distinct. Ces versions ultérieures seront susceptibles de prendre en compte de nouvelles problématiques rencontrées par les logiciels libres. 12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra faire l'objet d'une diffusion ultérieure que sous la même version du Contrat ou une version postérieure, sous réserve des dispositions de l'article 5.3.4. Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE 13.1 Le Contrat est régi par la loi française. Les Parties conviennent de tenter de régler à l'amiable les différends ou litiges qui viendraient à se produire par suite ou à l'occasion du Contrat. 13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter de leur survenance et sauf situation relevant d'une procédure d'urgence, les différends ou litiges seront portés par la Partie la plus diligente devant les Tribunaux compétents de Paris. Version 2.0 du 2006-09-05. sumaclust_v1.0.10/sumalibs/libutils/debug.c000644 000765 000024 00000000711 12551723264 022740 0ustar00celinemercierstaff000000 000000 /* * debug.c * * Created on: 4 sept. 2012 * Author: coissac */ #include #include #include "debug.h" char* int2bin(int64_t i,size_t bits) { static char str[65]; uint64_t u; if (bits > 64) return NULL; str[bits] = 0; // type punning because signed shift is implementation-defined u = *(unsigned *)&i; for(; bits--; u >>= 1) str[bits] = u & 1 ? '1' : '0'; return str; } sumaclust_v1.0.10/sumalibs/libutils/debug.h000644 000765 000024 00000000572 12551723264 022752 0ustar00celinemercierstaff000000 000000 /* * debug.h * * Created on: 4 sept. 2012 * Author: coissac */ #ifndef DEBUG_H_ #define DEBUG_H_ #ifdef DEBUG #undef DEBUG #endif #ifdef DEBUG_ON #define DEBUG(format,...) fprintf(stderr,"[%s:%d] : "format"\n",__FILE__,__LINE__,__VA_ARGS__) #else #define DEBUG(format,...) #endif #include char * int2bin(int64_t i,size_t bits); #endif /* DEBUG_H_ */ sumaclust_v1.0.10/sumalibs/libutils/Makefile000644 000765 000024 00000000472 12551723264 023152 0ustar00celinemercierstaff000000 000000 SOURCES = utilities.c \ debug.c SRCS=$(SOURCES) OBJECTS= $(patsubst %.c,%.o,$(SOURCES)) LIBFILE= libutils.a RANLIB=ranlib include ../global.mk all: $(LIBFILE) clean: rm -rf $(OBJECTS) $(LIBFILE) rm -f *.P rm -f *.a $(LIBFILE): $(OBJECTS) ar -cr $@ $? $(RANLIB) $@ sumaclust_v1.0.10/sumalibs/libutils/utilities.c000644 000765 000024 00000010472 12551723264 023672 0ustar00celinemercierstaff000000 000000 /** * FileName: utilities.c * Author: Tiayyba Riaz * Description: C file for miscellenious functions and macros * **/ #include "utilities.h" #include #include #include /* * Function Name: errorAbort(int errorCode, char* errorMsg, char* fileName, int lineNumber) * Description: Reports an error on standard error and aborts */ void errorAbort(int32_t errorCode, char* errorMsg, char* fileName, int32_t lineNumber) { fprintf(stderr,"Error %d in file %s line %d : %s\n", errorCode, fileName, lineNumber, errorMsg); abort(); } void *util_malloc(size_t chunksize, const char *filename, int32_t line) { void * chunk; chunk = calloc(1,chunksize); if (!chunk) errorAbort(MEM_ALLOC_ERROR,"Could not allocate memory.",filename,line); return chunk; } /* * Function Name: util_realloc(void *chunk, int32_t newsize, const char *filename, int32_t line) * Description: Overloading realloc funstion, changes the size of the memory object pointed to by chunk * to the size specified by newsize. If memory cannot be allocated, gives the error on stderr and aborts. */ void *util_realloc(void *chunk, size_t newsize, const char *filename, int32_t line) { void *newchunk; newchunk = realloc(chunk,newsize); if (!newchunk) { errorAbort(MEM_ALLOC_ERROR,"Could not allocate memory.",filename,line); } return newchunk; } /* * Function Name: util_free(void *chunk) * Description: Returns the memory specified by chunk back to operating syste. */ void util_free(void *chunk) { free(chunk); } BOOL util_findInArr(int32_t tempArr[], int seqNo, int32_t noOfSeqs) { int index; for(index = 0; index < noOfSeqs; index++) { if(tempArr[index] == seqNo) return TRUE; } return FALSE; } /** * * String handling utilities * **/ /* * Function Name: str_chopAtDelim(char *dest, char *src, char *delim, BOOL includeDelim) * Description: chops the string startig from source to the delimeter specified. */ char *str_chopAtDelim(char *dest, char *src, char *delim, BOOL includeDelim) { char *temp; int32_t len; /* returns a pointer to the first occurance of delim in src*/ temp = strstr(src, delim); if (temp == NULL) return NULL; if (includeDelim) { /* temp - src + strlen(delim) -> a string between src and delimeter including delimeter*/ len = temp - src + strlen(delim); strncpy(dest, src, len); } else { len = temp - src; strncpy(dest, src, temp - src); } dest[len] = '\0'; return dest; } /* * Function Name: str_sepNameValue(char *name, char *value, char *src, char *delim) * Description: . */ void str_sepNameValue(char *name, char *value, char *src, char *delim) { char *temp; temp = strstr(src, delim); if(temp != NULL) { strncpy(name, src, temp - src); strcpy(value, temp + strlen(delim)); } else { strcpy(name, src); strcpy(value, ""); } } /* * Function Name: str_removeSpaces(char *src) * Description: Removes the spaces from the start and end of the string. */ int str_isSpace (char ch) { switch (ch) { case ' ': case '\t': case '\n': return 1; } return 0; } void str_removeSpaces(char *src) { int32_t start = 0, end = strlen(src) - 1; int32_t index = 0; if (src == NULL || end < 0) return; while(str_isSpace(src[start]) && start < end) start++; while(str_isSpace(src[end]) && end > start) end--; if ( start == end && src[start] == ' ') { src[0] = '\0'; return; } if (start > 0) { while(start <= end) { src[index] = src[start]; index++; start++; } src[index] = '\0'; return; } src[end+1] = '\0'; } /* * Function Name: str_strrstr(char *src, char *delim) * Description: Searches the position of last occurence of string delim in src. */ char *str_strrstr(char *src, char *delim) { char *last, *next; next = strstr(src, delim); last = next; while(next != NULL) { last = next; next = strstr(last + 1, delim); } return last; } void* getA16Address(int size) { void* address; address = (void*) malloc(size); while ((((long long unsigned int) (address))%16) != 0) address++; return(address); } void** reallocA16Address(void** address, int size) { if (*(address) == NULL) *(address) = malloc(size); *(address) = realloc(address, size); while ((((long long unsigned int) (*(address)))%16) != 0) (*(address))++; return(address); } sumaclust_v1.0.10/sumalibs/libutils/utilities.h000644 000765 000024 00000002625 12551723264 023700 0ustar00celinemercierstaff000000 000000 /** * FileName: utilities.h * Author: Tiayyba Riaz * Description: Header file for miscellenious functions and macros * **/ #ifndef UTILITIES_H_ #define UTILITIES_H_ #include #include #include //static char *basecodes = "00100020000000000003000000"; //#define BASEIDX(ch) basecodes[ch - 'a'] - 48 #ifndef MAX #define MAX(x,y) (((x)>(y)) ? (x):(y)) #define MIN(x,y) (((x)<(y)) ? (x):(y)) #endif typedef char BOOL; #define TRUE (3==3) #define FALSE (!TRUE) #define ALILEN (0) #define MAXLEN (1) #define MINLEN (2) /* Error Codes */ #define FILE_OPENING_ERROR (1) #define MEM_ALLOC_ERROR (2) /* Prototypes */ void errorAbort(int32_t code, char* errorMsg, char* fileName, int32_t lineNumber); char *str_strrstr(char *src, char *delim); void str_removeSpaces(char *src); void str_sepNameValue(char *name, char *value, char *src, char *delim); char *str_chopAtDelim(char *dest, char *src, char *delim, BOOL includeDelim); void util_free(void *chunk); void *util_realloc(void *chunk, size_t newsize, const char *filename, int32_t line); void *util_malloc(size_t chunksize, const char *filename, int32_t line); BOOL util_findInArr(int32_t tempArr[], int seqNo, int32_t noOfSeqs); void* getA16Address(int size); void** reallocA16Address(void** address, int size); /* Macros */ #define ERRORABORT(code, msg) errorAbort((code), (msg), __FILE__, __LINE__) #endif /*UTILITIES_H_*/ sumaclust_v1.0.10/sumalibs/libsse/_sse.h000644 000765 000024 00000035215 12551723264 022251 0ustar00celinemercierstaff000000 000000 #ifndef _SSE_H_ #define _SSE_H_ #include #include #ifdef __SSE2__ #include #else typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__)); #endif /* __SSE2__ */ #ifndef MAX #define MAX(x,y) (((x)>(y)) ? (x):(y)) #define MIN(x,y) (((x)<(y)) ? (x):(y)) #endif #define ALIGN __attribute__((aligned(16))) typedef __m128i vUInt8; typedef __m128i vInt8; typedef __m128i vUInt16; typedef __m128i vInt16; typedef __m128i vUInt64; typedef union { __m128i i; int64_t s64[ 2]; int16_t s16[ 8]; int8_t s8 [16]; uint8_t u8 [16]; uint16_t u16[8 ]; uint32_t u32[4 ]; uint64_t u64[2 ]; } um128; typedef union { vUInt8 m; uint8_t c[16]; } uchar_v; typedef union { vUInt16 m; uint16_t c[8]; } ushort_v; typedef union { vUInt64 m; uint64_t c[2]; } uint64_v; #ifdef __SSE2__ static inline int8_t _s2_extract_epi8(__m128i r, const int p) { #define ACTIONP(r,x) return _mm_extract_epi16(r,x) & 0xFF #define ACTIONI(r,x) return _mm_extract_epi16(r,x) >> 8 switch (p) { case 0: ACTIONP(r,0); case 1: ACTIONI(r,0); case 2: ACTIONP(r,1); case 3: ACTIONI(r,1); case 4: ACTIONP(r,2); case 5: ACTIONI(r,2); case 6: ACTIONP(r,3); case 7: ACTIONI(r,3); case 8: ACTIONP(r,4); case 9: ACTIONI(r,4); case 10: ACTIONP(r,5); case 11: ACTIONI(r,5); case 12: ACTIONP(r,6); case 13: ACTIONI(r,6); case 14: ACTIONP(r,7); case 15: ACTIONI(r,7); } #undef ACTIONP #undef ACTIONI return 0; } static inline __m128i _s2_max_epi8(__m128i a, __m128i b) { __m128i mask = _mm_cmpgt_epi8( a, b ); a = _mm_and_si128 (a,mask ); b = _mm_andnot_si128(mask,b); return _mm_or_si128(a,b); } static inline __m128i _s2_min_epi8(__m128i a, __m128i b) { __m128i mask = _mm_cmplt_epi8( a, b ); a = _mm_and_si128 (a,mask ); b = _mm_andnot_si128(mask,b); return _mm_or_si128(a,b); } static inline __m128i _s2_insert_epi8(__m128i r, int b, const int p) { #define ACTIONP(r,x) return _mm_insert_epi16(r,(_mm_extract_epi16(r,x) & 0xFF00) | (b & 0x00FF),x) #define ACTIONI(r,x) return _mm_insert_epi16(r,(_mm_extract_epi16(r,x) & 0x00FF) | ((b << 8)& 0xFF00),x) switch (p) { case 0: ACTIONP(r,0); case 1: ACTIONI(r,0); case 2: ACTIONP(r,1); case 3: ACTIONI(r,1); case 4: ACTIONP(r,2); case 5: ACTIONI(r,2); case 6: ACTIONP(r,3); case 7: ACTIONI(r,3); case 8: ACTIONP(r,4); case 9: ACTIONI(r,4); case 10: ACTIONP(r,5); case 11: ACTIONI(r,5); case 12: ACTIONP(r,6); case 13: ACTIONI(r,6); case 14: ACTIONP(r,7); case 15: ACTIONI(r,7); } #undef ACTIONP #undef ACTIONI return _mm_setzero_si128(); } // Fill a SSE Register with 16 time the same 8bits integer value #define _MM_SET1_EPI8(x) _mm_set1_epi8(x) #define _MM_INSERT_EPI8(r,x,i) _s2_insert_epi8((r),(x),(i)) #define _MM_CMPEQ_EPI8(x,y) _mm_cmpeq_epi8((x),(y)) #define _MM_CMPGT_EPI8(x,y) _mm_cmpgt_epi8((x),(y)) #define _MM_CMPLT_EPI8(x,y) _mm_cmplt_epi8((x),(y)) #define _MM_MAX_EPI8(x,y) _s2_max_epi8((x),(y)) #define _MM_MIN_EPI8(x,y) _s2_min_epi8((x),(y)) #define _MM_ADD_EPI8(x,y) _mm_add_epi8((x),(y)) #define _MM_SUB_EPI8(x,y) _mm_sub_epi8((x),(y)) #define _MM_EXTRACT_EPI8(r,p) _s2_extract_epi8((r),(p)) #define _MM_MIN_EPU8(x,y) _mm_min_epu8((x),(y)) // Fill a SSE Register with 8 time the same 16bits integer value #define _MM_SET1_EPI16(x) _mm_set1_epi16(x) #define _MM_INSERT_EPI16(r,x,i) _mm_insert_epi16((r),(x),(i)) #define _MM_CMPEQ_EPI16(x,y) _mm_cmpeq_epi16((x),(y)) #define _MM_CMPGT_EPI16(x,y) _mm_cmpgt_epi16((x),(y)) #define _MM_CMPGT_EPU16(x,y) _mm_cmpgt_epu16((x),(y)) // n'existe pas ?? #define _MM_CMPLT_EPI16(x,y) _mm_cmplt_epi16((x),(y)) #define _MM_MAX_EPI16(x,y) _mm_max_epi16((x),(y)) #define _MM_MIN_EPI16(x,y) _mm_min_epi16((x),(y)) #define _MM_ADD_EPI16(x,y) _mm_add_epi16((x),(y)) #define _MM_SUB_EPI16(x,y) _mm_sub_epi16((x),(y)) #define _MM_EXTRACT_EPI16(r,p) _mm_extract_epi16((r),(p)) #define _MM_UNPACKLO_EPI8(a,b) _mm_unpacklo_epi8((a),(b)) #define _MM_UNPACKHI_EPI8(a,b) _mm_unpackhi_epi8((a),(b)) #define _MM_ADDS_EPU16(x,y) _mm_adds_epu16((x),(y)) // Multiplication #define _MM_MULLO_EPI16(x,y) _mm_mullo_epi16((x), (y)) #define _MM_SRLI_EPI64(r,x) _mm_srli_epi64((r),(x)) #define _MM_SLLI_EPI64(r,x) _mm_slli_epi64((r),(x)) // Set a SSE Register to 0 #define _MM_SETZERO_SI128() _mm_setzero_si128() #define _MM_AND_SI128(x,y) _mm_and_si128((x),(y)) #define _MM_ANDNOT_SI128(x,y) _mm_andnot_si128((x),(y)) #define _MM_OR_SI128(x,y) _mm_or_si128((x),(y)) #define _MM_XOR_SI128(x,y) _mm_xor_si128((x),(y)) #define _MM_SLLI_SI128(r,s) _mm_slli_si128((r),(s)) #define _MM_SRLI_SI128(r,s) _mm_srli_si128((r),(s)) // Load a SSE register from an unaligned address #define _MM_LOADU_SI128(x) _mm_loadu_si128(x) // Load a SSE register from an aligned address (/!\ not defined when SSE not available) #define _MM_LOAD_SI128(x) _mm_load_si128(x) // #define _MM_UNPACKLO_EPI8(x,y) _mm_unpacklo_epi8((x),(y)) #else /* __SSE2__ Not defined */ static inline __m128i _em_set1_epi8(int x) { um128 a; x&=0xFF; a.s8[0]=x; a.s8[1]=x; a.u16[1]=a.u16[0]; a.u32[1]=a.u32[0]; a.u64[1]=a.u64[0]; return a.i; } static inline __m128i _em_insert_epi8(__m128i r, int x, const int i) { um128 a; a.i=r; a.s8[i]=x & 0xFF; return a.i; } static inline __m128i _em_cmpeq_epi8(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.s8[z]=(x.s8[z]==y.s8[z]) ? 0xFF:0 R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); R(10); R(11); R(12); R(13); R(14); R(15); #undef R return r.i; } static inline __m128i _em_cmpgt_epi8(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.s8[z]=(x.s8[z]>y.s8[z]) ? 0xFF:0 R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); R(10); R(11); R(12); R(13); R(14); R(15); #undef R return r.i; } static inline __m128i _em_cmplt_epi8(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.s8[z]=(x.s8[z]y.s16[z]) ? 0xFFFF:0 R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); #undef R return r.i; } static inline __m128i _em_cmplt_epi16(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.s16[z]=(x.s16[z]>=b; x.s64[1]>>=b; return x.i; } static inline __m128i _em_slli_epi64(__m128i a, int b) { um128 x; x.i=a; x.s64[0]<<=b; x.s64[1]<<=b; return x.i; } static inline __m128i _em_setzero_si128() { um128 x; x.s64[0]=x.s64[1]=0; return x.i; } static inline __m128i _em_and_si128(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.u64[z]=x.u64[z] & y.u64[z] R(0); R(1); #undef R return r.i; } static inline __m128i _em_andnot_si128(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.u64[z]=(~x.u64[z]) & y.u64[z] R(0); R(1); #undef R return r.i; } static inline __m128i _em_or_si128(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.u64[z]=x.u64[z] | y.u64[z] R(0); R(1); #undef R return r.i; } static inline __m128i _em_xor_si128(__m128i a, __m128i b) { um128 x; um128 y; um128 r; x.i=a; y.i=b; #define R(z) r.u64[z]=x.u64[z] ^ y.u64[z] R(0); R(1); #undef R return r.i; } static inline __m128i _em_slli_si128(__m128i a, int b) { um128 x; x.i=a; #define R(z) x.u8[z]=(z>=b) ? x.u8[z-b]:0 R(15); R(14); R(13); R(12); R(11); R(10); R(9); R(8); R(7); R(6); R(5); R(4); R(3); R(2); R(1); R(0); #undef R return x.i; } static inline __m128i _em_srli_si128(__m128i a, int b) { um128 x; x.i=a; #define R(z) x.u8[z]=((b+z) > 15) ? 0:x.u8[z+b] R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); R(10); R(11); R(12); R(13); R(14); R(15); #undef R return x.i; } inline static __m128i _em_loadu_si128(__m128i const *P) { um128 tmp; um128 *pp=(um128*)P; tmp.u8[0]=(*pp).u8[0]; tmp.u8[1]=(*pp).u8[1]; tmp.u8[2]=(*pp).u8[2]; tmp.u8[3]=(*pp).u8[3]; tmp.u8[4]=(*pp).u8[4]; tmp.u8[5]=(*pp).u8[5]; tmp.u8[6]=(*pp).u8[6]; tmp.u8[7]=(*pp).u8[7]; tmp.u8[8]=(*pp).u8[8]; tmp.u8[9]=(*pp).u8[9]; tmp.u8[10]=(*pp).u8[10]; tmp.u8[11]=(*pp).u8[11]; tmp.u8[12]=(*pp).u8[12]; tmp.u8[13]=(*pp).u8[13]; tmp.u8[14]=(*pp).u8[14]; tmp.u8[15]=(*pp).u8[15]; return tmp.i; } #define _MM_SET1_EPI8(x) _em_set1_epi8(x) #define _MM_INSERT_EPI8(r,x,i) _em_insert_epi8((r),(x),(i)) #define _MM_CMPEQ_EPI8(x,y) _em_cmpeq_epi8((x),(y)) #define _MM_CMPGT_EPI8(x,y) _em_cmpgt_epi8((x),(y)) #define _MM_CMPLT_EPI8(x,y) _em_cmplt_epi8((x),(y)) #define _MM_MAX_EPI8(x,y) _em_max_epi8((x),(y)) #define _MM_MIN_EPI8(x,y) _em_min_epi8((x),(y)) #define _MM_ADD_EPI8(x,y) _em_add_epi8((x),(y)) #define _MM_SUB_EPI8(x,y) _em_sub_epi8((x),(y)) #define _MM_EXTRACT_EPI8(r,p) _em_extract_epi8((r),(p)) #define _MM_MIN_EPU8(x,y) _em_min_epu8((x),(y)) #define _MM_SET1_EPI16(x) _em_set1_epi16(x) #define _MM_INSERT_EPI16(r,x,i) _em_insert_epi16((r),(x),(i)) #define _MM_CMPEQ_EPI16(x,y) _em_cmpeq_epi16((x),(y)) #define _MM_CMPGT_EPI16(x,y) _em_cmpgt_epi16((x),(y)) #define _MM_CMPLT_EPI16(x,y) _em_cmplt_epi16((x),(y)) #define _MM_MAX_EPI16(x,y) _em_max_epi16((x),(y)) #define _MM_MIN_EPI16(x,y) _em_min_epi16((x),(y)) #define _MM_ADD_EPI16(x,y) _em_add_epi16((x),(y)) #define _MM_SUB_EPI16(x,y) _em_sub_epi16((x),(y)) #define _MM_EXTRACT_EPI16(r,p) _em_extract_epi16((r),(p)) #define _MM_UNPACKLO_EPI8(a,b) _em_unpacklo_epi8((a),(b)) #define _MM_UNPACKHI_EPI8(a,b) _em_unpackhi_epi8((a),(b)) #define _MM_ADDS_EPU16(x,y) _em_adds_epu16((x),(y)) #define _MM_SRLI_EPI64(r,x) _em_srli_epi64((r),(x)) #define _MM_SLLI_EPI64(r,x) _em_slli_epi64((r),(x)) #define _MM_SETZERO_SI128() _em_setzero_si128() #define _MM_AND_SI128(x,y) _em_and_si128((x),(y)) #define _MM_ANDNOT_SI128(x,y) _em_andnot_si128((x),(y)) #define _MM_OR_SI128(x,y) _em_or_si128((x),(y)) #define _MM_XOR_SI128(x,y) _em_xor_si128((x),(y)) #define _MM_SLLI_SI128(r,s) _em_slli_si128((r),(s)) #define _MM_SRLI_SI128(r,s) _em_srli_si128((r),(s)) #define _MM_LOADU_SI128(x) _em_loadu_si128(x) #define _MM_LOAD_SI128(x) _em_loadu_si128(x) #endif /* __SSE2__ */ #define _MM_NOT_SI128(x) _MM_XOR_SI128((x),(_MM_SET1_EPI8(0xFFFF))) #endif sumaclust_v1.0.10/sumalibs/liblcs/_lcs.ext.1.c000644 000765 000024 00000005520 12551723264 023154 0ustar00celinemercierstaff000000 000000 #include "_lcs.h" #include #include #include #include // Allocate a band allowing to align sequences of length : 'length' column_t* allocateColumn(int length,column_t *column, bool mode8bits) { int size; bool newc = false; // The band length should be equal to the length // of the sequence + 7 for taking into account its // shape size = (length+1) * ((mode8bits) ? sizeof(int8_t):sizeof(int16_t)); // If the pointer to the old column is NULL we allocate // a new column if (column==NULL) { column = malloc(sizeof(column_t)); if (!column) return NULL; column->size = 0; column->data.shrt=NULL; column->score.shrt=NULL; newc = true; } // Otherwise we check if its size is sufficient // or if it should be extended if (size > column->size) { int16_t *old = column->data.shrt; int16_t *olds= column->score.shrt; column->data.shrt = malloc(size); column->score.shrt= malloc(size); if (column->data.shrt==NULL || column->score.shrt==NULL) { fprintf(stderr,"Allocation Error on column for a size of %d\n" , size); column->data.shrt = old; column->score.shrt= olds; if (newc) { free(column); column=NULL; return NULL; } return NULL; } else column->size = size; } return column; } void freeColumn(column_p column) { if (column) { if (column->data.shrt) free(column->data.shrt); if (column->score.shrt) free(column->score.shrt); free(column); } } int fastLCSScore(const char* seq1, const char* seq2,column_pp column,int32_t* lpath) { return fastLCSScore16(seq1,seq2,column,lpath); } int simpleLCS(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath) { int lseq1,lseq2; // length of the both sequences int lcs; int itmp; // tmp variables for swap const char* stmp; // int32_t *score; int32_t *path; column_t *column; int32_t i,j; int32_t sl,su,sd; int32_t pl,pu,pd; // Made seq1 the longest sequences lseq1=strlen(seq1); lseq2=strlen(seq2); if (lseq1 < lseq2) { itmp=lseq1; lseq1=lseq2; lseq2=itmp; stmp=seq1; seq1=seq2; seq2=stmp; } lseq1++; lseq2++; // a band sized to the smallest sequence is allocated if (ppcolumn) column = *ppcolumn; else column=NULL; column = allocateColumn(lseq1*2,column,0); score = (int32_t*) column->score.shrt; path = (int32_t*) column->data.shrt; memset(score,0,lseq1 * sizeof(int32_t)); for (j=0; j < lseq1; j++) path[j]=j; for (i=1; i< lseq2; i++) { sl=0; pl=i; for (j=1; j < lseq1; j++) { sd=score[j-1] + (seq2[i-1]==seq1[j-1] ? 1:0); pd=path[j-1] + 1; su=score[j]; pu=path[j] + 1; score[j-1]=sl; if (su > sl) sl=su, pl=pu; if (sd > sl) sl=sd, pl=pd; } } lcs = sl; if(lpath) *lpath=pl; if (ppcolumn) *ppcolumn=column; else freeColumn(column); return lcs; } sumaclust_v1.0.10/sumalibs/liblcs/_lcs.ext.2.c000644 000765 000024 00000001401 12551723264 023147 0ustar00celinemercierstaff000000 000000 #include "_lcs.h" #include #include #include #include #define VSIZE (8) #define VTYPE vInt16 #define STYPE int16_t #define CMENB shrt #define VMODE false #define FASTLCSSCORE fastLCSScore16 #define INSERT_REG _MM_INSERT_EPI16 #define EXTRACT_REG _MM_EXTRACT_EPI16 #define EQUAL_REG _MM_CMPEQ_EPI16 #define GREATER_REG _MM_CMPGT_EPI16 #define SMALLER_REG _MM_CMPLT_EPI16 #define ADD_REG _MM_ADD_EPI16 #define SUB_REG _MM_SUB_EPI16 #define AND_REG _MM_AND_SI128 #define ANDNOT_REG _MM_ANDNOT_SI128 #define OR_REG _MM_OR_SI128 #define SET_CONST _MM_SET1_EPI16 #define GET_MAX _MM_MAX_EPI16 #define GET_MIN _MM_MIN_EPI16 #define MIN_SCORE INT16_MIN #define MAX_SCORE 32000 #include "_lcs_fast.h" sumaclust_v1.0.10/sumalibs/liblcs/_lcs.ext.3.c000644 000765 000024 00000001361 12551723264 023155 0ustar00celinemercierstaff000000 000000 #include "_lcs.h" #include #include #include #include #define VSIZE (16) #define VTYPE vInt8 #define STYPE int8_t #define CMENB byte #define VMODE true #define FASTLCSSCORE fastLCSScore8 #define INSERT_REG _MM_INSERT_EPI8 #define EXTRACT_REG _MM_EXTRACT_EPI8 #define EQUAL_REG _MM_CMPEQ_EPI8 #define GREATER_REG _MM_CMPGT_EPI8 #define SMALLER_REG _MM_CMPLT_EPI8 #define ADD_REG _MM_ADD_EPI8 #define SUB_REG _MM_SUB_EPI8 #define AND_REG _MM_AND_SI128 #define ANDNOT_REG _MM_ANDNOT_SI128 #define OR_REG _MM_OR_SI128 #define SET_CONST _MM_SET1_EPI8 #define GET_MAX _MM_MAX_EPI8 #define GET_MIN _MM_MIN_EPI8 #define MIN_SCORE INT8_MIN #define MAX_SCORE 127 #include "_lcs_fast.h" sumaclust_v1.0.10/sumalibs/liblcs/_lcs.h000644 000765 000024 00000001345 12551723264 022224 0ustar00celinemercierstaff000000 000000 #include "../libsse/_sse.h" #define bool char #define false (1==0) #define true (1==1) typedef struct { int16_t size; union { int16_t *shrt; int8_t *byte; } data; union { int16_t *shrt; int8_t *byte; } score; } column_t, **column_pp, *column_p; column_p allocateColumn(int length,column_t *column, bool mode8bits); void freeColumn(column_p column); int fastLCSScore16(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath); int fastLCSScore8(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath); int simpleLCS(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath); int fastLCSScore(const char* seq1, const char* seq2,column_pp column,int32_t* lpath); sumaclust_v1.0.10/sumalibs/liblcs/_lcs_fast.h000644 000765 000024 00000032736 12551723264 023251 0ustar00celinemercierstaff000000 000000 /* * Print a SSE register for debug purpose */ #ifdef __SSE2__ static void printreg(VTYPE r) { STYPE a0,a1,a2,a3,a4,a5,a6,a7; #if VMODE STYPE a8,a9,a10,a11,a12,a13,a14,a15; #endif a0= EXTRACT_REG(r,0); a1= EXTRACT_REG(r,1); a2= EXTRACT_REG(r,2); a3= EXTRACT_REG(r,3); a4= EXTRACT_REG(r,4); a5= EXTRACT_REG(r,5); a6= EXTRACT_REG(r,6); a7= EXTRACT_REG(r,7); #if VMODE a8= EXTRACT_REG(r,8); a9= EXTRACT_REG(r,9); a10= EXTRACT_REG(r,10); a11= EXTRACT_REG(r,11); a12= EXTRACT_REG(r,12); a13= EXTRACT_REG(r,13); a14= EXTRACT_REG(r,14); a15= EXTRACT_REG(r,15); #endif printf( "a00 :-> %7d %7d %7d %7d " " %7d %7d %7d %7d " #if VMODE "%7d %7d %7d %7d " " %7d %7d %7d %7d " #endif "\n" , a0,a1,a2,a3,a4,a5,a6,a7 #if VMODE , a8,a9,a10,a11,a12,a13,a14,a15 #endif ); } /* * set position p of a SSE register with the value v */ static inline VTYPE insert_reg(VTYPE r, STYPE v, int p) { switch (p) { case 0: return INSERT_REG(r,v,0); case 1: return INSERT_REG(r,v,1); case 2: return INSERT_REG(r,v,2); case 3: return INSERT_REG(r,v,3); case 4: return INSERT_REG(r,v,4); case 5: return INSERT_REG(r,v,5); case 6: return INSERT_REG(r,v,6); case 7: return INSERT_REG(r,v,7); #if VMODE case 8: return INSERT_REG(r,v,8); case 9: return INSERT_REG(r,v,9); case 10: return INSERT_REG(r,v,10); case 11: return INSERT_REG(r,v,11); case 12: return INSERT_REG(r,v,12); case 13: return INSERT_REG(r,v,13); case 14: return INSERT_REG(r,v,14); case 15: return INSERT_REG(r,v,15); #endif } return _MM_SETZERO_SI128(); } static inline STYPE extract_reg(VTYPE r, int p) { switch (p) { case 0: return EXTRACT_REG(r,0); case 1: return EXTRACT_REG(r,1); case 2: return EXTRACT_REG(r,2); case 3: return EXTRACT_REG(r,3); case 4: return EXTRACT_REG(r,4); case 5: return EXTRACT_REG(r,5); case 6: return EXTRACT_REG(r,6); case 7: return EXTRACT_REG(r,7); #if VMODE case 8: return EXTRACT_REG(r,8); case 9: return EXTRACT_REG(r,9); case 10: return EXTRACT_REG(r,10); case 11: return EXTRACT_REG(r,11); case 12: return EXTRACT_REG(r,12); case 13: return EXTRACT_REG(r,13); case 14: return EXTRACT_REG(r,14); case 15: return EXTRACT_REG(r,15); #endif } return 0; } #define GET_H_SYMBOLE(s,p) ((p && p < lseq1) ? (s)[(p)-1]:255) #define GET_V_SYMBOLE(s,p) ((p && p < lseq2) ? (s)[(p)-1]:0) #define LSHIFT_SCORE(r) { r = _MM_SLLI_SI128((r),sizeof(STYPE)); } #define SET_H_SYMBOLE(r,p,s) { r = insert_reg((r),(STYPE)GET_H_SYMBOLE(seq1,(s)),(p)); } #define PUSH_V_SYMBOLE(r,s) { r = insert_reg(_MM_SLLI_SI128((r),sizeof(STYPE)),(STYPE)GET_V_SYMBOLE(seq2,(s)),0); } #define EQUAL(f1,f2) _MM_AND_SI128(EQUAL_REG((f1),(f2)),SET_CONST(1)) int FASTLCSSCORE(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath) { int lseq1,lseq2; // length of the both sequences int itmp; // tmp variables for swap const char* stmp; // int nbands; // Number of bands of width eight in the score matrix int lastband; // width of the last band // Register for scanning the score matrix VTYPE minus1; VTYPE minus2; VTYPE current; VTYPE left; VTYPE top; VTYPE diag; VTYPE sminus1; VTYPE sminus2; VTYPE scurrent; VTYPE sleft; VTYPE stop; VTYPE sdiag; VTYPE way; VTYPE onevect; VTYPE maxvect; VTYPE fhseq; // The fragment of the horizontal sequence // to consider for aligment VTYPE fvseq; // The fragment of the horizontal sequence // to consider for aligment VTYPE match; int band; int line; int limit; int lcs; int h; int i; column_t *column; // Made seq1 the longest sequences lseq1=strlen(seq1); lseq2=strlen(seq2); if (lseq1 < 10 || lseq2 < 10) return simpleLCS(seq1,seq2,ppcolumn,lpath); if (lseq1 < lseq2) { itmp=lseq1; lseq1=lseq2; lseq2=itmp; stmp=seq1; seq1=seq2; seq2=stmp; } // we add one to both lengths for taking into // account the extra line and column in the score // matrix lseq1++; lseq2++; // a band sized to the smallest sequence is allocated if (ppcolumn) column = *ppcolumn; else column=NULL; column = allocateColumn(lseq2,column,VMODE); // Check memory allocation if (column == NULL) return -1; for (i=0; idata.CMENB[i]=MIN_SCORE; column->score.CMENB[i]=-1; } nbands = lseq1 / VSIZE; // You have VSIZE element in one SSE register // Alignment will be realized in nbands lastband = lseq1 - (nbands * VSIZE); // plus one of width lastband except if // lastband==0 if (lastband) nbands++; else lastband=VSIZE; lastband--; // printf("seq1 : %s seq2 : %s\n",seq1,seq2); minus2 = SET_CONST(MIN_SCORE); minus1 = _MM_SETZERO_SI128(); sminus1= _MM_SETZERO_SI128(); sminus2= _MM_SETZERO_SI128(); onevect= SET_CONST(1); maxvect= SET_CONST(MAX_SCORE); h=0; fhseq = _MM_SETZERO_SI128(); fvseq = _MM_SETZERO_SI128(); // // Beginning of the first band // for (line = 0; line < VSIZE; line++,h++) // avant VSIZE - 1 { // printf("line= %4d h= %4d\n",line,h); SET_H_SYMBOLE(fhseq,line,h) PUSH_V_SYMBOLE(fvseq,line) minus2 = insert_reg(minus2,0,h); minus1 = insert_reg(minus1,MIN_SCORE,line); // 0 avant match = EQUAL(fhseq,fvseq); if (lpath) { sminus2 = insert_reg(sminus2,line-1,line); // Je ne suis pas certain de l'initialisation sminus1 = insert_reg(sminus1,0,line); } // printreg(fvseq); // printreg(fhseq); // printreg(match); // printf("================================\n"); current = minus1; // The best score is the upper one // It cannot be the best as set to MIN_SCORE left = minus1; // printf("Vert = "); printreg(current); LSHIFT_SCORE(minus1) // I shift minus1 so now I'll compare with the left position minus1=insert_reg(minus1,(column)->data.CMENB[line],0); top=minus1; if (lpath) { sleft=sminus1; // I store the path length corresponding to the upper path LSHIFT_SCORE(sminus1) // I shift to prepare the score coming from the left side sminus1=insert_reg(sminus1,(column)->score.CMENB[line],0); stop=sminus1; sdiag=sminus2; } // printf("Horz = "); printreg(minus1); current = GET_MAX(current,minus1); // Look for the best between upper and left // printf("BstHV= "); printreg(current); // // printf("Diag = "); printreg(ADD_REG(minus2,match)); diag=minus2; // minus2 = ; // Minus2 contains the diagonal score, so I add the match reward // Diag score are setup to 0 so this one will win on the first iteration current = GET_MAX(current,ADD_REG(minus2,match)); if (lpath) { // printf("\n"); // printf("current: "); // printreg(current); // printf("current: "); // printreg(SUB_REG(current,match)); // printf("diag : "); // printreg(diag); // printf("left : "); // printreg(left); // printf("top : "); // printreg(top); way = EQUAL_REG(SUB_REG(current,match),diag); scurrent= OR_REG(AND_REG(way,sdiag), ANDNOT_REG(way,maxvect)); // printf("sdiag : "); // printreg(scurrent); way = EQUAL_REG(current,left); scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,sleft), ANDNOT_REG(way,maxvect))); // printf("sleft : "); // printreg(scurrent); way = EQUAL_REG(current,top); scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,stop), ANDNOT_REG(way,maxvect))); // printf("stop : "); // printreg(scurrent); scurrent= ADD_REG(scurrent,onevect); sminus2=sminus1; sminus1=scurrent; } // printf("line %d :Best = ",line); printreg(current); // // printf("================================\n"); minus2=minus1; minus1=current; // printf("min2 = "); printreg(minus2); // printf("min1 = "); printreg(minus1); // printf("================================\n"); // printf("\n"); // printf("sdiag : "); // printreg(sminus2); // printf("scur : "); // printreg(scurrent); // printf("current: "); // printreg(current); // printf("%8s\n",seq1); // printf("%8s\n",seq2); // printf("================================\n"); } ///// <<<<<<<<------- Fin du debut de la premiere bande // printf("================================\n"); (column)->data.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(current,VSIZE-1); if (lpath) (column)->score.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(scurrent,VSIZE-1); for (band=0; band < nbands; band++) { // SET_H_SYMBOLE(fhseq,line,h) // minus2 = insert_reg(minus2,0,line); // minus1 = insert_reg(minus1,MIN_SCORE,line); // 0 avant // h++; for (; line < lseq2; line++) { // printf("Je tourne avec line= %d \n",line); PUSH_V_SYMBOLE(fvseq,line) match = EQUAL(fhseq,fvseq); // printreg(fvseq); // printreg(fhseq); // printreg(match); // printf("================================\n"); current = minus1; left = minus1; // Store the last current score in extra column (column)->data.CMENB[line-VSIZE]=EXTRACT_REG(current,VSIZE-1); LSHIFT_SCORE(minus1) minus1=insert_reg(minus1,(column)->data.CMENB[line],0); top = minus1; // printf("Vert = "); printreg(current); if (lpath) { sleft= sminus1; (column)->score.CMENB[line-VSIZE]=EXTRACT_REG(scurrent,VSIZE-1); LSHIFT_SCORE(sminus1) sminus1=insert_reg(sminus1,(column)->score.CMENB[line],0); stop=sminus1; sdiag=sminus2; } // printf("line = %d --> get = %d\n",line,(column)->data.CMENB[line]); // printf("Horz = "); printreg(minus1); current = GET_MAX(current,minus1); diag=minus2; current = GET_MAX(current,ADD_REG(minus2,match)); if (lpath) { // printf("\n"); // printf("current: "); // printreg(current); // printf("current: "); // printreg(SUB_REG(current,match)); // printf("diag : "); // printreg(diag); // printf("left : "); // printreg(left); // printf("top : "); // printreg(top); way = EQUAL_REG(SUB_REG(current,match),diag); scurrent= OR_REG(AND_REG(way,sdiag), ANDNOT_REG(way,maxvect)); // printf("sdiag : "); // printreg(scurrent); way = EQUAL_REG(current,left); scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,sleft), ANDNOT_REG(way,maxvect))); // printf("sleft : "); // printreg(scurrent); way = EQUAL_REG(current,top); scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,stop), ANDNOT_REG(way,maxvect))); // printf("stop : "); // printreg(scurrent); scurrent= ADD_REG(scurrent,onevect); sminus2=sminus1; sminus1=scurrent; } minus2=minus1; minus1=current; // printf("\n"); // printf("sdiag : "); // printreg(sminus2); // printf("scur : "); // printreg(scurrent); // printf("current: "); // printreg(current); // printf("%8s\n",seq1); // printf("%8s\n",seq2); } // printf("================================\n"); // end of the band and beginnig of the next one limit=(band==(nbands-1)) ? lastband:VSIZE; for (line = 0; line < limit; line++,h++) { // printf("Je fini avec line= %d \n",line); SET_H_SYMBOLE(fhseq,line,h) PUSH_V_SYMBOLE(fvseq,line) minus2 = insert_reg(minus2,MIN_SCORE,line); minus1 = insert_reg(minus1,MIN_SCORE,line); current = minus1; left=minus1; match = EQUAL(fhseq,fvseq); if (lpath) { sminus2 = insert_reg(sminus2,lseq2-VSIZE+line,line); sminus1 = insert_reg(sminus1,h,line); sleft= sminus1; } // printf("\n"); // printf("fhseq = "); printreg(fhseq); // printf("fvseq = "); printreg(fvseq); // printf("----------------------------------------------------------------\n"); // printf("match = "); printreg(match); (column)->data.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(current,VSIZE-1); LSHIFT_SCORE(minus1) minus1=insert_reg(minus1,(column)->data.CMENB[line],0); top=minus1; current = GET_MAX(current,minus1); if (lpath) { (column)->score.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(scurrent,VSIZE-1); LSHIFT_SCORE(sminus1) sminus1=insert_reg(sminus1,(column)->score.CMENB[line],0); stop=sminus1; sdiag=sminus2; way = EQUAL_REG(current,minus1); scurrent= OR_REG(AND_REG(way,sminus1), ANDNOT_REG(way,scurrent)); } diag=minus2; current = GET_MAX(current,ADD_REG(minus2,match)); if (lpath) { way = EQUAL_REG(SUB_REG(current,match),diag); scurrent= OR_REG(AND_REG(way,sdiag), ANDNOT_REG(way,maxvect)); way = EQUAL_REG(current,left); scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,sleft), ANDNOT_REG(way,maxvect))); way = EQUAL_REG(current,top); scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,stop), ANDNOT_REG(way,maxvect))); scurrent= ADD_REG(scurrent,onevect); sminus2=sminus1; sminus1=scurrent; } // printf("currt = "); printreg(current); minus2=minus1; minus1=current; // printf("\n"); // printf("sdiag : "); // printreg(sminus2); // printf("scur : "); // printreg(scurrent); // printf("current: "); // printreg(current); // printf("%8s\n",seq1); // printf("%8s\n",seq2); // printf("Je stocke line= %d la valeur %d\n",lseq2-VSIZE+line,(column)->data.CMENB[lseq2-VSIZE+line]); } } // printf("\n"); // printf("line = %d, h= %d, lastband = %d\n",line,h,lastband); // printf("currt = "); printreg(current); lcs = extract_reg(current,lastband); if(lpath) *lpath= extract_reg(scurrent,lastband); // printf("lastband = %d (%d) lcs = %d\n",lastband,lseq2,lcs); if (ppcolumn) *ppcolumn=column; else freeColumn(column); return lcs; } #else int FASTLCSSCORE(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath) { return simpleLCS(seq1,seq2,ppcolumn,lpath); } #endif /* __SSE2__ */ sumaclust_v1.0.10/sumalibs/liblcs/banded_LCS_alignment.c000644 000765 000024 00000010750 12551723264 025253 0ustar00celinemercierstaff000000 000000 /* * banded_LCS_alignment.c * * Created on: 7 nov. 2012 * Author: merciece */ #include #include #include #include "../libutils/utilities.h" typedef struct { int score; int l_path; }infos; int calculateScore(char nuc1, char nuc2) { return(nuc1 == nuc2); } infos** banded_align(char *seq1, char *seq2, int l1, int l2, int bandLengthRight, int bandLengthLeft) { int i, j; //int c; //double id; int start, end; int diag_score, delete, insert, mismatch; int l_path, l_path_i, l_path_d; int bestScore; int mismatch_margin; int stop; int diag_index; infos **matrix; l1++; l2++; mismatch_margin = bandLengthLeft; // the biggest one diag_index = l1-l2; // diagonal index stop=0; //fprintf(stderr,"\nseq1 = %s, seq2=%s, bandLengthR = %d, bandLengthL = %d", seq1, seq2, bandLengthRight, bandLengthLeft); // Matrix initialization~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ matrix = (infos**) malloc(l1 * sizeof(infos*)); for (i = 0; i < l1; i++) matrix[i] = (infos*) malloc(l2 * sizeof(infos)); for (i = 0; i < l1; i++) for (j = 0; j < l2; j++) { matrix[i][j].score = 0; matrix[i][j].l_path = 0; } for (i = 0; i < l1; i++) matrix[i][0].l_path = i; for (j = 0; j < l2; j++) matrix[0][j].l_path = j; // Matrix initialized~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for (i = 1; i < l1; i++) { start = i - bandLengthLeft; if (start < 1) start = 1; end = i+bandLengthRight+1; if (end > l2) end = l2; for (j = start; j < end; j++) { delete = matrix[i-1][j].score; l_path_d = matrix[i-1][j].l_path + 1; insert = matrix[i][j-1].score; l_path_i = matrix[i][j-1].l_path + 1; mismatch = 0; diag_score = calculateScore(seq1[i-1], seq2[j-1]); bestScore = matrix[i-1][j-1].score + diag_score; l_path = matrix[i-1][j-1].l_path + 1; if (diag_score == 0) // mismatch mismatch = 1; if ((insert > bestScore) || ((insert == bestScore) && (l_path_i < l_path))) { bestScore = matrix[i][j-1].score; l_path = l_path_i; mismatch = 0; } if ((delete > bestScore) || ((delete == bestScore) && (l_path_d < l_path))) { bestScore = delete; l_path = l_path_d; mismatch = 0; } /*if (((i-j) - diag_index == 0) && (mismatch == 1)) { //fprintf(stderr, "\nR = %d, L = %d\n", bandLengthRight, bandLengthLeft); if (bandLengthRight+bandLengthLeft == 0) { stop = 1; //fprintf(stderr, "\nBREAKING LOOPS\n"); break; } if (bandLengthRight != 0) bandLengthRight = bandLengthRight - 1; if (bandLengthLeft != 0) bandLengthLeft = bandLengthLeft - 1; }*/ (matrix[i][j]).score = bestScore; (matrix[i][j]).l_path = l_path; } //if ((bandLengthRight + bandLengthLeft == 0) && ((matrix[i][j].l_path - matrix[i][j].score) > mismatch_margin)) if (stop==1) break; } return(matrix); } void calculateBandLength(int l1, int l2, double threshold, int* bandLengthRight, int* bandLengthLeft) { (*bandLengthLeft) = round(-l1 * threshold + l1); (*bandLengthRight) = round(-l1 * threshold + l2); // fprintf(stderr,"\nR=%d, L=%d", (*bandLengthRight), (*bandLengthLeft)); } double calculateId(infos** matrix, int len1, int len2) { double id; int l_ali; int l_lcs; l_lcs = matrix[len1][len2].score; l_ali = matrix[len1][len2].l_path; if (l_lcs == 0) id = 0.0; else id = (double) l_lcs / (double) l_ali; //fprintf(stderr, "\n%d, %d\n", l_lcs, l_ali); return(id); } double banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, double threshold, BOOL n, int ref, BOOL lcsmode, int16_t* address) { double id; int bandLengthRight, bandLengthLeft; int i,j; char* s1; char* s2; s1 = (char*) malloc(l1*sizeof(char)+1); s2 = (char*) malloc(l2*sizeof(char)+1); for (i=l1-1, j=0; i>=0, j #include #include #include #include "../libutils/utilities.h" #include "../libsse/_sse.h" /*static void printreg(__m128i r) { int16_t a0,a1,a2,a3,a4,a5,a6,a7; a0= _MM_EXTRACT_EPI16(r,0); a1= _MM_EXTRACT_EPI16(r,1); a2= _MM_EXTRACT_EPI16(r,2); a3= _MM_EXTRACT_EPI16(r,3); a4= _MM_EXTRACT_EPI16(r,4); a5= _MM_EXTRACT_EPI16(r,5); a6= _MM_EXTRACT_EPI16(r,6); a7= _MM_EXTRACT_EPI16(r,7); fprintf(stderr, "a00 :-> %7d %7d %7d %7d " " %7d %7d %7d %7d " "\n" , a0,a1,a2,a3,a4,a5,a6,a7 ); } */ static inline int extract_reg(__m128i r, int p) { switch (p) { case 0: return(_MM_EXTRACT_EPI16(r,0)); case 1: return(_MM_EXTRACT_EPI16(r,1)); case 2: return(_MM_EXTRACT_EPI16(r,2)); case 3: return(_MM_EXTRACT_EPI16(r,3)); case 4: return(_MM_EXTRACT_EPI16(r,4)); case 5: return(_MM_EXTRACT_EPI16(r,5)); case 6: return(_MM_EXTRACT_EPI16(r,6)); case 7: return(_MM_EXTRACT_EPI16(r,7)); } return(0); } void sse_banded_align_lcs_and_ali_len(int16_t* seq1, int16_t* seq2, int l1, int l2, int bandLengthLeft, int bandLengthTotal, int16_t* address, double* lcs_length, int* ali_length) { register int j; int k1, k2; int max, diff; int l_reg, l_loc; int line; int numberOfRegistersPerLine; int numberOfRegistersFor3Lines; BOOL even_line; BOOL odd_line; BOOL even_BLL; BOOL odd_BLL; um128* SSEregisters; um128* p_diag; um128* p_gap1; um128* p_gap2; um128* p_diag_j; um128* p_gap1_j; um128* p_gap2_j; um128 current; um128* l_ali_SSEregisters; um128* p_l_ali_diag; um128* p_l_ali_gap1; um128* p_l_ali_gap2; um128* p_l_ali_diag_j; um128* p_l_ali_gap1_j; um128* p_l_ali_gap2_j; um128 l_ali_current; um128 nucs1; um128 nucs2; um128 scores; um128 boolean_reg; // Initialisations odd_BLL = bandLengthLeft & 1; even_BLL = !odd_BLL; max = INT16_MAX - l1; numberOfRegistersPerLine = bandLengthTotal / 8; numberOfRegistersFor3Lines = 3 * numberOfRegistersPerLine; SSEregisters = (um128*) calloc(numberOfRegistersFor3Lines * 2, sizeof(um128)); l_ali_SSEregisters = SSEregisters + numberOfRegistersFor3Lines; // preparer registres SSE for (j=0; ji, scores.i); // Computing alignment length l_ali_current.i = p_l_ali_diag_j->i; boolean_reg.i = _MM_CMPGT_EPI16(p_gap1_j->i, current.i); l_ali_current.i = _MM_OR_SI128( _MM_AND_SI128(p_l_ali_gap1_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i)); current.i = _MM_OR_SI128( _MM_AND_SI128(p_gap1_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, current.i)); boolean_reg.i = _MM_AND_SI128( _MM_CMPEQ_EPI16(p_gap1_j->i, current.i), _MM_CMPLT_EPI16(p_l_ali_gap1_j->i, l_ali_current.i)); l_ali_current.i = _MM_OR_SI128( _MM_AND_SI128(p_l_ali_gap1_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i)); current.i = _MM_OR_SI128( _MM_AND_SI128(p_gap1_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, current.i)); boolean_reg.i = _MM_CMPGT_EPI16(p_gap2_j->i, current.i); l_ali_current.i = _MM_OR_SI128( _MM_AND_SI128(p_l_ali_gap2_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i)); current.i = _MM_OR_SI128( _MM_AND_SI128(p_gap2_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, current.i)); boolean_reg.i = _MM_AND_SI128( _MM_CMPEQ_EPI16(p_gap2_j->i, current.i), _MM_CMPLT_EPI16(p_l_ali_gap2_j->i, l_ali_current.i)); l_ali_current.i = _MM_OR_SI128( _MM_AND_SI128(p_l_ali_gap2_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i)); current.i = _MM_OR_SI128( _MM_AND_SI128(p_gap2_j->i, boolean_reg.i), _MM_ANDNOT_SI128(boolean_reg.i, current.i)); /* fprintf(stderr, "\nline = %d", line); fprintf(stderr, "\nDiag, r %d : ", j); printreg((*(p_diag_j)).i); fprintf(stderr, "Gap1 : "); printreg((*(p_gap1_j)).i); fprintf(stderr, "Gap2 : "); printreg((*(p_gap2_j)).i); fprintf(stderr, "current : "); printreg(current.i); fprintf(stderr, "L ALI\nDiag r %d : ", j); printreg((*(p_l_ali_diag_j)).i); fprintf(stderr, "Gap1 : "); printreg((*(p_l_ali_gap1_j)).i); fprintf(stderr, "Gap2 : "); printreg((*(p_l_ali_gap2_j)).i); fprintf(stderr, "current : "); printreg(l_ali_current.i); */ // diag = gap1 and gap1 = current p_diag_j->i = p_gap1_j->i; p_gap1_j->i = current.i; // l_ali_diag = l_ali_gap1 and l_ali_gap1 = l_ali_current+1 p_l_ali_diag_j->i = p_l_ali_gap1_j->i; p_l_ali_gap1_j->i = _MM_ADD_EPI16(l_ali_current.i, _MM_SET1_EPI16(1)); } // shifts for gap2, to do only once all the registers of a line have been computed Copier gap2 puis le charger depuis la copie? for (j=0; j < numberOfRegistersPerLine; j++) { if ((odd_line && even_BLL) || (even_line && odd_BLL)) { p_gap2[j].i = _MM_LOADU_SI128((p_gap1[j].s16)-1); p_l_ali_gap2[j].i = _MM_LOADU_SI128((p_l_ali_gap1[j].s16)-1); if (j == 0) { p_gap2[j].i = _MM_INSERT_EPI16(p_gap2[j].i, 0, 0); p_l_ali_gap2[j].i = _MM_INSERT_EPI16(p_l_ali_gap2[j].i, max, 0); } } else { p_gap2[j].i = _MM_LOADU_SI128(p_gap1[j].s16+1); p_l_ali_gap2[j].i = _MM_LOADU_SI128(p_l_ali_gap1[j].s16+1); if (j == numberOfRegistersPerLine - 1) { p_gap2[j].i = _MM_INSERT_EPI16(p_gap2[j].i, 0, 7); p_l_ali_gap2[j].i = _MM_INSERT_EPI16(p_l_ali_gap2[j].i, max, 7); } } } // end shifts for gap2 } /* /// Recovering LCS and alignment lengths \\\ */ // finding the location of the results in the registers : diff = l1-l2; if ((diff & 1) && odd_BLL) l_loc = (int) floor((double)(bandLengthLeft) / (double)2) - floor((double)(diff) / (double)2); else l_loc = (int) floor((double)(bandLengthLeft) / (double)2) - ceil((double)(diff) / (double)2); l_reg = (int)floor((double)l_loc/(double)8.0); //fprintf(stderr, "\nl_reg = %d, l_loc = %d\n", l_reg, l_loc); l_loc = l_loc - l_reg*8; // extracting the results from the registers : *lcs_length = extract_reg(p_gap1[l_reg].i, l_loc); *ali_length = extract_reg(p_l_ali_gap1[l_reg].i, l_loc) - 1; // freeing the registers free(SSEregisters); } double sse_banded_align_just_lcs(int16_t* seq1, int16_t* seq2, int l1, int l2, int bandLengthLeft, int bandLengthTotal) { register int j; int k1, k2; int diff; int l_reg, l_loc; int16_t l_lcs; int line; int numberOfRegistersPerLine; int numberOfRegistersFor3Lines; BOOL even_line; BOOL odd_line; BOOL even_BLL; BOOL odd_BLL; um128* SSEregisters; um128* p_diag; um128* p_gap1; um128* p_gap2; um128* p_diag_j; um128* p_gap1_j; um128* p_gap2_j; um128 current; um128 nucs1; um128 nucs2; um128 scores; // Initialisations odd_BLL = bandLengthLeft & 1; even_BLL = !odd_BLL; numberOfRegistersPerLine = bandLengthTotal / 8; numberOfRegistersFor3Lines = 3 * numberOfRegistersPerLine; SSEregisters = malloc(numberOfRegistersFor3Lines * sizeof(um128)); // preparer registres SSE for (j=0; j 0) { if (normalize) { if (reference == MINLEN) LCSmin = threshold*l2; else // ref = maxlen or alilen LCSmin = threshold*l1; } else if (lcsmode) LCSmin = threshold; else if ((reference == MINLEN)) // not lcsmode LCSmin = l2 - threshold; else // not lcsmode and ref = maxlen or alilen LCSmin = l1 - threshold; } else LCSmin = 0; return(LCSmin); } int calculateSSEBandLength(int bandLengthRight, int bandLengthLeft) { // *bandLengthTotal= (double) floor(bandLengthRight + bandLengthLeft) / 2.0 + 1; int bandLengthTotal= (double)(bandLengthRight + bandLengthLeft) / 2.0 + 1.0; return (bandLengthTotal & (~ (int)7)) + (( bandLengthTotal & (int)7) ? 8:0); // Calcule le multiple de 8 superieur } int calculateSizeToAllocate(int maxLen, int minLen, int LCSmin) { int size; int notUsed; calculateBandLengths(maxLen, minLen, ¬Used, &size, LCSmin); // max size = max left band length * 2 //fprintf(stderr, "\nsize for address before %8 = %d", size); size*= 2; size = (size & (~ (int)7)) + (( size & (int)7) ? 8:0); // Calcule le multiple de 8 superieur size*= 3; size+= 16; //fprintf(stderr, "\nsize for address = %d", size); return(size*sizeof(int16_t)); } void iniSeq(int16_t* seq, int size, int16_t iniValue) { int16_t *target=seq; int16_t *end = target + (size_t)size; for (; target < end; target++) *target = iniValue; } void putSeqInSeq(int16_t* seq, char* s, int l, BOOL reverse) { int16_t *target=seq; int16_t *end = target + (size_t)l; char *source=s; if (reverse) for (source=s + (size_t)l-1; target < end; target++, source--) *target=*source; else for (; target < end; source++,target++) *target=*source; } void initializeAddressWithGaps(int16_t* address, int bandLengthTotal, int bandLengthLeft, int l1) { int i; int address_00, x_address_10, address_01, address_01_shifted; int numberOfRegistersPerLine; int bm; int value=INT16_MAX-l1; numberOfRegistersPerLine = bandLengthTotal / 8; bm = bandLengthLeft%2; for (i=0; i < (3*numberOfRegistersPerLine*8); i++) address[i] = value; // 0,0 set to 1 and 0,1 and 1,0 set to 2 address_00 = bandLengthLeft / 2; x_address_10 = address_00 + bm - 1; address_01 = numberOfRegistersPerLine*8 + x_address_10; address_01_shifted = numberOfRegistersPerLine*16 + address_00 - bm; // fill address_00, address_01,+1, address_01_shifted,+1 address[address_00] = 1; address[address_01] = 2; address[address_01+1] = 2; address[address_01_shifted] = 2; address[address_01_shifted+1] = 2; } double sse_banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int LCSmin) { double id; int bandLengthRight, bandLengthLeft, bandLengthTotal; int ali_length; //fprintf(stderr, "\nl1 = %d, l2 = %d\n", l1, l2); calculateBandLengths(l1, l2, &bandLengthRight, &bandLengthLeft, LCSmin); //fprintf(stderr, "\nBLL = %d, BLR = %d, LCSmin = %d\n", bandLengthLeft, bandLengthRight, LCSmin); bandLengthTotal = calculateSSEBandLength(bandLengthRight, bandLengthLeft); //fprintf(stderr, "\nBLT = %d\n", bandLengthTotal); if ((reference == ALILEN) && (normalize || !lcsmode)) { initializeAddressWithGaps(address, bandLengthTotal, bandLengthLeft, l1); sse_banded_align_lcs_and_ali_len(seq1, seq2, l1, l2, bandLengthLeft, bandLengthTotal, address, &id, &ali_length); } else id = sse_banded_align_just_lcs(seq1, seq2, l1, l2, bandLengthLeft, bandLengthTotal); //fprintf(stderr, "\nid before normalizations = %f", id); //fprintf(stderr, "\nlcs = %f, ali = %d\n", id, ali_length); if (!lcsmode && !normalize) switch(reference) { case ALILEN: id = ali_length - id; break; case MAXLEN: id = l1 - id; break; case MINLEN: id = l2 - id; } //fprintf(stderr, "\n2>>> %f, %d\n", id, ali_length); if (normalize) switch(reference) { case ALILEN: id = id / (double) ali_length; break; case MAXLEN: id = id / (double) l1; break; case MINLEN: id = id / (double) l2; } //fprintf(stderr, "\nid = %f\n", id); return(id); } double generic_sse_banded_lcs_align(char* seq1, char* seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, int16_t** address, int* buffer_size, int16_t** iseq1, int16_t** iseq2, int* buffer_sizeS) { double id; int l1; int l2; int lmax, lmin; int sizeToAllocateForBand; int maxBLL, notUsed; int sizeToAllocateForSeqs; int LCSmin; l1 = strlen(seq1); l2 = strlen(seq2); if (l2 > l1) { lmax = l1; lmin = l2; } else { lmax = l2; lmin = l1; } if (!lcsmode && (normalize==TRUE)) { threshold = 1.0 - threshold; } LCSmin = calculateLCSmin(lmax, lmin, threshold, normalize, reference, lcsmode); // Allocating space for matrix band if the alignment must be computed if ((reference == ALILEN) && ((lcsmode && normalize) || (!lcsmode))) // checking if alignment must be computed { sizeToAllocateForBand = calculateSizeToAllocate(lmax, lmin, LCSmin); if (sizeToAllocateForBand > (*buffer_size)) { // reallocating if needed address = reallocA16Address(*address, sizeToAllocateForBand); } } // Allocating space for the int16_t arrays representing the sequences calculateBandLengths(lmax, lmin, ¬Used, &maxBLL, LCSmin); sizeToAllocateForSeqs = 2*maxBLL+lmax; if (sizeToAllocateForSeqs > *buffer_sizeS) { (*(iseq1)) = realloc((*(iseq1)), sizeToAllocateForSeqs*sizeof(int16_t)); (*(iseq2)) = realloc((*(iseq2)), sizeToAllocateForSeqs*sizeof(int16_t)); } iniSeq(*(iseq1), maxBLL, 0); iniSeq(*(iseq2), maxBLL, 255); *(iseq1) = *(iseq1)+maxBLL; *(iseq2) = *(iseq2)+maxBLL; // longest seq must be first argument of sse_align function if (l2 > l1) { putSeqInSeq((*(iseq1)), seq2, l2, TRUE); putSeqInSeq((*(iseq2)), seq1, l1, FALSE); id = sse_banded_lcs_align(*(iseq1), *(iseq2), l2, l1, normalize, reference, lcsmode, *address, LCSmin); } else { putSeqInSeq((*(iseq1)), seq1, l1, TRUE); putSeqInSeq((*(iseq2)), seq2, l2, FALSE); id = sse_banded_lcs_align(*(iseq1), *(iseq2), l1, l2, normalize, reference, lcsmode, *address, LCSmin); } return(id); } int prepareTablesForSumathings(int lmax, int lmin, double threshold, BOOL normalize, int reference, BOOL lcsmode, int16_t** address, int16_t** iseq1, int16_t** iseq2) { int sizeToAllocateForBand; int maxBLL; int notUsed; int sizeToAllocateForSeqs; int LCSmin; LCSmin = calculateLCSmin(lmax, lmin, threshold, normalize, reference, lcsmode); // Allocating space for matrix band if the alignment must be computed if ((reference == ALILEN) && (normalize || !lcsmode)) // checking if alignment must be computed { sizeToAllocateForBand = calculateSizeToAllocate(lmax, lmin, LCSmin); (*(address)) = getA16Address(sizeToAllocateForBand); } // Allocating space for the int16_t arrays representing the sequences calculateBandLengths(lmax, lmin, ¬Used, &maxBLL, LCSmin); sizeToAllocateForSeqs = 2*maxBLL+lmax; (*(iseq1)) = malloc(sizeToAllocateForSeqs*sizeof(int16_t)); (*(iseq2)) = malloc(sizeToAllocateForSeqs*sizeof(int16_t)); iniSeq(*(iseq1), maxBLL, 0); iniSeq(*(iseq2), maxBLL, 255); *(iseq1) = *(iseq1)+maxBLL; *(iseq2) = *(iseq2)+maxBLL; return(maxBLL+lmax); } double alignForSumathings(char* seq1, int16_t* iseq1, char* seq2, int16_t* iseq2, int l1, int l2, BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int sizeForSeqs, int LCSmin) { double id; iniSeq(iseq1, sizeForSeqs, 0); iniSeq(iseq2, sizeForSeqs, 255); if (l2 > l1) { putSeqInSeq(iseq1, seq2, l2, TRUE); putSeqInSeq(iseq2, seq1, l1, FALSE); id = sse_banded_lcs_align(iseq1, iseq2, l2, l1, normalize, reference, lcsmode, address, LCSmin); } else { putSeqInSeq(iseq1, seq1, l1, TRUE); putSeqInSeq(iseq2, seq2, l2, FALSE); id = sse_banded_lcs_align(iseq1, iseq2, l1, l2, normalize, reference, lcsmode, address, LCSmin); } return(id); } sumaclust_v1.0.10/sumalibs/liblcs/sse_banded_LCS_alignment.h000644 000765 000024 00000002414 12551723264 026130 0ustar00celinemercierstaff000000 000000 /* * sse_banded_LCS_alignment.h * * Created on: november 29, 2012 * Author: mercier */ #ifndef SSE_BANDED_LCS_ALIGNMENT_H_ #define SSE_BANDED_LCS_ALIGNMENT_H_ #include double sse_banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int LCSmin); int calculateSizeToAllocate(int maxLen, int minLen, int LCSmin); void calculateThresholdFromErrorNumber(int error, int length, double* threshold); void iniSeq(int16_t* seq, int size, int16_t iniValue); void putSeqInSeq(int16_t* seq, char* s, int l, BOOL reverse); double generic_sse_banded_lcs_align(char* seq1, char* seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, int16_t** address, int* buffer_size, int16_t** iseq1, int16_t** iseq2, int* buffer_sizeS); int prepareTablesForSumathings(int lmax, int lmin, double threshold, BOOL normalize, int reference, BOOL lcsmode, int16_t** address, int16_t** iseq1, int16_t** iseq2); double alignForSumathings(char* seq1, int16_t* iseq1, char* seq2, int16_t* iseq2, int l1, int l2, BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int sizeForSeqs, int LCSmin); int calculateLCSmin(int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode); #endif sumaclust_v1.0.10/sumalibs/liblcs/upperband.c000644 000765 000024 00000022121 12551723264 023252 0ustar00celinemercierstaff000000 000000 #include "../libsse/_sse.h" #include #include #include "../libutils/utilities.h" #include "../libfasta/sequence.h" #include "sse_banded_LCS_alignment.h" inline static uchar_v hash4m128(uchar_v frag) { uchar_v words; vUInt8 mask_03= _MM_SET1_EPI8(0x03); // charge le registre avec 16x le meme octet vUInt8 mask_FC= _MM_SET1_EPI8(0xFC); frag.m = _MM_SRLI_EPI64(frag.m,1); // shift logic a droite sur 2 x 64 bits frag.m = _MM_AND_SI128(frag.m,mask_03); // and sur les 128 bits words.m= _MM_SLLI_EPI64(frag.m,2); words.m= _MM_AND_SI128(words.m,mask_FC); frag.m = _MM_SRLI_SI128(frag.m,1); words.m= _MM_OR_SI128(words.m,frag.m); words.m= _MM_SLLI_EPI64(words.m,2); words.m= _MM_AND_SI128(words.m,mask_FC); frag.m = _MM_SRLI_SI128(frag.m,1); words.m= _MM_OR_SI128(words.m,frag.m); words.m= _MM_SLLI_EPI64(words.m,2); words.m= _MM_AND_SI128(words.m,mask_FC); frag.m = _MM_SRLI_SI128(frag.m,1); words.m= _MM_OR_SI128(words.m,frag.m); return words; } #ifdef __SSE2__ inline static int anyzerom128(vUInt8 data) { vUInt8 mask_00= _MM_SETZERO_SI128(); uint64_v tmp; tmp.m = _MM_CMPEQ_EPI8(data,mask_00); return (int)(tmp.c[0]!=0 || tmp.c[1]!=0); } #else inline static int anyzerom128(vUInt8 data) { int i; um128 tmp; tmp.i = data; for (i=0;i<8;i++) if (tmp.s8[i]==0) return 1; return 0; } #endif inline static void dumpm128(unsigned short *table,vUInt8 data) { memcpy(table,&data,16); } /** * Compute 4mer occurrence table from a DNA sequence * * sequence : a pointer to the null terminated nuc sequence * table : a pointer to a 256 cells unisgned char table for * storing the occurrence table * count : pointer to an int value used as a return value * containing the global word counted * * returns the number of words observed in the sequence with a * count greater than 255. */ int buildTable(const char* sequence, unsigned char *table, int *count) { int overflow = 0; int wc=0; int i; vUInt8 mask_00= _MM_SETZERO_SI128(); uchar_v frag; uchar_v words; uchar_v zero; char* s; s=(char*)sequence; memset(table,0,256*sizeof(unsigned char)); // encode ascii sequence with A : 00 C : 01 T: 10 G : 11 for(frag.m=_MM_LOADU_SI128((vUInt8*)s); ! anyzerom128(frag.m); s+=12,frag.m=_MM_LOADU_SI128((vUInt8*)s)) { words= hash4m128(frag); // printf("%d %d %d %d\n",words.c[0],words.c[1],words.c[2],words.c[3]); if (table[words.c[0]]<255) table[words.c[0]]++; else overflow++; if (table[words.c[1]]<255) table[words.c[1]]++; else overflow++; if (table[words.c[2]]<255) table[words.c[2]]++; else overflow++; if (table[words.c[3]]<255) table[words.c[3]]++; else overflow++; if (table[words.c[4]]<255) table[words.c[4]]++; else overflow++; if (table[words.c[5]]<255) table[words.c[5]]++; else overflow++; if (table[words.c[6]]<255) table[words.c[6]]++; else overflow++; if (table[words.c[7]]<255) table[words.c[7]]++; else overflow++; if (table[words.c[8]]<255) table[words.c[8]]++; else overflow++; if (table[words.c[9]]<255) table[words.c[9]]++; else overflow++; if (table[words.c[10]]<255) table[words.c[10]]++; else overflow++; if (table[words.c[11]]<255) table[words.c[11]]++; else overflow++; wc+=12; } zero.m=_MM_CMPEQ_EPI8(frag.m,mask_00); //printf("frag=%d %d %d %d\n",frag.c[0],frag.c[1],frag.c[2],frag.c[3]); //printf("zero=%d %d %d %d\n",zero.c[0],zero.c[1],zero.c[2],zero.c[3]); words = hash4m128(frag); if (zero.c[0]+zero.c[1]+zero.c[2]+zero.c[3]==0) for(i=0;zero.c[i+3]==0;i++,wc++) if (table[words.c[i]]<255) table[words.c[i]]++; else overflow++; if (count) *count=wc; return overflow; } static inline vUInt16 partialminsum(vUInt8 ft1,vUInt8 ft2) { vUInt8 mini; vUInt16 minilo; vUInt16 minihi; vUInt8 mask_00= _MM_SETZERO_SI128(); mini = _MM_MIN_EPU8(ft1,ft2); minilo = _MM_UNPACKLO_EPI8(mini,mask_00); minihi = _MM_UNPACKHI_EPI8(mini,mask_00); return _MM_ADDS_EPU16(minilo,minihi); } int compareTable(unsigned char *t1, int over1, unsigned char* t2, int over2) { vUInt8 ft1; vUInt8 ft2; vUInt8 *table1=(vUInt8*)t1; vUInt8 *table2=(vUInt8*)t2; ushort_v summini; int i; int total; ft1 = _MM_LOADU_SI128(table1); ft2 = _MM_LOADU_SI128(table2); summini.m = partialminsum(ft1,ft2); table1++; table2++; for (i=1;i<16;i++,table1++,table2++) { ft1 = _MM_LOADU_SI128(table1); ft2 = _MM_LOADU_SI128(table2); summini.m = _MM_ADDS_EPU16(summini.m,partialminsum(ft1,ft2)); } // Finishing the sum process summini.m = _MM_ADDS_EPU16(summini.m,_MM_SRLI_SI128(summini.m,8)); // sum the 4 firsts with the 4 lasts summini.m = _MM_ADDS_EPU16(summini.m,_MM_SRLI_SI128(summini.m,4)); total = summini.c[0]+summini.c[1]; total+= (over1 < over2) ? over1:over2; return total; } int threshold4(int wordcount,double identity) { int error; int lmax; wordcount+=3; error = (int)floor((double)wordcount * ((double)1.0-identity)); lmax = (wordcount - error) / (error + 1); if (lmax < 4) return 0; return (lmax - 3) \ * (error + 1) \ + ((wordcount - error) % (error + 1)); } int thresholdLCS4(int32_t reflen,int32_t lcs) { int nbfrag; int smin; int R; int common; nbfrag = (reflen - lcs)*2 + 1; smin = lcs/nbfrag; R = lcs - smin * nbfrag; common = MAX(smin - 2,0) * R + MAX(smin - 3,0) * (nbfrag - R); return common; } int hashDB(fastaSeqCount db) { int32_t i; int32_t count; fprintf(stderr,"Indexing dataset..."); for (i=0; i < db.count;i++) { db.fastaSeqs[i].table = util_malloc((256)*sizeof(unsigned char), __FILE__, __LINE__); db.fastaSeqs[i].over = buildTable((const char*)(db.fastaSeqs[i].sequence), db.fastaSeqs[i].table, &count); } fprintf(stderr," : Done\n"); return db.count; } BOOL isPossible(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode) { int32_t reflen; int32_t maxlen; int32_t lcs; int32_t mincount; if (seq1->length < 12 || seq2->length < 12) return TRUE; maxlen = MAX(seq1->length,seq2->length); if (reference==ALILEN || reference==MAXLEN) reflen = maxlen; else reflen = MIN(seq1->length,seq2->length); if (normalize) { if (! lcsmode) threshold = 1. - threshold; lcs = (int32_t)ceil((double)reflen * threshold); } else { if (! lcsmode) threshold = reflen - threshold; lcs = (int32_t) threshold; } if (lcs > MIN(seq1->length,seq2->length)) return FALSE; mincount = thresholdLCS4(maxlen,lcs); return compareTable(seq1->table,seq1->over,seq2->table,seq2->over) >=mincount; } BOOL isPossibleSumathings(fastaSeqPtr seq1, fastaSeqPtr seq2, int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode) { // optimized version of the filter for sumaclust and sumatra int32_t reflen; int32_t lcs; int32_t mincount; if (l1 < 12 || l2 < 12) return TRUE; if (reference==ALILEN || reference==MAXLEN) reflen = l1; else reflen = l2; if (normalize) lcs = (int32_t)ceil((double)reflen * threshold); else { if (! lcsmode) threshold = reflen - threshold; lcs = (int32_t) threshold; } mincount = thresholdLCS4(l1,lcs); return compareTable(seq1->table,seq1->over,seq2->table,seq2->over) >=mincount; } void filters(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin) { // score takes value -1 if filters are passed. score must be initialized in calling function. int l1; int l2; l1 = seq1->length; l2 = seq2->length; if (l1 >= l2) { *LCSmin = calculateLCSmin(l1, l2, threshold, normalize, reference, lcsmode); if (l2 >= *LCSmin) { if (isPossibleSumathings(seq1, seq2, l1, l2, threshold, normalize, reference, lcsmode)) // 4-mers filter *score = -1.0; } } else { *LCSmin = calculateLCSmin(l2, l1, threshold, normalize, reference, lcsmode); if (l1 >= *LCSmin) { if (isPossibleSumathings(seq2, seq1, l2, l1, threshold, normalize, reference, lcsmode)) // 4-mers filter *score = -1.0; } } } void filtersSumatra(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin) { // score takes value -2 if filters are not passed, -1 if filters are passed and >= 0 with max score if the 2 sequences are identical. int l1; int l2; l1 = seq1->length; *score = -2.0; if (strcmp(seq1->sequence, seq2->sequence) == 0) // the 2 sequences are identical { if (lcsmode && normalize) *score = 1.0; else if (!lcsmode) *score = 0.0; else *score = l1; } else if (threshold != 0) { l2 = seq2->length; if (l1 >= l2) { *LCSmin = calculateLCSmin(l1, l2, threshold, normalize, reference, lcsmode); if (l2 >= *LCSmin) { if (isPossibleSumathings(seq1, seq2, l1, l2, threshold, normalize, reference, lcsmode)) // 4-mers filter *score = -1.0; } } else { *LCSmin = calculateLCSmin(l2, l1, threshold, normalize, reference, lcsmode); if (l1 >= *LCSmin) { if (isPossibleSumathings(seq2, seq1, l2, l1, threshold, normalize, reference, lcsmode)) // 4-mers filter *score = -1.0; } } } else *LCSmin = 0; } sumaclust_v1.0.10/sumalibs/liblcs/upperband.h000644 000765 000024 00000001472 12551723264 023265 0ustar00celinemercierstaff000000 000000 #ifndef UPPERBAND_H_ #define UPPERBAND_H_ int buildTable(const char *sequence, unsigned char *table, int *count); int compareTable(unsigned char *t1, int over1, unsigned char* t2, int over2); int threshold4(int wordcount,double identity); int thresholdLCS4(int32_t reflen,int32_t lcs); int hashDB(fastaSeqCount); BOOL isPossible(fastaSeqPtr, fastaSeqPtr, BOOL, int, double, BOOL); BOOL isPossibleSumathings(fastaSeqPtr seq1, fastaSeqPtr seq2, int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode); void filters(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin); void filtersSumatra(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin); #endif sumaclust_v1.0.10/sumalibs/libfile/fileHandling.c000644 000765 000024 00000003352 12551723264 024021 0ustar00celinemercierstaff000000 000000 /** * FileName: fileHandling.c * Authors: Tiayyba Riaz, Celine Mercier * Description: C file for file handling functions * **/ #include #include #include #include "../libutils/utilities.h" /* * Function Name: fileOpen(char* fileName, BOOL abortOnError) * Description: Opens the file and returns the pointer to file object */ FILE *file_open(char* fileName, BOOL abortOnError) { FILE* fp; if (fileName == NULL && abortOnError) ERRORABORT(FILE_OPENING_ERROR, "File name not given."); if (fileName == NULL) return NULL; fp = fopen(fileName, "r"); return fp; } FILE *file_openrw(char* fileName, BOOL abortOnError) { FILE* fp; if (fileName == NULL && abortOnError) ERRORABORT(FILE_OPENING_ERROR, "File name not given."); if (fileName == NULL) return NULL; fp = fopen(fileName, "w+"); return fp; } /* * Function Name: fileNextChar(FILE* fp) * Description: Reads the file and returns next character, if file is null or its end of file, returns \¯. */ char file_nextChar(FILE* fp) { if (fp == NULL) return '\0'; if(feof(fp)) return '\0'; return (char) fgetc(fp); } /* * Function Name: *fileNextLine(FILE *fp, char *buffer, int32_t bufferSize) * Description: Reads the file and returns next line, if file is null or its end of file, returns \¯. */ char *file_nextLine(FILE *fp, char *buffer, int32_t bufferSize) { if(fp == NULL) return NULL; if(feof(fp)) return NULL; return fgets(buffer, bufferSize, fp); } void exitIfEmptyFile(FILE *file) { long savedOffset = ftell(file); fseek(file, 0, SEEK_END); if (ftell(file) == 0) { fprintf(stderr, "\nInput file is empty.\n"); exit(1); } fseek(file, savedOffset, SEEK_SET); } sumaclust_v1.0.10/sumalibs/libfile/fileHandling.h000644 000765 000024 00000000777 12551723264 024036 0ustar00celinemercierstaff000000 000000 /** * FileName: fileHandling.h * Authors: Tiayyba Riaz, Celine Mercier * Description: Header file for file handling functions * **/ #ifndef FILEHANDLING_H_ #define FILEHANDLING_H_ #include "../libutils/utilities.h" /* Prototypes */ FILE *file_open(char* fileName, BOOL abortOnError); char file_nextChar(FILE* fp); char *file_nextLine(FILE *fp, char *buffer, int32_t bufferSize); FILE *file_openrw(char* fileName, BOOL abortOnError); void exitIfEmptyFile(FILE *file); #endif /*FILEHANDLING_H_*/ sumaclust_v1.0.10/sumalibs/libfile/Makefile000644 000765 000024 00000000442 12551723264 022726 0ustar00celinemercierstaff000000 000000 SOURCES = fileHandling.c SRCS=$(SOURCES) OBJECTS= $(patsubst %.c,%.o,$(SOURCES)) LIBFILE= libfile.a RANLIB=ranlib include ../global.mk all: $(LIBFILE) clean: rm -rf $(OBJECTS) $(LIBFILE) rm -f *.P rm -f *.a $(LIBFILE): $(OBJECTS) ar -cr $@ $? $(RANLIB) $@ sumaclust_v1.0.10/sumalibs/libfasta/fasta_header_handler.c000644 000765 000024 00000005402 12551723264 025715 0ustar00celinemercierstaff000000 000000 #include #include #include #include "sequence.h" #include "fasta_header_parser.h" #include "fasta_header_handler.h" char* char_header_add_field(char* header, char* name, char* value) { int lheader = strlen(header); header = (char*) realloc(header, (lheader+strlen(name)+strlen(value)+4)*sizeof(char)); if (header[lheader-1] == '.') { strcpy(header+lheader-1,";"); strcpy(header+lheader," "); strcpy(header+lheader+1,name); strcpy(header+lheader+1+strlen(name),"="); strcpy(header+lheader+1+strlen(name)+1,value); } else { strcpy(header+lheader,";"); strcpy(header+lheader+1," "); strcpy(header+lheader+2,name); strcpy(header+lheader+2+strlen(name),"="); strcpy(header+lheader+2+strlen(name)+1,value); } return header; } char* fastaSeqPtr_header_add_field(fastaSeqPtr seq, char* name, char* value) { int lheader = strlen(seq->rawheader); int i; char* buffer; char* rawheader; rawheader = (char*) malloc((lheader+strlen(name)+strlen(value)+5)*sizeof(char)); strcpy(rawheader, seq->rawheader); buffer = calloc(lheader, sizeof(char)); i=0; while ((rawheader[i] != ' ') && (rawheader[i] != 0)) i++; if (rawheader[i] == ' ') strcpy(buffer, rawheader+i); else strcpy(rawheader+i, " "); i++; strcpy(rawheader+i,name); strcpy(rawheader+i+strlen(name),"="); strcpy(rawheader+i+strlen(name)+1,value); strcpy(rawheader+i+strlen(name)+1+strlen(value),";"); strcpy(rawheader+i+strlen(name)+1+strlen(value)+1, buffer); free(buffer); return(rawheader); } element_from_header* table_header_add_field(element_from_header* header, char* name, char* value) { int nbf; nbf = atoi(header[0].value); nbf++; header = (element_from_header*) realloc(header, (nbf+1)*sizeof(element_from_header)); header[nbf].name = (char*) malloc((1+strlen(name))*sizeof(char)); strcpy(header[nbf].name, name); header[nbf].value = (char*) malloc((1+strlen(value))*sizeof(char)); strcpy(header[nbf].value, value); sprintf(header[0].value, "%d", nbf); return(header); } void free_header_table(element_from_header* header) { int i; int nbf = atoi(header[0].value); for (i = 0; i <= nbf; i++) { free((header[i]).name); free((header[i]).value); } free(header); } char* getItemFromHeader(char* name, element_from_header* header) { char* value = 0; int nbf; int i; nbf = atoi(header[0].value); for (i = 1; i <= nbf; i++) { if (strcmp(header[i].name,name)==0) value = header[i].value; } return value; } void changeValue(element_from_header* header, char* name, char* newValue) { int i; int nbf = atoi(header[0].value); for (i = 1; i <= nbf; i++) { if (strcmp(header[i].name, name)==0) { header[i].value = realloc(header[i].value, (1+strlen(newValue))*sizeof(char)); strcpy(header[i].value, newValue); } } } sumaclust_v1.0.10/sumalibs/libfasta/fasta_header_handler.h000644 000765 000024 00000001150 12551723264 025716 0ustar00celinemercierstaff000000 000000 #ifndef FASTA_HEADER_HANDLER_H_ #define FASTA_HEADER_HANDLER_H_ #include "sequence.h" char* char_header_add_field(char*,char*,char*); char* fastaSeqPtr_header_add_field(fastaSeqPtr seq, char* name, char* value); element_from_header* table_header_add_dic(element_from_header* header, char* name, struct hashtable *hashtab); element_from_header* table_header_add_field(element_from_header* header, char* name, char* value); void free_header_table(element_from_header*); char* getItemFromHeader(char*, element_from_header*); void changeValue(element_from_header* header, char* name, char* newValue); #endif sumaclust_v1.0.10/sumalibs/libfasta/fasta_header_parser.c000644 000765 000024 00000144532 12551723264 025604 0ustar00celinemercierstaff000000 000000 #line 3 "" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define yy_create_buffer header_yy_create_buffer #define yy_delete_buffer header_yy_delete_buffer #define yy_flex_debug header_yy_flex_debug #define yy_init_buffer header_yy_init_buffer #define yy_flush_buffer header_yy_flush_buffer #define yy_load_buffer_state header_yy_load_buffer_state #define yy_switch_to_buffer header_yy_switch_to_buffer #define yyin header_yyin #define yyleng header_yyleng #define yylex header_yylex #define yylineno header_yylineno #define yyout header_yyout #define yyrestart header_yyrestart #define yytext header_yytext #define yywrap header_yywrap #define yyalloc header_yyalloc #define yyrealloc header_yyrealloc #define yyfree header_yyfree #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE header_yyrestart(header_yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t header_yyleng; extern FILE *header_yyin, *header_yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up header_yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up header_yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via header_yyrestart()), so that the user can continue scanning by * just pointing header_yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when header_yytext is formed. */ static char yy_hold_char; static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t header_yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow header_yywrap()'s to do buffer switches * instead of setting up a fresh header_yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void header_yyrestart (FILE *input_file ); void header_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE header_yy_create_buffer (FILE *file,int size ); void header_yy_delete_buffer (YY_BUFFER_STATE b ); void header_yy_flush_buffer (YY_BUFFER_STATE b ); void header_yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void header_yypop_buffer_state (void ); static void header_yyensure_buffer_stack (void ); static void header_yy_load_buffer_state (void ); static void header_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER header_yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE header_yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE header_yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE header_yy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *header_yyalloc (yy_size_t ); void *header_yyrealloc (void *,yy_size_t ); void header_yyfree (void * ); #define yy_new_buffer header_yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ header_yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ header_yy_create_buffer(header_yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ header_yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ header_yy_create_buffer(header_yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *header_yyin = (FILE *) 0, *header_yyout = (FILE *) 0; typedef int yy_state_type; extern int header_yylineno; int header_yylineno = 1; extern char *header_yytext; #define yytext_ptr header_yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up header_yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ header_yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 12 #define YY_END_OF_BUFFER 13 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[29] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 12, 3, 2, 1, 5, 4, 7, 6, 9, 8, 10, 11, 3, 2, 5, 4, 9, 8, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 1, 5, 6, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[7] = { 0, 1, 2, 3, 4, 4, 1 } ; static yyconst flex_int16_t yy_base[35] = { 0, 0, 0, 22, 21, 6, 0, 12, 0, 26, 29, 0, 0, 29, 0, 0, 29, 29, 0, 0, 29, 29, 0, 0, 0, 0, 0, 0, 29, 23, 16, 22, 20, 20, 18 } ; static yyconst flex_int16_t yy_def[35] = { 0, 28, 1, 1, 1, 28, 5, 28, 7, 28, 28, 29, 30, 28, 31, 32, 28, 28, 33, 34, 28, 28, 29, 30, 31, 32, 33, 34, 0, 28, 28, 28, 28, 28, 28 } ; static yyconst flex_int16_t yy_nxt[36] = { 0, 10, 11, 12, 12, 12, 13, 10, 14, 15, 16, 17, 10, 10, 18, 19, 20, 21, 10, 23, 23, 27, 26, 25, 24, 22, 28, 10, 10, 9, 28, 28, 28, 28, 28, 28 } ; static yyconst flex_int16_t yy_chk[36] = { 0, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 30, 30, 34, 33, 32, 31, 29, 9, 4, 3, 28, 28, 28, 28, 28, 28, 28 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int header_yy_flex_debug; int header_yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *header_yytext; #line 1 "fasta_header_parser.l" /* * Add -ll in Makefile if you modify this file to convert to .c */ #line 10 "fasta_header_parser.l" #include #include #include "header_mem_handler.h" #include "fasta_header_handler.h" #define MEMALLOCATED 10 #define BUFFER 5 #define YY_DECL int header_parser(int *nbf, int *memory_allocated, element_from_header **p_header) #line 502 "" #define INITIAL 0 #define REGID 1 #define REGNAME 2 #define REGVAL 3 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int header_yylex_destroy (void ); int header_yyget_debug (void ); void header_yyset_debug (int debug_flag ); YY_EXTRA_TYPE header_yyget_extra (void ); void header_yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *header_yyget_in (void ); void header_yyset_in (FILE * in_str ); FILE *header_yyget_out (void ); void header_yyset_out (FILE * out_str ); yy_size_t header_yyget_leng (void ); char *header_yyget_text (void ); int header_yyget_lineno (void ); void header_yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int header_yywrap (void ); #else extern int header_yywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( header_yytext, header_yyleng, 1, header_yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( header_yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( header_yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, header_yyin))==0 && ferror(header_yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(header_yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int header_yylex (void); #define YY_DECL int header_yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after header_yytext and header_yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 32 "fasta_header_parser.l" int i; int size_needed; int free_size; char* field; #line 696 "" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! header_yyin ) header_yyin = stdin; if ( ! header_yyout ) header_yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { header_yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = header_yy_create_buffer(header_yyin,YY_BUF_SIZE ); } header_yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of header_yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 29 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 29 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 40 "fasta_header_parser.l" { /*printf("\n{SUP},%s",header_yytext);*/ BEGIN(REGID); } YY_BREAK case 2: YY_RULE_SETUP #line 45 "fasta_header_parser.l" { i=0; field = malloc_field(&free_size); (*p_header)[*nbf].name = (char*) malloc(3*sizeof(char)); strcpy(((*p_header)[*nbf]).name,"id"); size_needed = strlen(header_yytext)+1; (*p_header)[*nbf].value = (char*) malloc(sizeof(char)*size_needed); strcpy(((*p_header)[*nbf]).value,header_yytext); (*nbf)++; } YY_BREAK case 3: YY_RULE_SETUP #line 60 "fasta_header_parser.l" { BEGIN(REGNAME); } YY_BREAK case 4: YY_RULE_SETUP #line 64 "fasta_header_parser.l" { /*fprintf(stderr,"\n{WORD} **%s**",header_yytext);*/ field = store_in_field(field,header_yytext,&free_size,&i); } YY_BREAK case 5: YY_RULE_SETUP #line 69 "fasta_header_parser.l" { /*fprintf(stderr,"\n{SPACE} **%s**",header_yytext);*/ if (i != 0) field = store_in_field(field,header_yytext,&free_size,&i); } YY_BREAK case 6: YY_RULE_SETUP #line 75 "fasta_header_parser.l" { /*fprintf(stderr,"\n{EQUAL},%s",header_yytext);*/ field = store_in_header_table(field, &((*p_header)[*nbf].name), &free_size, &i); BEGIN(REGVAL); } YY_BREAK case 7: YY_RULE_SETUP #line 81 "fasta_header_parser.l" { /*fprintf(stderr,"\n{SEP},%s",header_yytext);*/ (*p_header)[*nbf].name = (char*) malloc(19*sizeof(char)); strcpy((*p_header)[*nbf].name,"definition"); field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); BEGIN(REGNAME); } YY_BREAK case 8: YY_RULE_SETUP #line 90 "fasta_header_parser.l" { /*fprintf(stderr,"\n{WORD} **%s**\n",header_yytext);*/ field = store_in_field(field,header_yytext,&free_size,&i); } YY_BREAK case 9: YY_RULE_SETUP #line 95 "fasta_header_parser.l" { /*fprintf(stderr,"\n{SPACE} **%s**\n",header_yytext);*/ field = store_in_field(field,header_yytext,&free_size,&i); } YY_BREAK case 10: YY_RULE_SETUP #line 100 "fasta_header_parser.l" { /*fprintf(stderr,"\n{SEP},%s\n",header_yytext);*/ field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); BEGIN(REGNAME); } YY_BREAK case 11: YY_RULE_SETUP #line 109 "fasta_header_parser.l" { /*fprintf(stderr, "\nWarning : separator ';' probably missing in header after %s",(*p_header)[*nbf].name);*/ } YY_BREAK case YY_STATE_EOF(REGVAL): #line 113 "fasta_header_parser.l" { field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); end_header_table(p_header, *nbf); free(field); BEGIN(INITIAL); return 0; } YY_BREAK case YY_STATE_EOF(REGNAME): #line 123 "fasta_header_parser.l" { /*(*p_header)[*nbf].name = (char*) malloc(sizeof(char)*19); strcpy((*p_header)[*nbf].name,"other_informations"); field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); */ end_header_table(p_header, *nbf); free(field); BEGIN(INITIAL); return 0; } YY_BREAK case 12: YY_RULE_SETUP #line 136 "fasta_header_parser.l" ECHO; YY_BREAK #line 915 "" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(REGID): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed header_yyin at a new source and called * header_yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = header_yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( header_yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * header_yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of header_yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ header_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; header_yyrestart(header_yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) header_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 29 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 29 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 28); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up header_yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register yy_size_t number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ header_yyrestart(header_yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( header_yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve header_yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void header_yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ header_yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = header_yy_create_buffer(header_yyin,YY_BUF_SIZE ); } header_yy_init_buffer(YY_CURRENT_BUFFER,input_file ); header_yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void header_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * header_yypop_buffer_state(); * header_yypush_buffer_state(new_buffer); */ header_yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; header_yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (header_yywrap()) processing, but the only time this flag * is looked at is after header_yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void header_yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; header_yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE header_yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) header_yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in header_yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) header_yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in header_yy_create_buffer()" ); b->yy_is_our_buffer = 1; header_yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with header_yy_create_buffer() * */ void header_yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) header_yyfree((void *) b->yy_ch_buf ); header_yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a header_yyrestart() or at EOF. */ static void header_yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; header_yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then header_yy_init_buffer was _probably_ * called from header_yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void header_yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) header_yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void header_yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; header_yyensure_buffer_stack(); /* This block is copied from header_yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from header_yy_switch_to_buffer. */ header_yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void header_yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; header_yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { header_yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void header_yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)header_yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in header_yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)header_yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in header_yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE header_yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) header_yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in header_yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; header_yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to header_yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * header_yy_scan_bytes() instead. */ YY_BUFFER_STATE header_yy_scan_string (yyconst char * yystr ) { return header_yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to header_yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE header_yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) header_yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in header_yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = header_yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in header_yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up header_yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ header_yytext[header_yyleng] = (yy_hold_char); \ (yy_c_buf_p) = header_yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ header_yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int header_yyget_lineno (void) { return header_yylineno; } /** Get the input stream. * */ FILE *header_yyget_in (void) { return header_yyin; } /** Get the output stream. * */ FILE *header_yyget_out (void) { return header_yyout; } /** Get the length of the current token. * */ yy_size_t header_yyget_leng (void) { return header_yyleng; } /** Get the current token. * */ char *header_yyget_text (void) { return header_yytext; } /** Set the current line number. * @param line_number * */ void header_yyset_lineno (int line_number ) { header_yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see header_yy_switch_to_buffer */ void header_yyset_in (FILE * in_str ) { header_yyin = in_str ; } void header_yyset_out (FILE * out_str ) { header_yyout = out_str ; } int header_yyget_debug (void) { return header_yy_flex_debug; } void header_yyset_debug (int bdebug ) { header_yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from header_yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT header_yyin = stdin; header_yyout = stdout; #else header_yyin = (FILE *) 0; header_yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * header_yylex_init() */ return 0; } /* header_yylex_destroy is for both reentrant and non-reentrant scanners. */ int header_yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ header_yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; header_yypop_buffer_state(); } /* Destroy the stack itself. */ header_yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * header_yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *header_yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *header_yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void header_yyfree (void * ptr ) { free( (char *) ptr ); /* see header_yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 136 "fasta_header_parser.l" int header_yywrap() { return 1; } element_from_header* header_parser_main(char *h) { int nbfields,memory_allocated; element_from_header* header; char* nbfields_n; char* nbfields_v; nbfields_n = (char*) malloc(9*sizeof(char)); nbfields_v = (char*) malloc(5*sizeof(char)); memory_allocated=MEMALLOCATED; nbfields=1; strcpy(nbfields_n, "nbfields"); strcpy(nbfields_v, "1"); header = (element_from_header*) malloc(memory_allocated * sizeof(element_from_header)); header[0].name = nbfields_n; header[0].value = nbfields_v; YY_BUFFER_STATE state; state=header_yy_scan_string(h); header_parser(&nbfields, &memory_allocated, &header); header_yy_delete_buffer(state); return header; } sumaclust_v1.0.10/sumalibs/libfasta/fasta_header_parser.h000644 000765 000024 00000000274 12551723264 025603 0ustar00celinemercierstaff000000 000000 #ifndef FASTA_HEADER_PARSER_H_ #define FASTA_HEADER_PARSER_H_ typedef struct { char *name; void *value; }element_from_header; element_from_header* header_parser_main(char*); #endif sumaclust_v1.0.10/sumalibs/libfasta/fasta_header_parser.l000644 000765 000024 00000010476 12551723264 025614 0ustar00celinemercierstaff000000 000000 /* * Add -ll in Makefile if you modify this file to convert to .c */ %x REGID %x REGNAME %x REGVAL %{ #include #include #include "header_mem_handler.h" #include "fasta_header_handler.h" #define MEMALLOCATED 10 #define BUFFER 5 #define YY_DECL int header_parser(int *nbf, int *memory_allocated, element_from_header **p_header) %} WORD [[:alnum:]:\-.{},'_()\#\[\]\|\&\"\'\/\%\+]+ WORDID [[:alnum:]:\-.{},'_()\#\[\]\|\&\"\'\/\%\+=;]+ SUP > EOL \n SEP ; SPACE [[:blank:]]+ EQUAL = %% int i; int size_needed; int free_size; char* field; {SUP} { /*printf("\n{SUP},%s",yytext);*/ BEGIN(REGID); } {WORDID} { i=0; field = malloc_field(&free_size); (*p_header)[*nbf].name = (char*) malloc(3*sizeof(char)); strcpy(((*p_header)[*nbf]).name,"id"); size_needed = strlen(yytext)+1; (*p_header)[*nbf].value = (char*) malloc(sizeof(char)*size_needed); strcpy(((*p_header)[*nbf]).value,yytext); (*nbf)++; } {SPACE} { BEGIN(REGNAME); } {WORD} { /*fprintf(stderr,"\n{WORD} **%s**",yytext);*/ field = store_in_field(field,yytext,&free_size,&i); } {SPACE} { /*fprintf(stderr,"\n{SPACE} **%s**",yytext);*/ if (i != 0) field = store_in_field(field,yytext,&free_size,&i); } {EQUAL} { /*fprintf(stderr,"\n{EQUAL},%s",yytext);*/ field = store_in_header_table(field, &((*p_header)[*nbf].name), &free_size, &i); BEGIN(REGVAL); } {SEP} { /*fprintf(stderr,"\n{SEP},%s",yytext);*/ (*p_header)[*nbf].name = (char*) malloc(19*sizeof(char)); strcpy((*p_header)[*nbf].name,"definition"); field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); BEGIN(REGNAME); } {WORD} { /*fprintf(stderr,"\n{WORD} **%s**\n",yytext);*/ field = store_in_field(field,yytext,&free_size,&i); } {SPACE} { /*fprintf(stderr,"\n{SPACE} **%s**\n",yytext);*/ field = store_in_field(field,yytext,&free_size,&i); } {SEP} { /*fprintf(stderr,"\n{SEP},%s\n",yytext);*/ field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); BEGIN(REGNAME); } {EQUAL} { /*fprintf(stderr, "\nWarning : separator ';' probably missing in header after %s",(*p_header)[*nbf].name);*/ } <> { field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); end_header_table(p_header, *nbf); free(field); BEGIN(INITIAL); return 0; } <> { /*(*p_header)[*nbf].name = (char*) malloc(sizeof(char)*19); strcpy((*p_header)[*nbf].name,"other_informations"); field = store_in_header_table(field, &((*p_header)[*nbf].value), &free_size, &i); p_header = check_and_realloc_mem_in_header_table(p_header, nbf, memory_allocated); */ end_header_table(p_header, *nbf); free(field); BEGIN(INITIAL); return 0; } %% int header_yywrap() { return 1; } element_from_header* header_parser_main(char *h) { int nbfields,memory_allocated; element_from_header* header; char* nbfields_n; char* nbfields_v; nbfields_n = (char*) malloc(9*sizeof(char)); nbfields_v = (char*) malloc(5*sizeof(char)); memory_allocated=MEMALLOCATED; nbfields=1; strcpy(nbfields_n, "nbfields"); strcpy(nbfields_v, "1"); header = (element_from_header*) malloc(memory_allocated * sizeof(element_from_header)); header[0].name = nbfields_n; header[0].value = nbfields_v; YY_BUFFER_STATE state; state=yy_scan_string(h); header_parser(&nbfields, &memory_allocated, &header); yy_delete_buffer(state); return header; } sumaclust_v1.0.10/sumalibs/libfasta/fasta_seq_writer.c000644 000765 000024 00000002640 12551723264 025155 0ustar00celinemercierstaff000000 000000 #include #include #include #include "sequence.h" #include "fasta_header_parser.h" void printOnlySeqFromFastaSeqPtr(fastaSeqPtr seq, FILE* output) { char nuc; int n=60; int l = strlen(seq->sequence); for (n=60; nsequence[n]; seq->sequence[n]=0; fprintf(output,"%s\n",seq->sequence+n-60); seq->sequence[n]=nuc; } fprintf(output,"%s\n",seq->sequence+n-60); } void printOnlySeqFromChar(char* seq, FILE* output) { char nuc; int n=60; int l = strlen(seq); for (n=60; n%s\n",seq->rawheader); } void printOnlyHeaderFromTable(element_from_header* header, FILE* output) { int i; int nbf; nbf = atoi(header[0].value); fprintf(output,">%s ",header[1].value); for (i = 2; i <= nbf; i++) { if (strcmp(header[i].name, "definition") != 0) { fprintf(output,"%s",header[i].name); fprintf(output,"="); fprintf(output,"%s; ",header[i].value); } } if (strcmp(header[nbf].name, "definition") == 0) fprintf(output,"%s; ",header[nbf].value); fprintf(output,"\n"); } void printHeaderAndSeqFromFastaSeqPtr(fastaSeqPtr seq, FILE* output) { printOnlyHeaderFromFastaSeqPtr(seq, output); printOnlySeqFromFastaSeqPtr(seq, output); } sumaclust_v1.0.10/sumalibs/libfasta/fasta_seq_writer.h000644 000765 000024 00000000556 12551723264 025166 0ustar00celinemercierstaff000000 000000 #ifndef FASTA_SEQ_WRITER_H_ #define FASTA_SEQ_WRITER_H_ #include "sequence.h" void printOnlySeqFromFastaSeqPtr(fastaSeqPtr, FILE*); void printOnlySeqFromChar(char*, FILE*); void printOnlyHeaderFromFastaSeqPtr(fastaSeqPtr, FILE*); void printOnlyHeaderFromTable(element_from_header*, FILE*); void printHeaderAndSeqFromFastaSeqPtr(fastaSeqPtr, FILE*); #endif sumaclust_v1.0.10/sumalibs/libfasta/header_mem_handler.c000644 000765 000024 00000004331 12551723264 025375 0ustar00celinemercierstaff000000 000000 #include #include #include "header_mem_handler.h" #include #define FIELD_BUFFER 1024 char* malloc_field(int *free_size) { char* field = (char*) malloc(sizeof(char) * FIELD_BUFFER); field[0] = 0; (*free_size) = FIELD_BUFFER; return field; } int check_mem_field(int size_needed) { int number_of_chunks_to_alloc; number_of_chunks_to_alloc = size_needed / FIELD_BUFFER + 1; return number_of_chunks_to_alloc; } char* realloc_field(int number_of_chunks_to_alloc, char* field) { int size_needed; size_needed = number_of_chunks_to_alloc * FIELD_BUFFER; field = realloc(field, (size_needed)*sizeof(char)); return field; } char* check_and_realloc_field(char* field, int size_needed, int* free_size) { size_needed = size_needed + strlen(field); int number_of_chunks_to_alloc = check_mem_field(size_needed); if (strlen(field)>0) field = realloc_field(number_of_chunks_to_alloc, field); else { free(field); field = malloc(number_of_chunks_to_alloc * FIELD_BUFFER); } (*free_size) = number_of_chunks_to_alloc*FIELD_BUFFER - size_needed + 1; return field; } char* store_in_field(char* field, char* yytext, int* free_size, int* i) { int size_needed; size_needed = strlen(yytext)+1; if (size_needed > (*free_size)) field = check_and_realloc_field(field, size_needed, free_size); else (*free_size) = (*free_size) - size_needed + 1; strcpy(&(field[(*i)]),yytext); (*i) = (*i)+size_needed-1; return field; } char* store_in_header_table(char* field, char** storing_place, int* free_size, int* i) { int size_needed; size_needed = strlen(field)+1; *storing_place = (char*) malloc(size_needed*sizeof(char)); strcpy(*storing_place,field); (*i)=0; free(field); field = malloc_field(free_size); return field; } element_from_header** check_and_realloc_mem_in_header_table(element_from_header** p_header, int* nbf, int* memory_allocated) { (*nbf)++; if (*nbf == *memory_allocated) { (*memory_allocated)++; *p_header = (element_from_header*) realloc(*p_header, (*memory_allocated) * sizeof(element_from_header)); } return p_header; } void end_header_table(element_from_header** p_header, int nbf) { nbf = nbf - 1; //fprintf(stderr, "nbf = %d", nbf); sprintf((*p_header)->value, "%d", nbf); } sumaclust_v1.0.10/sumalibs/libfasta/header_mem_handler.h000644 000765 000024 00000000774 12551723264 025411 0ustar00celinemercierstaff000000 000000 #ifndef HEADER_MEM_HANDLER_H_ #define HEADER_MEM_HANDLER_H_ #include "fasta_header_parser.h" char* malloc_field(int*); int check_mem_field(int); char* realloc_field(int, char*); char* check_and_realloc_field(char*, int, int*); char* store_in_field(char*, char*, int*, int*); char* store_in_header_table(char*, char**, int*, int*); element_from_header** check_and_realloc_mem_in_header_table(element_from_header**, int*, int*); void end_header_table(element_from_header** p_header, int nbf); #endif sumaclust_v1.0.10/sumalibs/libfasta/Makefile000644 000765 000024 00000001032 12551723264 023101 0ustar00celinemercierstaff000000 000000 SOURCES = fasta_header_parser.c \ fasta_seq_writer.c \ fasta_header_handler.c \ header_mem_handler.c \ sequence.c SRCS=$(SOURCES) OBJECTS= $(patsubst %.c,%.o,$(SOURCES)) LIBFILE = libfasta.a RANLIB = ranlib include ../global.mk all: $(LIBFILE) fasta_header_parser.c: fasta_header_parser.l flex -Pheader_yy -t $< > $@ dic_parser.c: dic_parser.l lex -Phashtable_yy -t $< > $@ clean: rm -rf $(OBJECTS) $(LIBFILE) rm -f *.a $(LIBFILE): $(OBJECTS) ar -cr $@ $? $(RANLIB) $@ sumaclust_v1.0.10/sumalibs/libfasta/sequence.c000644 000765 000024 00000023010 12551723264 023415 0ustar00celinemercierstaff000000 000000 /** * FileName: sequence.c * Authors: Tiayyba Riaz, Celine Mercier * Description: C file for sequence reading and parsing * **/ #include #include #include #include #include "../libutils/utilities.h" #include "sequence.h" #include "../libfile/fileHandling.h" #include "fasta_header_handler.h" #include "fasta_header_parser.h" /* * Function Name: seq_getNext(FILE *fp, char *fieldDelim) * Description: Gets the next sequence from file by calling another function, passes the sequence * to other function to get the header elements and nucleotide suquence into a strcuture of * type fastaSeq and returns a pointer to this newly populated structure. */ fastaSeqPtr seq_getNext(FILE *fp, char *fieldDelim, BOOL isStandardSeq, BOOL onlyATGC) { char *seq; char *header; char *strTemp; fastaSeqPtr seqElem; int seqLen; seq = seq_readNextFromFilebyLine(fp); if (seq == NULL) return NULL; /* Find header separator \n, if not found return NULL */ strTemp = strchr(seq, '\n'); if(strTemp == NULL) return NULL; seqLen = strlen(strTemp); header = (char*) util_malloc(1+(strlen(seq) - seqLen)*sizeof(char), __FILE__, __LINE__); /* Separate header in header variable */ strncpy(header, seq, strTemp - seq); header[strTemp - seq] = '\0'; /* Get memory for new sequence structure element */ seqElem = (fastaSeqPtr) util_malloc(sizeof(fastaSeq), __FILE__, __LINE__); /* Parse header and assign values to structure fields */ seq_fillHeader(header, fieldDelim, seqElem); /* Get clean sequence and assign to structure field */ if (isStandardSeq) if (onlyATGC) seq_fillSeqOnlyATGC(strTemp, seqElem, seqLen); else seq_fillSeq(strTemp, seqElem, seqLen); else seq_fillDigitSeq(strTemp, seqElem, seqLen); /* Type cast the char * seq to void pointer and deallocate the memory pointed by this */ util_free((void *)seq); /* Return new sequence structure element */ return seqElem; } char *seq_readNextFromFilebyLine(FILE* fp) { char newc = '\0'; BOOL seqCompleted = FALSE; int length = 500; int32_t len; char tempstr[length]; char* buffer; if (feof(fp)) return NULL; newc = file_nextChar(fp); if (newc != '>') ungetc(newc, fp); buffer = util_malloc(1*sizeof(char), __FILE__, __LINE__); buffer[0] = '\0'; while(!seqCompleted) { newc = file_nextChar(fp); if(newc == '>' || newc == '\0') { seqCompleted = TRUE; if (newc == '>') ungetc(newc, fp); // Make sure next time we start from sequence delimiter > } else { ungetc(newc, fp); if(file_nextLine( fp, tempstr, length) != NULL) { len = strlen(tempstr) + strlen(buffer) + 1; buffer = util_realloc(buffer, len, __FILE__, __LINE__); strcat(buffer, tempstr); } else { seqCompleted = TRUE; } } } return buffer; } /* * Function Name: seq_fillHeader(char* header, char *fieldDelim, fastaSeqPtr seqElem) */ void seq_fillHeader(char* header, char *fieldDelim, fastaSeqPtr seqElem) { char* IdEnd; int IdSize; seqElem->rawheader = strdup(header); IdEnd = strchr(header, ' '); if (IdEnd == NULL) IdSize = strlen(header); else IdSize = strlen(header) - strlen(IdEnd); seqElem->accession_id = (char*) util_malloc(1+IdSize*sizeof(char), __FILE__, __LINE__); strncpy(seqElem->accession_id, header, IdSize); (seqElem->accession_id)[IdSize] = '\0'; } /* * Function Name: seq_fillSeq(char *seq, fastaSeqPtr seqElem) * Description: Parses the whole sequences for actual nucleotide sequences and stores that * sequence in the field of structure 'seqElem' . */ void seq_fillSeq(char *seq, fastaSeqPtr seqElem, int seqLen) { char* seqTemp; char c; int32_t index = 0, seqIndex = 0, len = strlen(seq); char* seqAlphabets = "acgtACGT-nN"; seqTemp = (char*) util_malloc(seqLen*sizeof(char), __FILE__, __LINE__); while (index < len) { c = seq[index++]; if (strchr(seqAlphabets, c) != NULL) seqTemp[seqIndex++] = tolower(c); } seqTemp[seqIndex] = '\0'; seqElem->length=seqIndex; seqElem->sequence = strdup(seqTemp); } void seq_fillSeqOnlyATGC(char *seq, fastaSeqPtr seqElem, int seqLen) { char* seqTemp; char c; int32_t index = 0, seqIndex = 0, len = strlen(seq); char* seqAlphabets = "acgtACGT"; int notAllATGC = 0; seqTemp = (char*) util_malloc(seqLen*sizeof(char), __FILE__, __LINE__); while (index < len) { c = seq[index++]; if (strchr(seqAlphabets, c) != NULL) seqTemp[seqIndex++] = tolower(c); else if (c != '\n') notAllATGC = 1; } if (notAllATGC) seqTemp[0] = '\0'; else { seqTemp[seqIndex] = '\0'; seqElem->length=seqIndex; } seqElem->sequence = strdup(seqTemp); } void seq_fillDigitSeq(char *seq, fastaSeqPtr seqElem, int seqLen) { char* seqTemp; char c; int32_t index = 0, seqIndex = 0, len = strlen(seq); seqTemp = (char*) util_malloc(seqLen*sizeof(char), __FILE__, __LINE__); while (index < len) { c = seq[index++]; if ((c >= '0' && c <= '9') || c == ' ') seqTemp[seqIndex++] = c; /*else { printf("Error in input file"); exit(0); }*/ } seqTemp[seqIndex] = '\0'; seqElem->sequence = strdup(seqTemp); } fastaSeqCount seq_readAllSeq2(char *fileName, BOOL isStandardSeq, BOOL onlyATGC) { FILE* fp; fastaSeqPtr seqPtr; fastaSeqPtr seqPtrAr; int32_t counter = 0; int32_t slots = 1000; fastaSeqCount allseqs; int32_t discarded=0; fp = file_open(fileName, TRUE); if (fp == NULL) { fprintf(stderr, "\nCould not open file.\n"); exit(1); } exitIfEmptyFile(fp); seqPtrAr = (fastaSeqPtr) util_malloc(slots*sizeof(fastaSeq), __FILE__, __LINE__); seqPtr = seq_getNext(fp, " ", isStandardSeq, onlyATGC); while (seqPtr != NULL) { if (counter == slots) { slots += 1000; seqPtrAr = (fastaSeqPtr)util_realloc(seqPtrAr, slots*sizeof(fastaSeq), __FILE__, __LINE__); } if ((seqPtr->sequence)[0] != '\0') seqPtrAr[counter++] = *seqPtr; else discarded++; util_free((void *)seqPtr); seqPtr = seq_getNext(fp, " ", isStandardSeq, onlyATGC); } fclose(fp); if (counter != slots) seqPtrAr = (fastaSeqPtr)util_realloc(seqPtrAr, counter*sizeof(fastaSeq), __FILE__, __LINE__); allseqs.count = counter; allseqs.fastaSeqs = seqPtrAr; if (discarded) fprintf(stderr, "\nDiscarded %d sequences that did not contain only 'AaTtGgCc' characters.", discarded); return allseqs; } int32_t seq_findSeqByAccId (char *accid, fastaSeqCountPtr allseqs) { int32_t i; for (i = 0; i < allseqs->count; i++) { if (strcmp (accid, allseqs->fastaSeqs[i].accession_id) == 0) return i; } return -1; } void seq_printSeqs (fastaSeqCountPtr allseq) { int32_t i; for (i = 0; i < allseq->count; i++) //for (i = 0; i < 4; i++) { if (allseq->fastaSeqs[i].sequence == NULL) continue; if (allseq->fastaSeqs[i].rawheader) printf (">%s\n", allseq->fastaSeqs[i].rawheader); else printf (">%s\n", allseq->fastaSeqs[i].accession_id); printf ("%s\n", allseq->fastaSeqs[i].sequence); } } int cleanDB(fastaSeqCount db) // replace not a/t/g/c with a's { int32_t i; char *seq; BOOL changed; int32_t seqchanged=0; int32_t nucchanged=0; fprintf(stderr,"Cleaning dataset..."); for (i=0; i < db.count;i++) { changed=FALSE; for (seq = db.fastaSeqs[i].sequence; *seq!=0; seq++) { if (*seq!='a' && *seq!='c' && *seq!='g' && *seq!='t') { changed=TRUE; nucchanged++; *seq='a'; } } if (changed) seqchanged++; } if (seqchanged) fprintf(stderr," : %d nucleotides substituted in %d sequences\n",nucchanged,seqchanged); else fprintf(stderr," : Done\n"); return(db.count); } void addCounts(fastaSeqCount* db) { int s; char* count; element_from_header* header; char* count_n; char* count_v; count_n = (char*) malloc(6*sizeof(char)); count_v = (char*) malloc(2*sizeof(char)); strcpy(count_n, "count"); strcpy(count_v, "1"); for (s=0; s < db->count; s++) { header = header_parser_main(db->fastaSeqs[s].rawheader); count = getItemFromHeader("count", header); if (count == 0) // no count field { header = table_header_add_field(header, count_n, count_v); db->fastaSeqs[s].count = 1; } else db->fastaSeqs[s].count = atoi(count); db->fastaSeqs[s].header = header; } } int uniqSeqsVector(fastaSeqCount* db, fastaSeqPtr** uniqSeqs) { int i, j, k; *(*(uniqSeqs)) = db->fastaSeqs; db->fastaSeqs[0].uniqHead = TRUE; i = 0; k = 1; for (j=1; j < db->count; j++) { if (strcmp(db->fastaSeqs[i].sequence, db->fastaSeqs[j].sequence) == 0) { db->fastaSeqs[i].count += db->fastaSeqs[j].count; db->fastaSeqs[j].uniqHead = FALSE; } else { db->fastaSeqs[j].uniqHead = TRUE; *(*(uniqSeqs)+k) = (db->fastaSeqs)+j; k++; i = j; } } return(k); } void calculateMaxAndMinLen(fastaSeqPtr* db, int n, int* lmax, int* lmin) { int i; int l; *lmax = 0; for (i=0; i < n; i++) { l = (*(db+i))->length; if (l > *lmax) *lmax = l; } *lmin = *lmax; for (i=0; i < n; i++) { l = (*(db+i))->length; if (l < *lmin) *lmin = l; } } void calculateMaxAndMinLenDB(fastaSeqCount db, int* lmax, int* lmin) { int i; int l; *lmax = 0; for (i=0; i < db.count; i++) { l = ((db.fastaSeqs)+i)->length; if (l > *lmax) *lmax = l; } *lmin = *lmax; for (i=0; i < db.count; i++) { l = ((db.fastaSeqs)+i)->length;; if (l < *lmin) *lmin = l; } } int sortSeqsWithCounts(const void **s1, const void **s2) { return(((fastaSeqPtr) *s2)->count - ((fastaSeqPtr) *s1)->count); } int reverseSortSeqsWithCounts(const void **s1, const void **s2) { return(((fastaSeqPtr) *s1)->count - ((fastaSeqPtr) *s2)->count); } sumaclust_v1.0.10/sumalibs/libfasta/sequence.h000644 000765 000024 00000005505 12551723264 023433 0ustar00celinemercierstaff000000 000000 /** * FileName: sequence.h * Authors: Tiayyba Riaz, Celine Mercier * Description: Prototypes and other declarations for sequences * **/ #ifndef SEQUENCE_H_ #define SEQUENCE_H_ #include #include #include "../libutils/utilities.h" #include "fasta_header_parser.h" typedef struct { char* accession_id; // identifier char *rawheader; // not parsed header element_from_header* header; // parsed header char *sequence; // DNA sequence itself int32_t length; // DNA sequence's length int32_t count; // abundance of the sequence unsigned char *table; // 4mer occurrence table build using function buildTable int32_t over; // count of 4mer with occurrences greater than 255 (overflow) struct fastaSeqPtr* next; // next unique sequence for example BOOL cluster_center; // whether the sequence is a cluster center or not int32_t cluster_weight; // cluster weight when sequence is cluster center int32_t cluster_weight_unique_ids; // cluster weight when sequence is cluster center, counting the number sequence records double score; // score with cluster center for example struct fastaSeqPtr* center; // pointer to the sequence's cluster center int32_t center_index; // index of the sequence's cluster center BOOL uniqHead; // whether the sequence is a unique head or not char* columns_BIOM; // to print in BIOM format int columns_BIOM_size; // size allocated for columns_BIOM char* line_OTU_table; // to print in OTU table format int line_OTU_table_size; // size allocated for line_OTU_table struct hashtable *sample_counts; // sample counts for sumaclean }fastaSeq,*fastaSeqPtr; typedef struct { int32_t count; fastaSeqPtr fastaSeqs; }fastaSeqCount, *fastaSeqCountPtr; fastaSeqPtr seq_getNext(FILE *fp, char *fieldDelim, BOOL isStandardSeq, BOOL onlyATGC); char *seq_readNextFromFilebyLine(FILE* fp); void seq_fillSeq(char *seq, fastaSeqPtr seqElem, int seqLen); void seq_fillSeqOnlyATGC(char *seq, fastaSeqPtr seqElem, int seqLen); void seq_fillDigitSeq(char *seq, fastaSeqPtr seqElem, int seqLen); void seq_fillHeader(char* header, char *fieldDelim, fastaSeqPtr seqElem); fastaSeqCount seq_readAllSeq2(char *fileName, BOOL isStandardSeq, BOOL onlyATGC); int32_t seq_findSeqByAccId (char *accid, fastaSeqCountPtr allseqs); void seq_printSeqs (fastaSeqCountPtr allseq); int cleanDB(fastaSeqCount); void addCounts(fastaSeqCount* db); int uniqSeqsVector(fastaSeqCount* db, fastaSeqPtr** uniqSeqs); void calculateMaxAndMinLen(fastaSeqPtr* db, int n, int* lmax, int* lmin); void calculateMaxAndMinLenDB(fastaSeqCount db, int* lmax, int* lmin); int sortSeqsWithCounts(const void **s1, const void **s2); int reverseSortSeqsWithCounts(const void **s1, const void **s2); void readSampleCounts(fastaSeqCount* db, char* key_name); #endif /*SEQUENCE_H_*/