sciscipy-1.0.1/0000775000175000017500000000000012212711357012446 5ustar vinszvinszsciscipy-1.0.1/COPYING0000664000175000017500000010437411333753662013522 0ustar vinszvinsz GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . sciscipy-1.0.1/deallocator.h0000664000175000017500000000055111354214673015116 0ustar vinszvinsz#ifndef _DEALLOCATOR_H #define _DEALLOCATOR_H #include #if NUMPY == 1 #include #define DEBUG_MEM_ALLOC 0 struct _MyDeallocStruct { PyObject_HEAD void *memory ; } ; extern struct _MyDeallocStruct _MyDeallocObject ; extern PyTypeObject _MyDeallocType ; extern void attach_deallocator(PyObject *, void *) ; #endif #endifsciscipy-1.0.1/sciconv_read.h0000775000175000017500000000231611403266052015261 0ustar vinszvinsz/* This file is part of Sciscipy. Sciscipy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Sciscipy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . Copyright (c) 2009, Vincent Guffens. */ #ifndef SCICONV_READ #define SCICONV_READ #include #include "util.h" #if NUMPY == 1 #include "numpy/arrayobject.h" #endif struct sciconv_read_struct { PyObject * (*conv_func)(int *) ; int scitype ; struct sciconv_read_struct *next ; } ; // List of converter functions extern struct sciconv_read_struct* sciconv_read_list ; void sciconv_read_init(void) ; // Generic read a scilab variable given its address and type PyObject * sciconv_read (int *addr, int var_type) ; #endif sciscipy-1.0.1/util.h0000664000175000017500000000111111405525204013563 0ustar vinszvinsz#ifndef _UTIL_H #define _UTIL_H #undef HAVE_STRERROR #undef SIZEOF_LONG #include "call_scilab.h" #include "api_scilab.h" #define BUFSIZE 1024 #define TLIST_NAME "__tlist_name" /* * This has to be defined when a numpy extension * is split accross multiple files */ #define PY_ARRAY_UNIQUE_SYMBOL UNIQUE typedef double complex[2] ; int read_sci_type(char *name) ; int is_real(char *name) ; void sci_debug(const char *format, ...) ; void sci_error(const char *format, ...) ; PyObject* create_list(PyObject *obj) ; char *get_SCI(char*) ; extern const int sci_max_len ; #endif sciscipy-1.0.1/CHANGELOG0000664000175000017500000000137712075506714013676 0ustar vinszvinszsciscipy (1.0.0) * Update of the documentation * Clean up of the Python code (pylint rocks) * Update the search of scilab.cfg: - current directory - ../../../share/sciscipy/scilab.cfg - /usr/share/sciscipy/scilab.cfg (like before) * Fix some C warnings -- Sylvestre Ledru Wed, 16 Jan 2013 12:16:58 +0100 sciscipy (0.4.0) * Update of the documentation * Use call_scilab.h include instead of extern * Match the declaration from Scilab 5.3.3 and upper * Remove some dead code * Add the --no-as-needed option to the linker * Thanks to Luca DALL'OLIO for the various comments -- Sylvestre Ledru Sun, 30 Sep 2012 13:46:46 +0200 sciscipy-1.0.1/scilab.cfg0000664000175000017500000000017111356456606014376 0ustar vinszvinsz[KNOWN FUNC] size : 1 find : 1 disp : 0 bdiag : 3 banner : 0 exec : 1 plot2d : 0 scf : 0 xs2gif : 0sciscipy-1.0.1/scilab.py0000664000175000017500000001451212075506651014266 0ustar vinszvinsz""" This file is part of Sciscipy. Sciscipy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Sciscipy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . Copyright (c) 2009, Vincent Guffens. scilab module ============= Provide an easy to use interface toward scilab Usage: >>> from scilab import scilab as sci >>> x = [1,2,3] >>> sci.disp(x) 1. 2. 3. With the help of the sciscipy module, you can also do: >>> sciscipy.eval("function y = func(x) ; y = x*x ; endfunction") >>> sci.func(2) array([ 4.]) Internals ========= It uses macrovar ou fun2string to discover the number of output args @author: vincent.guffens@gmail.com """ from sciscipy import write, read, eval from threading import Thread from ConfigParser import ConfigParser import os import sys import time DFLT_CONFIG = "scilab.cfg" SECTION_CONFIG = "KNOWN FUNC" # Type 130 functions do not # work with macrovar so their # output vars is hardcoded here __known_func = {} class ScilabError(Exception): """ Define an exception class """ pass def update_scilab_func(filename = None): """ Look for filename and update the dictionary L{__known_func} filename is a python config file """ assert isinstance(filename, (type(None), str)), "Wrong filename" # Search first in the current path if filename == None and os.path.isfile(DFLT_CONFIG): filename = os.path.join (DFLT_CONFIG) # Search here too: share/sciscipy/scilab.cfg if filename == None: filename = os.path.join (os.path.dirname(__file__), "..", "..", "..", "share", "sciscipy", DFLT_CONFIG) if filename == None: filename = os.path.join (sys.prefix, 'share', 'sciscipy', DFLT_CONFIG) if not os.path.exists(filename): raise ValueError, "can not open file: " + filename parser = ConfigParser() parser.read(filename) if not parser.has_section(SECTION_CONFIG): raise ValueError, "Invalid config file" items = parser.items(SECTION_CONFIG) for new_func, value in items: __known_func[new_func] = int(value) def run_scilab_cmd(cmd_str): """ Defines the Scilab start command (with error handle) """ new_cmd = "_ier_ = execstr('%s', 'errcatch'); _er_msg_ = lasterror() ;" % cmd_str eval(new_cmd) ier = read("_ier_") if ier != 0 and ier != [0]: lasterror = read("_er_msg_") raise ScilabError, lasterror def find_scilab_type(var_name): """ Find the scilab type of var_name @param var_name: name of a scilab variable @type var_name: string @return: type(var_name) """ if type(var_name) != type(""): raise TypeError, "var_name must be a string" run_scilab_cmd("_tmp1_ = type(" + var_name + ")") res = read("_tmp1_") eval("clear _tmp1_") return res[0] def find_output_param(macro_name): """ Find out the number of output param of macro_name First we look in the __known_func dico to see if we have a special case for that macro. If not, we use macrovar for type 13 functions. Otherwise, we return 1. @param macro_name: the name of a scilab macro @type macro_name: string @return: number of ouput param of macro_name @rtype: integer """ if type(macro_name) != type(""): raise TypeError, "macro_name must be a string" if macro_name in __known_func.keys(): return __known_func[macro_name] if find_scilab_type(macro_name) == 13: eval("_tmp1_ = macrovar(" + macro_name + ");") eval("_tmp2_ = length(length(_tmp1_(2)))") res = read("_tmp2_") eval("clear _tmp1_, _tmp2_") return int(res[0]) return 1 class Functor(object): """ The attribute 'name' is the name of the function to call in scilab """ def __init__(self, name): if type(name) != type(""): raise TypeError, "name must be a string" self.name = name def __call__(self, *args): """ TODO: add a named argument outp=... if you want to force the number of output arguments """ cmd = self.name + "(" in_args = [] for (i, arg) in enumerate(args): arg_name = "__arg" + str(i) in_args += [arg_name] write(arg_name, arg) out = find_output_param(self.name) out_args = [] for i in range(out): out_args += ["__out" + str(i)] if out != 0: cmd = "[%s] = %s(%s)" % (",".join(out_args), self.name, ",".join(in_args)) else: cmd = "%s(%s)" % (self.name, ",".join(in_args)) run_scilab_cmd(cmd) if out == 0: return None res = [] for i in range(out): item = read("__out" + str(i)) res += [item] if len(res) == 1: return res[0] else: return tuple(res) class Scilab(object): """ This class can call any scilab function (yeah!) Just instanciate an object of this class and call any method to call equivalent scilab function. >>> sci = Scilab() >>> from scilab import Scilab >>> sci = Scilab() >>> sci.zeros(2,2) [[0.0, 0.0], [0.0, 0.0]] >>> """ def __getattr__(self, name): return Functor(name) class ScilabThread(Thread): """ Defines the Scilab thread to start """ def __init__(self, func): Thread.__init__(self) self.func = func self.daemon = True def run(self): self.func() def scipoll(): HOW_LONG = 0.1 # sec while 1: eval("") time.sleep(HOW_LONG) # Update the dictionary update_scilab_func() # Create a convenience Scilab object scilab = Scilab() # Run the polling thread poll_thread = ScilabThread(scipoll) poll_thread.start() sciscipy-1.0.1/README0000664000175000017500000000473412075517010013333 0ustar vinszvinszThis package creates a python module called sciscipy. It provides a link between python and Scilab by defining 3 functions: - sciscipy.eval(sci_cmd) - sciscipy.read(sci_var_name) - sciscipy.write(sci_var_name, py_var_name) To increase the level of enjoyment, a python module called scilab is also provided. This package contains a class 'Scilab' that can be used to issue any valid Scilab command. Use it as follows: >>> from scilab import Scilab >>> sci = Scilab() >>> (any_output, ...) = sci.any_func(param1, ...) INSTALL ======== LINUX $ ./setup.py build $ sudo ./setup.py install Debian/Ubuntu $ ./setup.py build $ sudo ./setup.py install --install-layout=deb $ ./setup WINDOWS c:\Python26\python.exe setup.py build --compiler=mingw32 c:\Python26\python.exe setup.py build install To build with an other compiler (ex: clang) $ CC=clang python setup.py build To clean the build: setup.py clean --all RUN === LINUX ----- the LD_LIBRARY_PATH environment variable must be set, for instance to export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jvm/default-java/jre/lib/amd64/:/usr/lib/jvm/default-java//jre/lib/amd64/server/ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/jvm/default-java/jre/lib/amd64/native_threads/ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/scilab export SCI=/usr/share/scilab See http://help.scilab.org/docs/current/en_US/compile_and_run_call_scilab.html Ubuntu ------ It is not possible to set LD_LIBRARY_PATH globally so you have to create a file sciscipy.conf in /etc/ld.so.conf.d: $ cat /etc/ld.so.conf.d/sciscipy.conf /usr/lib/scilab /usr/lib/jvm/default-java/jre/lib/i386/native_threads/ /usr/lib/jvm/default-java/jre/lib/i386/ /usr/lib/jvm/default-java/jre/lib/i386/server/ You also have to define the SCI environment variable in /etc/environment : $ cat /etc/environment PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/b in:/usr/games" SCI="/usr/share/scilab" WINDOWS ------- must include C:\Program Files (x86)\scilab-5.2.1\bin in the path and set the SCI enironment variable to C:\Program Files (x86)\scilab-5.2.1\ TESTS ===== To run the tests, the command: PYTHONPATH=build/lib.linux-x86_64-2.7/ python setup.py test should be launched. PYTHONPATH should be set if sciscipy is not installed in a system path. Coding style ============ The coding style is done through the command: astyle --pad-header --suffix=none --pad-oper --indent-col1-comments --indent-switches --indent=spaces=4 --add-brackets --formatted --style=bsd *.c sciscipy-1.0.1/MANIFEST.in0000664000175000017500000000015511403266052014203 0ustar vinszvinszinclude *.c include *.h recursive-include tests *.py include MANIFEST.in include COPYING include scilab.cfg sciscipy-1.0.1/doc/0000775000175000017500000000000012212711357013213 5ustar vinszvinszsciscipy-1.0.1/doc/tutorial/0000775000175000017500000000000012212711357015056 5ustar vinszvinszsciscipy-1.0.1/doc/tutorial/fig/0000775000175000017500000000000012212711357015623 5ustar vinszvinszsciscipy-1.0.1/doc/tutorial/fig/plot2d_screenshot.jpg0000664000175000017500000043667511352504626022016 0ustar vinszvinszJFIF``C      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?4xl,~"?xK.1~{%&ǂ ?zƯh< ]QCݔr[@IV!].d_-Үfd<=%h7$LHJnj[]ihhM}wW^c$|6 !; > 2!׹gyKdՍeOBMԧehy, oq\,Hѱhbe5[/ϊ;;WV.o%0^5j\B'XҔ2ϖZwKOѣGF魷ϱ?8 !VuM6>*?|^|S5/ {F5kA'4-bc"2T]g|ȱ7#t:^})y#sqh7IZmae[[_RZ[ϕ:zUqJ/l<=To[?? cɏ '_|#:CnnoIj. x\UiSx7?f?+q6V{iWV7p1 Z."O?|cGE&KrQ[Lp\P[{[]^27~/Eq{I^ ^*r w;S]uh%;Hvx"r oR~:_7.ӭn[2 Wgv䌂Nu鶧+BJI5o>򋟄r߆g|,tÿ^t7Ś|u.m7:mh44[+Q[/,7Io '!0FwW^ߞɧe>L<;UV_:|;6?whv.:5o߭6 UЈy6D"6nIm8CWڤ̑,yQC#ʑy# ̭)׿kF/S:|=7ÿQ?æ?O~ ^];[Ѧ4Z..c,:Vddwxᧅ/5rxl4 4΅KTUPYت(,ʪ  M+:Y?|K94i5/5s}ex{PnFQ_\,SD]wwk⿇^6q-4/x*Ai> ׁ;)kvl3k7&ѯTTߓ[[o_y|g =~_Aở?wkޯ>.'L{y._$m+[xij 01o ܞ&wZ>{ƞ5ˋG+Fy,0@$$%c(lUi|._ZzɻEKo]>O X>7ÿN_5*~П uo4Mgo{e_XX[O3\kX<S? x&mq5%I6^4"dExx2+H +;|ӳIsof_BI5>&|Y'MZƉ-o@έciiךDVf#K4ȓD0\:pn GgǽC\L5O _Du=?^ΧhDfI'1D"YB`&{|}]]zϷD}8o s ? _'?sk7ßN_.|_AtǏ90Ok;5iN_AO ?k!ŽS&[qѳ1Ȃ=3\8X etu\c_]"E7dYNmnӮ4Iv8匔taUAֶ[]-O׭X?sj.3ß]_<<9Eh4iYcB6,B3ßX %\_l<94}!|_AdƖ`ȅg ???k95+Q rzӰƶd/?k94ڞ3ßXr)Nm/sigd/?k95Nlٟ ԋ/~ ,u?xsi|_A03K8 7WŚyH*I6*=qORAĺS*<a7;0L|:?ʼLHV6:>*|* X|D&~*3q?zJ .k\D*UT"Bl8eB3Vg[ j{?.vבb;qֽl5јUOmgGgC m > :-uC ճשc׃$i^ |ggCt@:A$HֽcthȁBٷ9*#Mݏk_ٯ#CZֿe>!_UeXȲ(u2 S ◁ti2|('ĺ亐_b+?"vifU򞣌{j 1AQ*r@ϣu/>~CfVS[ǘB.J1^RG4bўe?M|煌\/x}̪Յeʣyɟk|<3 6"T7O2cnEKټ>xXܥfR,i5 +n0/H|iS@PoQ,\x_n[VQna8=E"&ΎyЩ)Y~ļe3aM6Pm^#~/4 ڏJ|le:y Z8лM PXȖǾIqg?]+?l.o?4>ox kZZ3V Jdۙ"mK4SA/"7%*4e'&5~[я -xU:q$kiuuۦ}!m|:kDfWD @ +~3_<1ݧn4mLPVƶ#XDV,yſ{woGu~n֋F8͹_Ze NKNR}OK{N \][*AdV l^#φ;ҵ u9cnyRkk< w3E}E R{_o4*z +KϦ4z҂>|0'Iz?go cI"4GsuY> | Y뚝Xu}kP("H.s%3*[c~:<Xk:|O&_Xo[m3h!2Tv˓Ww^ΓxR{+ uKœG#'cT]$t i{i ZRm7]:&?|/$?Lu'5?m]jNyqMjEOaO-ln!cN׋q0$sfMz %aԊ/30[%UW[r0I+Fm d0> $.O-]^\zncF4?|1#Ij}WaYx{5Ij!L!M(;pc|_^͇K=R촨-n [HG)3!W#xUdfQދVOi_W#'>4Fs?5/ţCƲKuuZDŽOmM.ⷒ0k#UrT}PYAѯuGqOwyX_h[̒uwT|- aH([%R/]5[[mB)uooE?eF՟?|2$i]IľѴ/miRZc^Y-&2ʞ#ms>+ZN|E,??ZZ[[Kykr3YYB) FZ׷LҊބ\}яP $iYhC"/!rF( [\Ve8crh#|2#Hj`>?GgFmY:V14VdDiChDy'HjS`ШV?GgFæcdDiV$`*w;AhDȑ#L G#Tr_GRuHt>56K G wY;!葎<܏5eK&$8_<FWs,fXϊ=ĭ7~ ԏ5T"_[ ?G67-i:}k{Jbp~ڻnaR|$Ҽ[ > jx>թ{6| mf-*5nkj֫N'J%CgZZl1R.ȵe++/q"6ȵŏ iQŋ8T ~}QΎK> -)K&|3FZqeh:9E:X&|3FZ>եЙmj#lhҥ=ĿjLg6"M g6Z.Uiߥ 5> -HۻSŐJEBJ?%3Gj? K xcI$Hȗ6_ ֤ ERQ՟F'D_ChV!~ 5R _үZY5ؚ84fXGj;->FCi5jvտere6jM1>g]D􍭶m0)+lH_fIamr0ȦHMj7¡s39@?RȵRO 0 Z/"Ծ:[Xk՟z.uY4AK?"pl+gtɟ_(υ T ]jILLE?Q[c6N/~g#.ѳ1&ؒI$}kZ@RKd! \؃+[ IOl;ӤUgx ?4hu ^Q^\r22X><?~8:g. $ {xN^ F sNß noxWZ?nIh)*l\nb v՗ *Tt xAZs,9XX DnQpI6Tdq  gm}ۏ 8GkoJ+c?m}7<ku :}bO-nbrX3~ԚŻE|Yx:`mb-֯vV+(ΏgZx{E|q4v7׷^^z8Eit@s-pkxP? 3c5I O~)7{^)76K4[U`---{Hb"HcVUχ3^ x03swKOeYaw]F4lto)7m+GNG$֍qG$Zy_uХhze7ĺm=ciu4eDBL^[Hqrk! |WL㼲7 H vܻl"T mp OqG1G$Զt'q? "1jKu޷;+-\^K$ו웶_r'֋ᇏ5Ϗ񠙬r4蠾SV+0O]u Ӵ-lum[tPV;J s}~;xyG?~kE\?|:>iEsΜ$Z|-]a6JIi&_KY6߰Dt='7mGw$iDJ-P1l1xT/]\č'P\ hdhr%wkz]\LcHUE?xJ䊡sE߆M++YSךwQQI--nY;++-j<>x[<9-90Ze;!xQ|`&F 7^/#[O'tƹKKS-"YgdcvMǭ1_ΚO$Vu'nO/|,߳>gV Gڝ麟$5=Ne qA#yUIGbF FCNJ~mMW~'H~IW3\o=g>3Zi+yA}q:{DQe[x̾dWpRIdм/,v?s[sy4 x~M6;,w:YHW?7TωmkJHPZӶ-Em=7߲5=c-OBt.O1+(Bc!#+O? c|C'u/u׈)G$˶M#ji_[zhm)EE쿯뱻-cmwik=HJVl%+wVm] |^x;U }.(ty ˲v#8 Y|Č ?-ŧaҦ/7WZQY"L6\W >IpuCW?&\oIl{ω.xŚg%͝>t).$vF$BaW3+~^ޓ?>ѭt  [kŸ[XC!#7,;iM 4Ԗngk},R2}Svn|5mC^0~ӬRZ^Y=7W*+ Jև^E<[e jHtl\Id9vW6ퟆgd!-4IW͹5w{mdLҜ9j^w;c_ @v0<};^R_ Kφ>(ԯƝ>soèđIqgr1O1bʑQwCW?&5iMWZΤr?ihͯ~.u%KM#jG$ F3[rxEd}5Vox?$SA$hM'|>Gd~ry-tI@eZki|H?$?x?$ӸR#Q|>G䚷o>#}4i8ǘZ?>kMd&<fOZiKb M#in@~/~kѫ>iMz =&PfOG-$+Mغڝ/^ckgrIqFN<_K5}>yUE|lRǥne籉BǃXm>礏&EI~c?:i_GEGlDtΆQrMjYX5kD?-4IU|S M#kڹtz~^G5FUΚG$֝;:iEk?WQ\jw2^Zxykxn%rIn#72#TmFŇA^_giq(ό>4Id Bu໊s:TDM+*e.?g͈ӯolcfxϖ aPᓏ.}S87_C?q%J_X'?~iEp޴./GA uSGď? ҿ"?1Jq0 I vrK"hP\Aj}m ͞'^&yE"dA3t$8Zljh 5.& `kf vך9𮥨Comφ7,qCW'UEI'&g^"fsFoZ+VFACJ夬#bqrSɮċ]WÖE$$ʖ2 r3g MNJ|7h0YQiVXdkY&*m6Ys?x SZBϦpP`66_|#%F`uA%ͫV uk}nJRJU$ݿߕZ+/xGOof4ٵM 3Ew̬cp iy7>c5Į"f;(Uǣq>?뷆uV{l15˪“kkɧ;oQ=eM}kqVG˟b_t/x櫪NѧKmLҵd`LQ+Px[s:ΡOxzw&յƥr,eD!8R$HcnP,_<>G_|]>|Gt*-w/"{ĕ֚[f6%ןCs\%ͮlW[QQDx]$, q_ M2Y r+KkxʌBĻe|GC7gN # ꧞-ryRrs{_c/ 5?]爛#P] n>\ʰ - w<=uZu𛴓\ZH\b0Gڱn^%9z>2wI !-_]pRO]+}VekYrZv?w?c=[M+>?溹[Ew #¢T@q:20qouWuO *\_K;;ݿͳQK~mž84 j^Zk^dF3۱V&!1U]v7ڬZIk 5i^)l Z_}-.FI_'P?D8?~2wNN܎2U˔+hH~Κ.C=/^25kb;.{2c iS˞X3dF1l!X٣D֗wZd7r]ݬ|ɽ7+>|C?'EyxoU1#dַr߯=|uwxU]bRaiokªv[Fprw|%|A)-u[zV#QNY%xO#*_l'@?|CCqr<<7˪i_dZeoD>w6[3|M4 +Ns^qq.;+|A7˪Vn=x>1ֽ3>-_ M8u.h)X e|Y_ ?L?$:}oTxub~GoT-_Gð,:}oT_Xo_ ꟷp>gyY'޾]X׆uNKߋiùQhT)_8⾕Ki/,cImPt WG w`:}oT??&H#oTZWbl޵n#Ur>R:k ^!t>#3x?- !Mx?#sW԰ʜ$|3RߊV%{_GU7oZDtF?Kz3[$3ʸ=Mg^?#Nş󇏦V1떯o.>A'n?xoF5&wōBvq'?i?q$`(]QZ|/>,_ .~,_ WR=d|-m_N%Ł4]Ӈu..d|Ȗ2X}.K|A7˪?iGBX;_L&_a4]QD]TGQڟJl=+EfUN~ ~=??9}oT/͋nMm3_M'_s.ӟ?߇?uK!uicҤK_Jõ)IßlSs.]D˹V=*V0m|Ss.Iß̃w>~/ӵr(_6 ]W9_%YH7˺#5s:qY5$ cƷm ޵$2>Ak_Y&>4[IW Jv՞4UgïZ['x^qz'C&;q߆w]% ?~!M|7˪龦UWC έ5WfC ̥d 7BWr68 ) 0A_??uWmb7uPsE;nތ~A^cF?_ }}^φ.kwM&ّ6KqZkTSDާrGf!^}sAV:ƊN53=ߏ&"td>$ſUDssDc<3hR&T&<=?,+l (5OoҐ #ckU.$7׶QteE#gQSMcy  >#o 4={k[y<|U៉ QQNZkPuZjPX3 F?뿋$~).VO-}c2oQSƨ((((((((((((((((((((((((((((((((((((((6S_sxQNG_🅮]VLI//onX- ,1 31I8 !wS|7aKߌoEť]ioiHZv(-4[jVV{vR:[$Hg0((D`㟶,|E%K|,pckp\uAm,p@ k/ڇt}O@ƿh;/8th[I%X$|^O C-Νi 퐔P`2+ wඕSAK GD&]z=/nو$]Y򃃇EyO= < ZA;{EbbgЬg @wex; _΅E姃&a[l]d+ "*x^ 5 +Eek$ֺ]6*+ 3$hXnv 3k3ǃ<74k]sÚEpU֒}1Ȓ .w+1zO|Em+kQXGi7znuA9'Cr Ta'Nޝ7N|4Uke^~#?f#Zş _~Y񋵝~[|_KػZRWK򽵵ޟ]f}ޏ{>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl>Yl+3P'}ŕơgA[쑢A <Fj?ǿ ~-[ڄIk3ꗷN# ,~,m*, ~muy#RKh71%ݤWvI JYd0 _?]E'vQZ/঳ck Gum` ?A~3🀾 V3E/ZzӨHK6nKe,ʾl5l;:?|s-ůo7WP$Nve\K?;f>yx[ 7qs;Elmd"hnW a6dx| 3ywNѬm俿w$Zh4 ctp>:( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>h?5?뇈˰H?ueǤJ(W huچSHҺ_ &-sH'|`lMU-π?~/NMT{MfBtz=~|gt} jM&/ >E~x߇xz;sQ[D1+pq*G q8L73*QVj(I쒻"jT8i%{ݿ/%U>)LԾ7i:6qyye[KXiښG (%(O P߃i|?.\mn >@F#xT%8D9} wdQP[ ;،;T6H *X|O{{mCM˺c,H;XeXd6$r"`rwĕNq:[_ z# r^3OUzկ>Kk+#\ãi,W8!%e\m jv8BS|Wa)$γgue`mCiqH[AWXRS;#vz)__,^%nf̴֚a +%T.C5bvVNN9ӓD]Q拺;/{Ώ{β\W<aͨU@lle=G=Yktqq_]j}~t}~u>@lle=G=Yktqq_]j}~t}~u>@lle=G=Yktqq_]j}~t}~u>@lle=G=Yktqq_]j}~t}~u>@lle=G=Yktqq_]j}~t}~u>@lle=G=Yktqq_]j}~t}~u>@l(  Ӯ>ۣ_ď?5kiP>eTt+eޠ"j L_ڏŏuB\źkhՔR$2um8Dq|P?d 7~P-!hpKv42"I%("4w;U>=O~j>&heKYTuwIf܍clW͙f`ͨX^-5[FƁYJm(BC,wZiFG # ~ōS?c +ueFK7@ c^?O_o_P-f{R]ߤa%Or7%e_6eJgោ> 9ZqzO7MͧX;bp%̝tQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE}k;a+4h?5?뇈˰HP0? o!O!f &-sH'W¾1h\55Ka3? e}𶭨u%vV+Aʨc,@(^UWiƥG[CmjD`jdb(Wq0hC|͵1\[i$SX _OVZh:8ټ"aMa@;y$HT 7ar-9ťvӵӶZϞrF6()/d䚽Shr/>:o1{KJG}6AѶ# A"Ɓ*dp<` gO\O}xkOѾpۧiC$EpI,c,NXZ~o _kE{.,ۼRVH䌈Ҩ0??:~ľ-^7Rүo;[ 0."=\TWͱJSԩ96V?+zvZjǗ`#<2QˢoN[NezzgğIQQVJ{%Fz\}'+gG㏮+~ŧ_>7_IZJb6蠳LnPIl W`ׇ~Jb:k4f#Y(.Qǰ}@@SX|}_ Bo]%I,{ŕZk`Q@'>[9~˿| _<0YMb[4# &Rٕ9\-XOpe{Zq-Ԯ"5?3+ {[:B&gC!KP l}ONCN7 Ck^߂>B4[]ODq o|[u.^kxu|@ɪh)G1LZ [+п #{+kkc,j$a'>~>/aMSV{yָ=]#Zc?p.WXJ9̲~HGz]E6NKe{m b+_僗,uni_|m{k y?n[xZ׼+i[B /˛A%Ѳ7Luڇ[a mH/(j_h+WR%왖MK]> RIO:De$*6itӡMNM{ٮ=b*)vxn Xj\o_="Ec7'C$@Ȱ_W _՗"Nu;XԯQV"n*int|K@54_'oD2Ks:ZCdu(1 w_ld7v-;+pS 5ŭ; JϵjOk5G}6P`x#/5խ]4FI\z?#ϥt:~CVZ綆+g̱[G);# #/&]ZY-,5RotkߧH[|Q9VZ_K<^%? ѿnSךk4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sGes@k4}_k4sEe@sKM?&Zf?[+wt !Z)P2+# +yx[ 7qs;Elmd"hnW a6dqj |q4H=}kˤK.&״ϵi֊aijBedޠ-/~^Y!څuX5)]MHeM1p:0 v]E'vQZ/঳ck Gum`%?Wϋvg^o%ü 8֘A]0c>[y<|U៉ QQNZkPuZjPX3 F?뿋$~).VO-}c2oQSƠ?EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPݿmpYvҿ?6E WuݕQmDYO_/0ڴ#}r_P=|xdG 9vȹ3~-4z|K|}lt?ڧWc1>_3=3Lǯ&OdkMfB07S)){KEmĞLx4q,ZՊ+{O|2Cr^^|/u|#ݔY qӁZ|b&Ym6Dumo"<.02H$ a~"_}!)!()II :H]szK3Xߏ$d^h:g;^[ѯ SĖ{x{?-yLopr+6R޳au{/.m<qrq6##ƊW'2].+cO>m PԵu}yN.#eT[Uԙ\4d+7~?h-)k~z_gkE72nUߴ?_|?hvZ~9 ݋9ڒ[j x6Wqj[RI`uvy`HS^xMMmGNMBEDxP7(2Gu{x6F7|[I% 2ēf2˃W\)ӕ q~6H|z߉o,?a\^K-z>!uY|`+IP2]jG4Ix_ou/ڇCs<7ymi^Y줺YYG@{?zxt|3MᲹ2V/%+uY[]L#>)־'O~#׭8uAcy=S,$SK$d#$g/ps/g>+u/_ DL>#/_nS7o@Ek'W>|%e$~֮.|Y$SçxvmKNOY)S{rdε (D76xS_MR~jn5O]&{u=ջ0&gf$5 |Qy G=9t}[SZMbvY>q*bExFYc5 sE6+뻴5&(9X# ]oPo NJ΍⋟hj){-suhMo؆&Dy~S\t߄}}cYVAupx $rYd% m|C~\}燼Yyϵi֗w;dMJYk8er'NW/x0bOj>$2w'OY'kgxQI&rdiefBwvf>\w >ol4}\nVYY[Amgj8HTEPU@|C_gROYJ;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3/k SC:J+58??r? *e>=;\_3e>=; U w,W6xoV}P>eſ7 xwe;OU៉ QQNZkPuZjPX3 GR =sm="[뵕쑣UDJQDhvOA~3🀾 V3E/ZzӨHK6nKe,ʾl5_W~&x/mGLjt}G:iGB54 jWSmBcLj68>H(ao>&xc׮,j~^`[?ĶS/5rYj^XUEO/df3ǿ ~-[ڄIk3ꗷN# ,~,m*, Sh ? !_̷ÏwW#`?~! ]@nm:Es,d,w??iv?TKj ;xsdF<q7G6HV6v_ 7oy[?Nq{1٦H>kywȒ@~W ^>?>x῏?Y'yj I "6H揕u', #x>?#4cf"; YXI5ݐge`ty^i_1^?o+?į7[x\:ޛk Kcմ)ǎBSݰ~~Ilo5MWTi$qG(U@5~/}j&izĞ'SKc$RT0$(A[3Fץkm:5ŝ͕\#Q#7 Q_TC?:_ :vs>ymJau2\[w*F^{t7#ېWhtW~>3yK7[ ]3PYc"07G{?$/B(UM w5+߆ٍm^4G[[vDb|_@~MBJӭԋ3ȱE*FX s][(jguxŗ"sTk. WL+@м9 mGQ`'(XR butrn"j} C֓ ፏ/l-‰jos,6M5ʹ1<,1H|7E~Oj>?֣{ |Hu4u3qmQŠ-GvnҔ)o~?[wR_;JQ{a-قM4< FDp"|EzG;uO%5W9￲# c}wޛJr$+;x~_ h<xRaeK$z eoI k?+ʁ^/@a{*?E' K>~+|~.v^NkΗ_RP o̞?yE+u^e~U-N4 -_Y9[wMM&$ٚL=K0~W_N~F?w$gů [Z~LNkɗ74dqR 2Ś ; mCSqtvYF`k ʡf?E~|NxxgƗZ=O |PXj6ZrcK] ʷk D'٘$V /rOKfs׾\xGvce=HV3IosE5ŴR$ 2 #YLQ}( l؆\_#xvp}㶒Hn&HZgeHբE5,|3#]}cǚxij3}I5=5.%/lm *"u&xqg~"[-: {-ݭ.Ys,)$aFeu ||}x;5 nKa藗CGx朵ż&T(b,"vy$Oď:oýS׃m߉^ zvfچios\ BY!X`o29u {gCo[>3ާ|O >%ڠӊY k2mx 3_`WnS\[cxTѼ?"MJ°7g5Ai58-%uy<~ۙv$X??&ৄ~&<|4wqVa un|M-L>&I$P5=>qukWUWՕ~?l|rt?6ܲI"R҆uVz,:U_w#W<y.$گ"m~񿁾|"߂Fm}k노0tiT!lʑU9+8Կg.5{⭼BDkZbtp\nAۀW~&x/mGLjt}G:iGB54 jWSmBcLj68>H(ao>&xc׮,j~^`[?ĶS/5rYj^XUEO/df3Q_ ?|}? ,4/sow߻n1װ~пOPqK _~G>m$o<ٻf'kc91^Ne(5cBMiҵ8۹dApNa|*6{xo!]}oRkڴ*M$jp8D#?Ö0^f꺅{_$&n&s,G".X{C(GW,}%w:Y<5'G+1kQc6TQOM$|W*7\ܼ_xR>x[?W[77N4;}J6zmޝe4NFmO.6H#.}{ƩYKO&@֑#<=goc{O6Iu50?g`/ڷI{xfSE.\a[Mm紿xhGjU>Yz_WKxVPkEn/[`&gPK ) x K?zT~;Ak[ ۩V{h$EY-MlZz>,Qu=ƾ IEMB6kH-6aR[c *Hy.4wGJu$]M%W#r #IVC-=}f> Vƒ=4c5'3Mfu_ƯiMoLIs䐝ҜFDAUm;L| '5om. +} ͭ5JZ$":D:ϊ&ho|Iy _\om(ꏦ#IHn*0]~úsRͿ|CR$9mťC<[Oq?LHR 0g1y'ɿ d/j>4/Hu=C@;%s5YH2-qOo~,b=BoG}n-k[۬j-unWr.di\w.B~xgI7/>ggVw-'Ɏ7"Xl/a]cH„o~]/MgE>PKD5ku2?r6yTơ^?|}:OKi!e\$Bw#%UԆU`g7~UK>?Ᏻ\<+/VP]}ʂ{Kx4{x͘K1G;t WĿޝX^wiZφ#VomŃ hL@Dt[cH|WڛǚocU|cg?kO[}:;+{Y -pte.gUܒ?ifo+imWi|867x].+e'vVCy`l7@'uqc{0& GZ`1êiKַ4Xe ٦mش(>/Z~;L|ak;}\@ )#;(.ij3~5Yi>WgmҵY.܌{Zi!WQT\A fėZҎb0 Lmn&#~vZ>Y'XOvqgo 3 q,2&ewJй~vu{'ź=wz^hqLKգ8 H/v~7/+i1%<5}p!֭>a$m"ۼ#o #\ǿ|AMk-}0I7ȡxͷ\*Z7<3qgi >OKi!e\$Bw#%UԆU`~vZ>Y'XOvqgo 3 q,2&ewJй|Ks Ö/ٵ( #(ϗڿ/c՘wNx;?ė#Ѵb^:Gyymwvw]:]ȦRg rKS'W>8֞9'm;^ _xNѭ4ߵ:Iq+8!Oyx[ 7qs;Elmd"hnW a6dx| 3ywNѬm俿w$Zh4 ctp>؃ngSZ喅Cv߇6sY,i-ь R1_`i_o^|LѼoz"]*}^÷Svmmymo4\O-\C=̌qI|]GuA/ 1I"M/О_W>:[67 ˦ivh"P䶞H9Vhs]K~%F.?hX~).ƿSu Qq[oo`;*OѿE|V k; ]a5 BR\y$ȿ;I3I70?{Rφ~#$еqVln7/kq,Kzw'@-Sυ}zO#riZ}X,f\ Ӭs :Owᗇ>U>>'ks{Чݲ[43HЭRWTº'u׊lchuM[/SK?8mgYb*A=Y ~??MKY}5m=okaϘ fʄo` O-|!.>xOԼ?p-5$_1IWup3@>ڿWm; 7_ |#>~A^T;8Ph$%Wo$kgǺğ|/nu=)o׭itzr\ߥ3qUXBݔV!#~׿'? ?zO}\WWf#hm+2ƅ_|?O?^|D5 б燿kn?Z7>Ԭ?5c%r ڍ̓Iߐ. 9Xx $ওi_>0^ƫR~o,s{5,x3Q^6:|Qoڻ OsvgúMdgؤV_G&Q?R.H{PIYm-+C0x4[f?ş|˟&t˻wJ^BD-Fb/rQ[῍fؙ4MGGC\5xSOܖviwEo3Ff%39odK>/i?>3&~{r׿i>\8mQoct7tO2% ۵č$̤Encdr<|+пe(Go&n|!Y'y/ [ >I .s?`;-E׉,\\]'FY`o v2Ļh\O_ ?|}? ,4/sow߻n1ܟTg?myŋ,Më{z]pB4MҪ/Ky=)oZi~!`6&[K{f@̩̎R  9Wό >}O3mmv307ƽu|?/xGhiOSԼiaMdS'Ef67|]o߅韴d0R[iѬg,kk^t?>*J|xBR3B~xgI7/>ggVw-'Ɏ7"Xl/a]cH„(((((((((((((((((((((((((((((MGu:??&mpYvҀ< &-sH'd(=,%Ӑ(*yOWo7#UY7Z襯A+ W$oK_ tT{SWO((((((((((((((((((((((((((((((((((7Ԓ?Wo}7_횵۴Lh2ʛ΅z~L2oګ?<k6c:>{P#ne+ԡ i5cQf$0j;{Ei[^xÐ}x2jADJQDhvA~3🀾 V3E/ZzӨHK6nKe,ʾl5(qFT$f?U៉ QQNZkPuZjPX3 F?뿋$~).VO-}c2oQSƽA~3🀾 V3E/ZzӨHK6nKe,ʾl5l;:?|s-ůo7WP$Nve\K?;f>sS|_7/7|xľ6AUє:8(̬X]eKi=G᧛:gi7#I?gkv߿ga6c>roP~?~-^]lHunINo6SwB|dު@~?j E|kyFÖYioiM'LdXm#)Vy@v<Eg;}MWŜְ[5[^V@91d,e?ko(iWV~pD1eŚsgYAPJSvt'tPx _~,f%5߇gO:W2K8[kXلU6L CFEqk5/> sxjBЭ4spZ PaTA#2&X\y~_|eGK3^̶3\4򴲴FIf%=K %~_{[xBSqusDt;E镮BioNbH$p'EzG?<a_wG$>v,r?C.y dRK]R\m_:FVxRQlo4C#$L3f.-0tPk_o=þ/: I ̲\ܸ{7Cryc/A~пλkV;җ%KӼ?=h&k{9g't# *I$.MhPs r"# EBm,e5Yۛ8,㵷ӭMaFDig7;(KNj~0ԬA[*ѭ^8Ik}$1FC~&k>1yܐ^gTEP""UP7EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE}k;a+4h?5?뇈˰H߷ |hֿj{fv*G?o1o#?C5~s ,OQx7VR ?9Z襯A) [+-ԯҟ@Q@&f:;gSI# .g@2K<|aZ_gW \Acko;m=΄f¡whx ߴg!(((((ĭni\-mVBZkVds$V J9U'ҕ)՚J.R{$օ *Tb'J$nQ^i w/Εx'H<:Wf д1:ytdxIf|}/W{ K?7vwoɳsRz7 C9?[*[)ߺuJ^]Ŀ8!?]|Ew_^-m >;ooVHnS {?kי-70tloqKM^+t_YѼg\]--WPu}7U"%VpI]!vEB{][ƶ)C7%:ǒ40OCc/)-Aav)'w!) s똺ơII/^nGI::s^|We]Ҋtߋ֚K9/ȶ e+Cr3>TEuنQ&JlדN?&;x>)7BWfiE4QEvQ@Q@Q@Q@Q@Q@}'`jVYƟODv]ۻj,HeVT$VF $W]E'vQZ/঳ck Gum`'PO?aJ}/߆횵t\\AMB˽A_-w^Y!څuX5)]MHeM1p:0 Rn,Nyx[ 7qs;Elmd"hnW a6dx| 3ywNѬm俿w$Zh4 ctp>33j?)׵ Mr?kVRmJ֚cQ8uaAC|!3wcT>#Ci%ѯf@#P"ª*y{#1i?~5c߈5Twc#b $IEK>" gWs&YAtۍ.S\YroP1$?gK7>xBַm?[O9rܽ,^Uw$AO>i ?ɥk =bKzG5Kur_3Na\.?~-^]lHunINo6SwB|dު?m_>"ht_-𾛩oMIVfXty浴XϾ1 8 e:Ex+yok"j6z߽!-4!xß0BZB>%>+ρ$\|:x~%,[kuI⿰bg #*c('~?1]> ft{xKj\9g&"셔2?i_Ƹ9v%cwj15|[vqmq1g.@xco{_QBu;COkZ$q-@EfXдk/g ψF'I1{`7L"u1Y: Kh/x-JMS— m/TBiS]yiDs%+o/i?>3&~{r׿i>\8mQocS?i$|4~[gǾƁv{Go2 GϵekiK5e!- ~vZ>Y'XOvqgo 3 q,2&ewJй+}+?Xh_m<8C|ǎ.3el-f|8SU~>?o߇~Wn.濂s%ЄTr_c6F`x~_5ּ7o+jŵOz-W/_6~ZGmC?ٞ:K*+Xa4ҭ S>*9HA<xw x' ֏Y$LMyjL Γo_t}:ƭ[<l [OǓnD_)Hº, kO[Լ#6wMN9n fl2*ɽT_o5Y|ApnoH/3*"TD@UT*>xVjVm_hE(T]2(I?jCPwgt0MW:eYʌ'tQEQEQEWa{*?E' K>~+|~.v^Nkj.t&TuK,!i.摂Gq,BPI$3W>!VUs5 Vm椿gFXdm2A#Ǣ5/7[[%ow& 2;[ym_c|~ +A4o ~ "4g{HTEPN]ݕOy8Ծ Awoi[ky U͹\y~a@]8[/|MIojz|L&=2=X+*tQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEoA)9\, /Hlf"U(|_v۵x9->*޷ 7gb[[  |6`袊((((0uO+÷a '5 UcYlaغۉW>ĒJ-aү>HmݿO+Mx -mշ]odi;>?嶳5!+=l/.%K+P+:2"G<Cg]f_f\& vKUceoۂX٫*\L~k-ѥ4m6 F M}pʪdw 敚G#,[WA]EJR։_tuJSvnm]&h+<(FӵKk>e'RYIA^{n_@yu3ŕmB3" vX>Eva7A]KUͧ߃*PN59o]IjWix?ƚ7?[kE"OKiF"VSR:Ӯ|%;xN7;N(EBG|#IQUaץ_4~uFec?JHk˕`p@48hz/褕՚cX$' ۦݵ/e,m$ԣ:(8(((((((((x7sѩjAIVP0*LB ƬH1E?>'1断ݾ$i&./ <m%e6i$Sh.5_Sj]^ɴh|^GwbǽIRZ |14:ј%/#{$YB hCj.5T, ]Sþ >E٘řfffbI&5,|S/;Oq˜,N5MjU۝gwnHˑQEz'QEAiΝqgyoݥm LHF22H$x %=[Oy<29tF"BNTÈۢ;J+VEm%k>}SӪkfT[IZuNf%(4JYӭ, fx\Iua)GKMoj]z-܍>@I v%,Ē£2dyu+mgN5 q$s#UՇ Ahb\ۥUZkuѮن7FF=ѓEwQ@Q@Q@Q@Q@o'Mݤow?-Hli)$Fj?ǿ ~-[ڄIk3ꗷN# ,~,m*, ~D63KCxs]& VbkMN3[ R]\ZYiuuI` VQc>'*-+ ^C >`_#I-B(>M Θk#y9;{?9ៈ>|t&Mnc_#yOn~Iπ*q_k4Zɭ ;>wI4?u/a{MX?k,+_yGuomY?૿<F£[GS/u/5 Is}ZD"'&Lxð~5"Wuj>Vkw gwܡ{ݛy|If)e 4x{?9ៈ>|t&h_/YIѼ]7\|OԶӒk YTM :IXdD'c iMogPǾ8{&=< 7%Q 4.VW '|Akᯄ~h:Z_[Z"wg=[[d"~~_dlX㯃څߎg->}[ΏNKfn#1ʫ[<߂t+[] bM֮›}"H亓sX0,dM?h߲·Y .5=SE[gWݝVcKv1aLj_ jۧEߴۣ.tnG,purGFV,Nc2^xf_/S\x}o~rnm-f7@B\@KfBm5+BTWOu ;e1Ȳ3EjYwO>/|,αqm~mGLw$%$Anbm/ rW)NN^|OO|P-oxXis^@y;a1r_ioI?jmƛi iomP[}[P|R"4buX'Ylx_qF^fRKy"12}Dcui_ xs+?Uզ&o 4r[ǺIt n'7/|!h+^ԵxXQfq ,ai k`Fͧdž{㟀O^V(t(l㹺K)BIglYtb w,o GxO+\?#?mv{,=v݁+Q|@M]S>&!-'Hg4"]:g(cI : o(J w7MK!{-}Ņ֡o+?`ӯomϙndnzۑxO=cOWhᩴC?eÝ%}!ns@>:m_gƭWJuՇ ՛-~=sKIs%xE}+xῄGTosgȅJjmk[&Cr <ړ/ iޭm>UkNԵ? Ma캶nNbu&S '/>"~7&'mAO׬fVX3IلW,cX'}'z]LE}[enqh'x<ݛ4< [}z<~~8ԼW=sNү`mi&Kw`M3O:4x7o{Džxğ.|upm4״'I^ݮZT6W[VO8ۄzO.$~xC^= ǟmM.t뤎XO.%V̑*oj?jׅ'x]߈,mJInOLOGHXT k).|.uajt]Xxj]Y-4;1J"WdZ*Utx?CuσN m?PԥIg!oePєePJO EZO7|5d4{]*ᮚk8 Q¨ ?~'o;kQ>l#Ҿ!nuAI;\©#y}sC-['EJnW|$iߕK`~'ƿc[%:uw1%ݤWU )"0`A"g4E~^w,u 3j啫]=ދX"4ܠ٥(WoZף<ۿzmBmA4Q%*fI"]ťх Cпhwė,xPԒ}OɓQiMy2&" Xk |,..n_n/-ĺv ,c:2-{,cwa蟵o4 B7Y5Z4 gO!Kc(ǟ?j>{bž /w=̿j>t e0WY ƽS KYѾ4ΗkέeawmExB͵er!2[{cDy~Οt"^0J|9lt+췥`Єldcs{z7ʽ''t|"~~5hzޱ;`RBx<#r%nJF9d(@ > /"w7/vڽղ]zeZړqAjKwڑb.[/7>|RZۑyZhiݬG%{g@xq(H;|> iW&ƞC}Vĺ]KLnm{{ys3%@B~_w|oo-ॾiQ_xn/o -U[2c2;;O袀 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>h?5?뇈˰H?ueǤJgbF3W烠U4?w/ˏo/_~ w#>*_J#uZ| G|#`o;2EIH[+-ԯҟ@Q@+&,($(((+?(4};6^˿ \lCZHjcT12tc0iE/XT]hX% +[sF^4FEW!QEQEQEQEQEQEQY~,e4d{ q}1Q !YbYݕgV)AԨ쑕zujEn^,eh*As\%&PZMp%IV !e` K,W|;oxZIy=<4NN^iXYc,y5Kt-8׉u8}V"Z2! ᙛtH/VM%nrUdW~vJ%Zm5m;?;'=Փi&( ( ( ( S?𖧉o8F,-M|ҸX K HBLn}u-gYݴUuK9J̓?oz?l#6gxc~_q:E \2YYEB7*}S~~)|?}%E^TIMmPŔÖ$B5W '|Akᯄ~h:Z_[Z"wg=[[d /6^9.|!?llS%[Ju "9&DUva,OxK>.=[FK]K"ysd5ŴINGضӿhᅢx1|1Ũjz~9k&ɨ_I ށacV_ͷO N+(t}^%{M4Xb ȑ1PcF^>1|4 > o#5mU-[M<%&4e2C 2 j|&& K!:ơ1\i̥fn+i?Kq^94{X>!,]\ZYiuuI` VQc/3uv_BnKkhZ Lr>$Y0Ee <?.Oe|F:jed4[2yyo|_GίMzXvYAo)/6yr"R?l/y9╟*܋jGMg9-$:7F@n?^ Y_Y2÷:ve'Op<2J/3fGdzL4dM?~Ӟ< ÍK}+M߄ŢGkqMsp3K*\̈ءQM/EBf?zƽĖ~ejj -fS42Oq,f-.(fo(O/ؿ?5xljaiꚝOu#hMq:KfAmb$ڬ\C5-6Ǟ KY[cm[s;\̶<,<nm<7|&OK Nk4GwHݤ +P$#G8(XWJj-;~Z'w}Ziz6jz̚$Cp}@Nϛ/xN|CRIiky 78\Q<1x~{yk/ Yig;kHcgl"6I4aI~>"^xnFšLV:]TY tGm)^[UQo47Z|s|q^N7K!7r_oH#VED-!c>?a|/χ.iV^kV_ 麞Ѵn<5jVeGk[He -xb625$SdDtS^LE(#– V5cǚyxSPQUKI$C6Jȍ]@>{{ƞ׋t[~F=Ixa$KF$dd/k5/> sxjBЭ4spZ PaTA#2&X\}Q+_> R~r񦱦xGrWVvqcw-ЉΡ ̭ –*:`Y;='޻cU,^|A~ (&wǞ6yB$yBdfY.?2:z)*x)KkzN=[i'g.SyuGk{%4[vj*W**YFtk>e'P":YH AVk̔\[z"a\Ȁ"SW3N$ʽҙ"C­Ċۡ ݥyO.ϷfR_]w?hG൪/ y`Ҋ(TŠ((((hZ74+A;TfțYk8er~jq_xCL| a⍷ŏO:6ψ΁6?i9KmrhKc,_Q_K+E^=|CE\Z\C[,f.)dX|d +?>9՟4m;<K$Zݽ0I5ՄѪȎlmkLg?9c-ƙ6:$XgŌ$X(e$ߴ/BGÚnj<vޠu;zlmZaas4E^P4&[ĿG }#W8g z|iO,Y \I`ĭ OUѾ xMմ[t}VKFh/mm =[v|!bkx[UeӼgSը_Û;MoqL-lncJXt$S$g{ߏ O φkxZZ]$,Ank3Ja7mtqؼ]d#[]xAU.R+vk]#Kx a|^dC\$\|7t: cCxl/6m*LJHhv,>ߣN>۷i'o;w<+w=v-|C;K_ ďQxѵf\+A pyoceo0@;_NM_/PѴJëi7Kz4&i "D->^QVL; ?d \X^yk;o ivN$4M٬+y_'ޑW}[wO=A%uvR9u,P}d H~?!?+¿|1+k2UNOB%J'"t&o/&}G-4+f\i>$XgŌ$X(e<;7YxB7o[5͝.6]Ga{}n*Igw/k٦YoGKI;G ?!^[g'PRkK@yT׼7o\xI2.m-ᴵ'd]<o1 ??gȳWN߾1<-|Ie?\\Yw0\.]Mt=2k۬ @^R[ Ea/ _Eh!Qqإ.ԟF-m/ Ybp i`ITggo^>k'vdI m!wv1k o43O٣P$M0iڊxI!0B1k??k◁,[/;q{smoo[\&Vtȅ\CxFQ Viӛ8bfҢ 2b~|:7Nu/MmWn4KHKK} hݢJ%.?K,jIngU{T$/.(dؙPϵK%?/XjZmϏIo7Cw>y;xBC5 m6hywog$i R2JgY|ß'<5^~>υ%x=gOͨi]q.qksJ&qvQ/u4Yx#X}sJt94;"XKTis5o;1wxPIyo YxkKt9$h4fi[2>fn2?|&lOpZ|7/ Sufk k!\ZZ^Y6QeRe :zo'ޟD~?W­'_߇4 b[]¶s_-q"4:XaHO?sXƽ φ7O]ˠXZZK]BmoGBd.dbzI?>4~!ݧ|n,=Zx+CҭEiGf@s 2_J?]?-ߵx[hچ$ʹ7{p᧍ [S[@]2 *[Fa9,BBd>c|@| i??7m ~MbBu?jie`=Ĥ*"'. ʧj_t_ o_SO7~t-ne<*͋fܮ<0|M-L>&I$P5=>qukWUWՕx:(((((((((((((((((((( !wS.=#wWik;a(nw'_F ?m8bN3W\~ںwpWZ ?;[赯A) [+-ԯҟ@Q@󇏿o Wui|]߈5YYF3i VN f }y1 *}Oibvoݱ^G=&~Vʋ[Я; F|;a,25ܥYr@>((xNy[_.>ǤhvSjm'Hd,U' 8Zu,/ σˬL}TYD8|MZ)FaZ&Vҍjjz9f^j4E5{tms5{+Oස?sľ!7n)9>Yj<R%N*>Xvi(95FVs; .ɨ &0#I b8a w ] Vl<(STvVޭmXL-<5ѧ{VoVoVQEntQ@Q@Q@Q@Q@Q@_nEGw+YTGUf1U+u]3Ěn,jZ["BT|1]B67+?vVӦF[Gwk.O6):62+h ɞ&W7Kh$G/urnRe(S ( ( (?*_-4kx~oVFH"I%(a;x'? _m j4^2%w^:$inF䱶R̫̳\0 e:J;).x~$>$UhBG)"0`A"9l'~ XMBPT7mI,,/ydǍ<O~Լ#sៈlj4-kwsUoÛ'(ۭo^rI zF_+ܚVC,4 //aDs_ķW+54&`]eυ_UO:w{9Ag/)7l4+d|U?4_n;?5SFKῄ嵎}4VX0JinbVB߹I|]GuA/ 1I"M/О_W>:[67 ˦ivh"P䶞H9Vh{#ho}kkvַȺqďmV@(!,?߇<#[>=>${wK}kOVӒ-6Yr좱&</y;W?K|-ZY~hz#6rg= \֗.?oࡶ `? O߇.|E} m-]fh=NI"83@]3W/gӢoS$[x[/n5I<u,)r i71,03ŏ,lyÿۏy Ꮑn5+8| j-|5es6s$Gyqw 50V=A~R|<׀h5Ҵt./s ?59g}xI)$$qǰIs :O|Uk??{oX)o]_HxK,Io$V9Oqn-  ව|^o|>gsJ"ZmYKxI"΁c;FQ2| GxO+\?#?mv{,=v݁+Q|@M]S>&!-'Hg4"]:g(cI : o(J |E~Iu6t_K WVxW~͖Nin9`$UQ">Owz֣|7G|C5[eIv!ڹcRG@_4}B-FS_Qh|aH's3 e=Ѹx'mZONJ<7_6>(Դo %%dA46\$op^ز4"-?1ǷZ|&/}#%Zw%]Fx<mٻcJSॿ=oޗK~4* Fi턷{f 44Gp1y]橯syx_zǎu ]4dTt $q`Ab:m_gƭWJuՇ ՛-~=sKIs%xE(<}+xῄGTosgȅJjmk[&Cr ?Η_RP o̞?yE+u^e~U-q /EBf?zƽĖ~ejj -fS42Oq,f-.(f%F?w$gů [Z~LNkɗ74dqRH5MßWkͧݤ_9z5xG|]yi8/ "(~I>MI((((((((+4O_.wῈG - km(ݩ COե_íGE6_*N%I.$n"O-T} #7F'mnn[-ZnzV&*:ju,eqi;-dk-| S֝Ig{/mywmvfy7Kk{*A=-rW:5eFkh,NVVMvi٭4߰QEQEQEQEx:RKDz ;_3eԮ['3ƛڻp4|< ^1u+ L>v b_S4 oӬ;=Uo)vۣ ѰҼ'F"X_ޗK}"`ڱRǿ))F)'} QEQEQEQEQEQEQEQEWź&4_[&^@\>gƟ3|qi\ κsȷTg(?0#uyٍ),EyUݯylQ}*{5R}h2 :+/~,υukTcNjA;%#rZJ*5iI4ЯN8֤$QZQ@Q@gRk?؞ݣ6lլݧ2ʛ΅qɗz[i33j?)׵ Mr?kVRmJ֚cQ8uaACPxn [ AsY42ݬod3H"I%("4w;U>=O~j>&heKYTuwIf܍clW͙f`11j L_ڏŏuB\źkhՔR$2um8Dq|P1n|L/]X?#Of?rZl_kx^f5?j~/Z /xg/nEFY7#rX)fUfY`~CÙo5 .-|GCpA$u+(Y1G o_4o;Y|?p.l/  )dtpQљX2,xzO7t=2Ho6F*(~l|;$ޠ-S>&k*5?YhZ7o]q|Co`W;eH:̐5#q-oo1)ҧ;u)~^_^I-ly\Dc$Dc<ф##C'5埃.~|;siPiZ?Ry,taI g o#Ο#,T~xsWSNCv^oiw7 {x-A#4 +,,UzO*<+x7Wx:OƍGTѥ4o9mcM{U+` |sۘՐCxuߍori~~Am/D-6[ x"y]-5ߏsڗ]޵_j Gi0˪^UkXi\v&$rs'xG ~5?4U-/ouH㻳 P2BYEp?ox/F|{|IB^3Җz֟>G%[l7U-EbLx| }R}B kQiM$]\4r}ɘ2 llۋWԼ={~5&YgnNEKg?n`0o4>I5RW/gӢoS$[x[/n5I<u,)r i71,03ŏ,lyÿۏy Ꮑn5+8| j-|5es6s$Gyqw 50ViE<7x{սH^oe$Q\pAWIe)̈7*vSe^rך=u4|_3@!oOnm<7wpmߣDB#0=Ak6w:mwq2ݬod$@K;wood4VrI%z3_,Ҩʸe`K-< />g/zT]\\HY%TوL6 n7h x[_K}BK5^:[4eHdvv*=EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEoA)9\,߶枠2?ux>hg.5hFDќM$`A9.@c¿ }ƗWt O2E?2ycM: FYHW~q_[A)^^~?Ul{Q@s_>"«uQi^[io}<~uıG0ڞf‚GK^i%_˫_ i/i-2WR dMFkle8ju+:\]i(瓌.k&t«uh^i^7W}<=ח~uIJڞf€KE^Ujm788ӯYSmݷv~EVFEPEPEPEPEPEPEPEP(|R|r:}EK}.j|:tX?oet+;TܢO&(/keI?í;Z6_6Q|%x.|ͪ$n"?1F.T}\W/6K8-.{x𳶜O-Ku!U!IK.̲] qz/WC'›|}q[]C#l0k̪AP:>nӚ˩*qPvUo)۱]WS_ k&+(499y`dr팳1֥Wm*PҦǣB:4FbKZ$QEhjQEQEQEQEQEQEQEQEqz/P'{|}W] ;p+{w|[g]9[[*yIT3 ]fYT/Ŗ9𵎭j{ Y\<2'dduUє+~gyGѿy۲%(eؚdFqKcR(TŠ((g A'.[Gg%ΝM$>I JREdaE~h4 xOwCx/N.~]GuhS͍DMնZ*წ" iiٶ!<3 /^éX93yrEH $W^<h%}橡_Es*(o%@ШUAO(F0ZV|zs?o .ߢz?OEË(pSYHݺ[\0u\a+;F_|UH kL@YҮ1 -È n-56XSʟyQc >dO?wW]~_iZ}|}^ Dq"eJi~Q_ ր'7jUg k0>Oᚷ#R+ f:|eWOp.,Y5~}Q_or2>4|>fa}|g}Svf碿G[ \}ST2 ?pS\Ί+]8#?#o' #?~j@W?u|>f*ds3SE~7;^[>S9χ+~oQ_?vE ?1GCl}OPCk[>S9χ+~oQ_?vE ?1GCl}OPCk[>S Gχ+~o_E O1Nn~|>^(z!s-W?{gb?7;^z!׿|>^(z!s-W?{gb?7;^z!׿|>^(z!s-W?{gb?7;^z!׿|>^(z!s-W?{gb?7;^z!׿|>^(z!s-W?{gb?7;^z!׿|>^(z!s-W?{gb?7;^z!׿|>^(z!s-W?{gb?7;^z!׿|>^(z!nn|=^){gjb?7h/3^!׿|=f(v"r-WFsz+xu-Y⢿G]w_jbW]?ZTE~:z,?E O1@4WCk}SR7O]z +xz+?E O1@wA)9\o~(V  /O<BGX&h7[IȈ[M 7S/&WºۄEF8W1w÷\>~\êrO,۬ݟI!>niNJRW?y%_j>|zϡg4U>dI/z)ur_=K~"l5m:oiwvdbCa#*A}:TRXTM4iL(Š(Cia5_u"4N6*3A=WxV3ivHPOHo13}cϥ}K~o܈巳7J&J͸rx@[cҾB~\_s.ʒI|2tIFPts:kPsk+j‹/*OIp vUrqzt>h|={fO ?fi>'Z?mv ֡km $ F3*90$Z4"cno{~gϺ_3I oc-kj/G|K#?]h4 ]iWɩxr5k+"ü@Fa98!Jo |Au]/A|;zVis>v̈ţ;#?ɯ{oj| +okQIf|.[cZG^WÃ࿎t= 猵ixb:Wu-KE<[[-ͿeJ B1|lpLel14K Ok.lח,obm0r@2ȢRQM7۲v>OZմ>ߴG?PdYOZդw=me{vBfC0 WӨjݹ*I_ ߴG??32-k~>)?gow^)4FF< a|D.Ial l46dg\-CN6$72'h ޟ=4}Xo/*@X֏o?+~@Xֻ/[x쾋ZjwsY$q\iq&8O)2o}5d6I0e` )Z' ;??o+?@X֚ogh ,k_F[>&/"{Kv`A$6|kxf#4:Wm3[gveI4>de*̮r~z+oKդy8>h ,kHngeo# Z???47w?h ,kJ?oe' Zӿ???4 h ,kG7O?h ,k_OӨh9Q|? ?X֓ OZ???47O?h7? OZ???47O?h7? OZ???47O?h7? OZ???47O?h7?ݿ H1:cu| ' -iG̱DcZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>`iBw4ccZGG1:>aiBx|5c1:cu| ' Z ' Z???4~?h ,kA~h ,k_NӨh9Q|? W W}= sNG@0x|3_x|3_1:cu| ' Zx3[1:cu| ' Zx|3+~@X־9Q| sN~ЭD῱? V?־9Q| sN~ЭD῱5nlROZ???4Zn#R$Ң6ڭV9 z?~OPux-Sĩ{6km9B5ɒpr &я5X|kه>}ޟ+ӟg*><,cyO Ҹ> #iPDVdXc_ta#W y@`t!ڢ!ؔz uEQEQEs@%.+[!l[{cT!nN_?'zFxPkz60gyeoml6+\)ۙk*?R='xG_Qm?ZeΫuM$PDҺbU @2GZܯ4C-no~7s6;ev]ZwW-:ؔ>µi>_ od(<y-׉yUٞ);Xm&]- ;uQXbqVUo'o.ˢ9qxүW⓻%]EV8QEQEQEQEQEQEQEQEQEQEeB#W*ӡOauj))Zu yvKx:U-ޮ,l49-79m0>h\t N}H,,g?> PI`r3\wŭlk7=KvJzQޝQ^QbF >ul%cOEnBΠHjk+vXMx`~.FE85UN%iݏ}|U<RJm'F6E_<'׸m{缺]J-2By<[TQ]t(B(ѤZ# =h$d]QZQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@ !EqY_jSjyx&M%\l*-mQEeB(S%l$aSMQ%KDI$QEjnQEyW5HKpKBq_ml_[Ga^{)lbYZpc7e"WM5`K'kuQj'SSG_*Oc 7xk ƸOG/mߎshZ?ufy/I*]u$N`eCFLD7 ZKk?~^Hmm`𧈥iX$q 31I=1]4s I_N?v.{~ ?_#=o?#Am3_խ']&O _FRmΞ{P35o>7Sw3Ѽec7 \sך΄t2d>]恌ba%Ȍ@圏ᠼ Coo _'{.J!@ߟ>w ug*柕|vkŕEd5Oj-t.ۅII4$*b$ ?^7P>e٧M5 GkM~/_wEZ-t.4/zZNnϵ#'jw7b- 3SADž|'Z7ï]GrcD>.dJC(%Vܑ+|x⯆|Lj4=*Hī PHIFA> _'{.ٮEOr%rG[ܾwүN?5<9 6ZO5sJUw> h&i$zO2K#e >}*|tٷw|;{oHmt>kiX"XY,LSra+eGAx?  9O]T_,\W[~rIygO=w>xN_FxoBGU{iY vU#,HG^xI<+I.}j@~@>%-~OF?_7ϾoEp|g۩=M>'ulaѫ?#6!\Qܙl~xgŅb\ TzoxJ ((>8|_lZIit>:?][l.|;w-nsc&%oYȚ?F`~Կ!h"~>$j֗PjW;\xb$1neKajQEyO|S_+?|?iO};<'nޘٴ'.#Go]g <m~hhg~]WRG2wNYN+c?(ݵjz5ޣXi̫6"y؀ $g=1xSuO: 424[ZA$l7G:ZЖ6[_U`3A5ȇ 4SY|rUŨE4X (S ( ( ( ( ( ( ( ( ( ( ( ( ( ((\8-RPC_1|p=aCLZ'*^4/U ^cM.}GȁvfWpό?^;J[+em ľP*q_ t3TWZ4"ysE|*zt||x瀢N yZN5k}Uoծgem d$wY۫IB5G?ڮ>iwFt#KeKdh. S_ۮތƾV]WN>.&1$|[K#8ʶ#xJuOx_SKK"HxeVPH<1\I/k2+htB61DO*FX1؇eX5x &qynyR,-X@r"8ʲ/߄ tm[Jy.|W[jcMqs$緙+#i_.řF-$;wӯ~,:ˤfhfx%h7NLs#ϟ|g'DIw^s_:^iim6GF~GKKפl]o24p++97 A7M*I+rZ4|mO57f_-m$qUywCN, [a0w~ߋ>0~3Y^h }ipMqZhږkmk[aQ^Kr~$^_6>a x4kTT|Lq_bNGutQch^t_s%K]Vkf9ѤzkYZ "{" 'Ic~+Ɗvߢ][J6ve7O*6v⹾/ib$P"U@VjJUWhh;E%}ݮ/4,V*uF)F I_wkޡEWQEQEQEQEQEQEQEQEQEQEQEQEymH^]XRkT?1i,t[yu_K4տN8-hm籠vWU@ot̞-k[3ǧ$m%*9 "[_-#`۶u+W3kպWsIv-;x+[mzQqr动KCTZ=%+kiOOfKvbp8_Ѝk-W 4{sI)[]e&aEWYQEQEQEQEQEQEQEQEQEQEQEQEQEQEyeǹe\oT%js?҅0>\^ # ?i?אCukO0MPYzכQg}9u)TeZV ^܂2ۯfu!'+xO{KM*|vK:1 ҐYL TwIk_ 5[Ʊ6\k  Bi%e*os.xĚ%ޟq]8/ah${_%%U6ᑃ ז;:|0xM׈Qpچ鵉f-ws)Gi>53zugRNY&g =8SRkd>~^1$Νy˕i[uΖ&ӂ`V^&M@g̃5gW-m|Y᫛(TWh*$s]nSrff*&~)6Xaƅ=E <߉~+9K4u:?i(;/t.k[+{{{uV6[W͘8ʔC:,Ex7Gi:C]iQ^Gnf .n3˜t=k:M5UO]x7zN&K `Q$HS8DPTr~$}̫94>ӊ۟>#`(b}a86)_e?51|bt+[ڥ}* FəeY$bwI4a1Iu o>!icIfu j6֔i&4Mݼz ,r5M|a-ZM=5@t+sk+E?xѳ:um9b{7->:j:6]u*-~~hh7x#+X^Id ,/jz_쯪~пxo"lowjH)}.ڴaEDZW>~!_ t$q^?$neѿXhe <omnQE["D0@lҞ>:x ,y/]W6NNɥiY+d4(&It_dIY)|z|Uݟj4϶{/>%s1𕶑蚭wײVwNHbā}ǭO@EXޢ"mM>}kG__w_OKmbSyk5I^]2Iß5iDO=^|V..#}^gEuRN˜Zx||Wשf0pJ^yÌC&c٤$Okmu]o\Uf쳥ݽ͏IKmo2?y_Lsh"괟x||WgY5=EX{ p53Io2nTs z O&=gf}iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]iޏ{g]yo~#rG~C<c?+frG~C|c?+;-M7ip-}yG [80,ax-%7,Msgezh=_$?ٚa[n=8MCOGkZǏ> []*O iu}<=k& {x;x{kn%#:|WV~CīI? r XQm&2Ĭlp*W/Vh P"nRrFT3@>ŷ#Y< -ז'cQyVWHTo"|a5f+OQd gpc |̗ @*7ܬn5)$z!E{yDp.kX)J&ݺ]_W98O Il.dve>;8dsk7HюF<?;^akDEC>1WCN֭4(,|?1ˮs?v\?skH5l<es hpx_t X/Ͱpmkwqp֐Ra$gƟio7lǩCkɧpNP0Ko@gDo/iS,?rExgKK$fo8''??࢚][^*Un{ymii0xFYZkKTtM;^衆>@aFzN-Mo};RibK"Syeڱ)uZHcu*wX_X|PԴeX-XE$Z \.|@~׿/O koM3_xNNW7QOk&m*6˴Jo&%#iU*>\?shˮs?vFm/c|:վb/͂6-Oݶr>z\Be(m|K#A ?~0_O!GVՠӵDZ6[mF4p$g9b} Tfz?;_#x )xCVWkw^խYFԴB+-Ĥ` !A6ֳbj2~ȺO –Z,ִ?VZ[jvz_:$ =յF`i"wjwHO?;G.]s{Q 5 Yh)v֤[Po!fwJ$]$cRH+c$ ;C1Gs!EeE%wr;Nro/ #ei`z Eֿ|9$V|QMqX&Emuuo'p qsHsXti/ߔrM%;W??į a@{s,jv3Hm]Ly_eZ^v&ώM(_ӿ)cQKO{8?K>:w7IN㕍E}_ӿ)K>:w7j(&&ώM(_ӿ)cQGpq64|to9G&ώM+= ~S?4|to9XQ=MM%;Q ~SƢm>li/ߔrM%;V5{iggINi/ߔrO{8?K>:w7IN㕍E}_ӿ)K>:w7j(&&ώM(_ӿ)cQGpq64|to9G&ώM+= ~S?4|to9XQ=MM%;Q ~SƢm>li/ߔrM%;V5{iggINi/ߔrO{8?K>:w7IN㕍E}_ӿ)K>:w7j(&&ώM(_ӿ)cQGpq64|to9G&ώM+= ~S?4|to9XQ=MM%;Q ~SƢm>li/ߔrM%;V5{iggINi/ߔrO{8?K>:w7IN㕍E}_ӿ)K>:w7j(&&ώM(_ӿ)cQGpq64|to9G&ώM+= ~S?4|to9^GW|gz|#Q|lwwU.ookw\7Q> e\2hƋ2Ik?J{tqqI) _j֓M*OM7j:,wٷW:ufA*OiuQ'qRylvoum|^_˩]fHO2gw``+jɽGڮ\gi^uO%oc G^etȔa}v5'-OZv%mmaٷJ]TIE,~b\KP^?n_@$W׷P:U?z>IwL N#:mVŅQ^yQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@_ 2Z-;Hdo!(sP;HŝZGy-4N֯(C.C:0 X}qT[kE V&Rek]4Ӿ2x FtMJ4Z+~(uOw7+l7ik^X[kViAo*EZ$طYb҇_ilnip&Z^[e܎ 0R28 2' 5uh|~^ ;#̋z:Ʋu:K-6]E"{iKC9-T+ ^Iqa-#_Ӭ/t{k m^[5 }VTꩩrp4G4K\4Ye?N< O7G2'V/&]Gc-;I5+Y%^ik0Xb,d[P}ؾ>x&ò^𽵅)(l3w71:}؉"m,|1q?Z?>8-?/w?4kԵ;?GQ}[It%\ٴR6eqT/Ɵ_zLJ>٠6B,xYtkSXjךnjmzXp5i dy#7fW1k?v:N]1귺v[w=WLyWEm.RKxx5WFc ǀAi]3}~:+?#|9~6[<h]sr*mvYQգxY]yk&Pv\A'klRAkc ǀAi}Z?#>1o&jZ>{j-r&u=$Q5I5љbv\7o@?ƣoiu/ٮAL[nʜy>z;c ǀAig}z|_i;;5[ δӾ Lc$Vp5O"ei4Ht_cᆃ0h|?{,p\\XAujVOY=>nlZ,P8F$Uoc ǀAi]3ʾ̿>h> }:I|׋6K*`9kjXcD t,|1q?Z_U~G|E} ǀAiXcD t?o2'cX7=~?诠?>8-? xn!|E} ǀAiXcD t}V?m.ߏ+e?N< O7G2'o{iv?_@,|1q?Z?>8-?U~CKc ǀAi]W xne?N< O7Gc߇>XcD t,|1q?Z>?o2'cX7=~?诠?>8-? xn!|E} ǀAiXcD t}V?m.ߏ+e?N< O7G2'o{iv?_@,|1q?Z?>8-?U~CKc ǀAi]W xne?N< O7Gc߇>XcD t,|1q?Z>?o2'cX7=~?诠?>8-? xn!|E} ǀAiXcD t}V?m.ߏ+e?N< O7G2'o{iv?_@,|1q?Z?>8-?U~CKc ǀAi]W xne?N< O7Gc߇>XcD t,|1q?Z>?o2'cX7=~?诠?>8-? xn!|E} ǀAiXcD t}V?m.ߏ+e?N< O7G2'o{iv6xo9sjYD0xD!7Ut]_@,|1q?Z?>8-?Wխ=~?|uwßV4 ImӝЪ%D%Feʐ?7c%Gm:{;m6FmnDZ^M[yV4"1>5?g[*5 K]FK=R;jf)s|BEo1Oa{AY|㏈xWĖך~_2l~.-#˲Յ$s5A<[^~%5OZ7qteip juj1/ٞI-"u?c8ʭO?77Yn7Doݷvy?~|O- *H4t O3O.UcM;Y؞I4'sOYؼP.  }6 e|-cZ{p{W ,nste<Ԯ/?FSt7mL i7 1vc{%2NЗWp~ZGR'J7~PiEW{aEPEPEPEPEPEPEPEPEPEPEP\^;M,~IFs0?eVuãc"K+?xvVf>Iwu.*(ԻpI+o4 H|gYU#gY$Yܸi"_"3B& ٤kP3m$ V Zu|Tfŵ@YSz͇TMҁbMF4i~*_j줾OIhoiGQ|2vRK6=.(((((((((((((((( Ox~u]J;=;LyR($+탠c~鷖Zvo:G+ê}r+^5]Qk9ldR!G\V"3uo'ox6ޡGcqߢjNY|ہ{c0] ɪܛyQ wKֻ=35ொ־寍m4/W};&4JYӭ, fx\Iua)GDS|%u<FEYIj*0^դ%^V}H15u%KI/K>EWaQEQEQEQEQEQEQEQEQEQPjZ\^^\AiiiM<88QA,DžP$%'dS9/_VPj[~o?=V"aҹzmޝyMJ{mW  Zڲ$<5S̲.q.kZ뺊V)H2h:kZ%h.O}Ǥ.(d+?i<Kᷛm4F[8*k6s:+xjnzI|qU»\=VzJ7IEQ^i;^?馇?ǓgJ`za~ZTѧiu{=C1W*)-{sFIJ2NU{=B(C(((((((((([hByQ]mom]{EQ\(QEZ'hmmHGnbXwfHl|BI {ǟ>6O?ڛDwVmMGRCο:&m9${?IWm.3\ Ksqq4UcH  w_~#__[/joxZ}1QCb#\ciϫZ3ڏU(b#s\ڶON7SNOkۃ )*䅯ٵ* !S,0Q*=|GRQEsaEPEPExnx' Y ֵXM.CO~xq}P[\I%o+BIRhxOϋ?e3Zw;HzަDGm%Ǽn,yaRn3z nwc$jzx<+*FҵڝSc_"7iLPO MHQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEs,xWw/S_xޣaiHGO3,iGD:: ( ( ( ( (??x䟳#?;|Bҹ־ȇs]tEt OR~!\ի| ~iҧ4SFEPEfÞ ='P-%LxQtBMT]ۛs0QEqY\:g3*_Fʅ= SGrqޙ.z}lyώ٭-K٥4J|4ȷ>g-̡~[gfp/ymu ^I&qO.__-9^4ڽ>euvQEzQEQEy?Ĩ_Oȍ+LyK֋gMNm-^%Jnee$A p߳yaj no5L{]]\j o6FTcUڥ'6i.M|t{Fw{Q-QE QEQEQEQEQEQEQEQEQEW|e x;oks'-ekcsgdB: [#еjz5ޣXi̫6"y؀ $gF{y1^4߻\u)I_:jzZ%xbOmƃng䷗I%{⾟j?_:,iW~ϷX;Zy{qjی_/+.4MJDK/: # G5߃Ƭe)Iy]Zu!֗zd-KmԿzi|k@H8 _}_Ox-32ƿTku`+((w|9'u=%m3_iդsK4fQ#,g_PrMSoPuomXn5SRZwWy%x++HށEx''Uu'|,Qn>:O~*!Ҽ=gg|S<h5_2eY{ΡH((((((((((((((((((((((((((+mO-/N㙋kX[i/%mnM)]Pa\ƿ <+o:~ivv^XtwMyy(ktiJDfnxVkuJ>|2X5GiG ~ 1AxhZ9`i{7<mmO| xPg/xoo26O!+/́ұ#OH ` ( ( ( ( (??>x俳:Bҹ~ȇs]tEt oR~!\ի| ~iҧ4SFEPEPEP^~?Ulz-KZG/<x'ͣ\fEyPI˰eU;C_r^*'w5Ѽ?V&6aoxXGMkk$t n >(/R4Ev}_ʥZ5Q\/(ʒvz4]I;lgŘ^=e[K'gEq?\-gK잸mf.dhҌ+cU=S[IJm$v2gְ+Io$e~Y&v(;B((((((((/U J|4ȶ}>g~b5W*I%>_wd[3̖P- +?}͎ܿWMs&O|r׸ߓj?+PQEQEQEW|ig$?ƍ|peԘ?c+)VڋYz]Vִ[?hzvimV1,Ut`C+)  kT+)^/I.z5mGg1bu%/I/[l;>+gjF<ktlwX3+I#mwox6^Q<=iRnOTדM5JwϣM^2^RM5Š(c((((((((kZ՟kGQ!{V(mE,;UTI 4&vʌ\UVu'a:mr^y+"I/*O|U'xN)!Ilm.6MV 4(EQmt6;4d׬vLnhN+c?+ ?>@^hvٛ6m:ŬOG#k8>wZ9$-"{7܇OKw cᬼ cM33'ɞv><Ϫpwt7oM.,mC&&&%`z]Q^QQ@Q@Q@Q@Q@Q@Q@yƟ1+k>'*\.6ZɌˀ]è!WqOi<kmB- > A'kGþuxPy'#;MLokh| %7@i>xtj.#i2|_k'M5i\((((q`'SÚJ~C | -R$_޾hn((((((((((((((((((((((~~ Zt7IjҴZE [^^0X4) WR+ox/Ú>(FW|? i~gشNO$idV4#e@A >$O ]h_5YMWY^$nmd9$')ԣ$ľSgO h Z_ݶI /]%r^^J#O6RٹŠ(((((((((e"u+ɿgH??usW2߳:BҹW񿙒V?OPiҧB(Y=+Ǿ-wLZPT),2ऑ3+# օ9<k㸮}OKj>{ "=>zGcvGMٗK҂AiutAq%:ֱψxJ>3:ZC=_OtZɤ=N9^&[fHO N+c?+)|KӾz.;b4+rȱ.e8'ˍfl*rKӾ0|OGxO~*Qkz~<hϙg{ 71eF.UQEQE|QM7]c{ -v!B\*ydU.!=ϊGFTg}VkOT4ˍCBT&R[$J./I)xwV~+῰϶p#+tt`X20 UgFɟN ȷ|$hD8L@9e4v*ګem&%2\jJI&dQEz!EPEPEPEPEPE[x'@PIQ$VCKb%ByeP[,ʠj UUӣNUF)%g?o,/ σˬL}TYD8|MZ)F;WNdҽ͹o'Jy^{/seS<ͫ ~kTcwʎNSX|3*wQ{sw]}uQQoQ^yQ@Q@Q@RړOUkx뢥ޟEvzTG}- pȪ\^_jzjV$uXIg~<7CxH#27R 1פ~ɐ> =?Ǩŭ:eеDHwE}0\34J r۝R.[ǭ>3Qc}m{ۿɿs?#U>Zx~V_kWþk -?WUeu>nETQEQEQE|E~? >+ۿO|-/|mᯊjW?-˙7ޣkS@?l8;ʭ+((((((((((((((((((((+?t|.=4idnvOJ|=?şSP-*]7PMd@nb-WX[i n5(eK I\{W$ __7eݰ{'x ºfi~hXi}[Z[ā"(4EUTP d~__<_O½ͦV4<d^kXY'n:M*7oxWLд-3OtM+ ?OKk[ x$PƈPZPEPEPEPEPEPEPEPEPEPEPEP/뮏^M=Ac/+gw?GW@& Z̗G궛1*zM=djQEQEWwX#ݶ=z6{r#67zBl-/&󭼫kCyhl׊ok.{%Z~ɝoKhdKcx!"W~q_[A)]ƿw} 7 ?Ğ*ҮgtY)Gh"9S^a_?j?+5ObMFBg˞hlvFE}?EPEPEP_<'m _i7O<1^DZgMvKtle]"|9eω}E X/dӵu ʠڲ$3 F:m΃<^,ҭHZTeQңFw4k<^^6.6 eik{$m[c,=EWxj$4* 7Rt{;..YG20]XpAN2RJQwL%$tŠ(PQEQEQEQEW&_yv:JNP_F+|4r#4+#ewz_j9Y4RD{Я+q!fƒ|I}7MѴ{;;x---#X` (QTpb9?6/H'T$x?q^ MzGI'$QEzQEQEQEQEQEQEs_>uf\W}=חDMQI^ʒ ',O4z{6_1m*bvM #IɱDFyoG Zg-k2!s$2yFwI *#ala$x9=n+$[J+Dg%vwrs4Ƣ(h&z[E֬IZj:uݵ \[JsdI A 5J.-JDdQE ( ( ( ( OzD&)ۚJC |N51j1bg'޾̑b̞fXt7uy4?Ic~oY4xwOY~An/olȝ{ iQ4{h;q M^MF[co 0̚O(((((((((((((e"u+ɿgH??usW2߳:BҹW񿙒V?OPiҧB(Y\ºgjjv iUggXLHe"r2N G zχC|@čkھ$#i+gs, qhF]-'ao-SU1x)\xR{}F[9mb][e ,S7P^~?Ul{xo'XU”QEQEQEQEqJcRutAç}hn?uTmw]]$d`C#)ᔂA ssoxn{B9_Gr҃Rs;!/休)pZ_*sÓOoG'ftVO{7O.K+=(((_)"v}saFHD]HʬR(}/YSGo" Agvb3*$XǕ~/WZغz,MEI ̔Xכը;M~U_OvHbjJS;T{-ߑ=$FEx?Xv}s-ُaF HD]ƬR(MͰڢBiTՒ[WvFb/VzB(MŠ(((((((4?=_ooOfɶ0 U;d25k8mkE&wj6}/muks N^7F2 o;/$8EJ?b2LsFi8UO W*$VoY^oP,B4U保%zwSe6 (((((?4Em}mrЬVxL6LDMK o<Ѣaiw\,feH$FHw\φOĺx0 FciamLpȱfu+#m ⮫^ u[7&_I\Eq-!81+'cn>~@𦑥|U~}VCJ|4:Z3/ʞ}XE!>@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@k¶ύ|CkiGxl4חʶI&Fn+??L?Kx&I|Uf^*Ԡoiaʰ!%Tv xtrh5~o[}gƾ! KӴbZ룼V6VkDo[[JWj#7~)OB|>:M,sxOɥ}#~ 1AxhZO F1Ec27uV$isQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ C?y7)Gj_!]Q]{#__W5j72_ox 7i|QsIޟ|Ur32ie9̑U\*?c8ʭ((((^"퟊y/HԆGV C+*@5v8M]={5ّV*AӨVi{r:nQ%oc% ](%DP$r;q1e KMt;x..hgdG20!A /Gu߆/!|=)zLIȨ_xD|ӝ>qZ/5yl֫毀ѩTYN>YN>iiEsxQ}9^}?[3,Uf$+8C gx k^ҌnO hIIw]>uOU(Ե+mN6yqpYُ I<+iIE9I#iIE9I"zg-!$$3---k%bI K쨬ß~>lm!_|2: N.m Q}^3Ϊ!IJ##sF,OW_}y]YSzQ wk{W\_Qյu-7  I{M3*UWdC,F1tQ]l4hǖ:ovK$I$^ <bmݷw%I$EQ]PQEQEQEQEQEQEQEQEVg<x×Vo+HIXB9Q]$FWGEeeeiWN%8;5ktU9RNkfF=~#^|7m<9Ig{Iai`viy<7 #[AU[ZlI]ڍ ]ZIJsWс  A=s_~iC7W,nX:edV䡋-BT/G7Oc S;FPo~WoiAr+ǯ|MeҴrٵxMƋvcW̚uKB e6WRzaPvi3`{,L%I0kV~ѮFOneXUPI$$1Qf1Qe"|YѾoz4[gFun䷉wmޥܕ%%xVq~&~އ)8YWѕOe`OG*;Yа[a1?lRAj{&#"c(;m(%jUu +4PJ5.FFr¾Ϡ((((((((((((((~ Ϩxh7ju=~w+C[7<xYE#*qs\!hcş?|+NƝRBZ\lx9f;?g|YWm Oյ{giJȒKx_ʏ2>RÀIչIeh˞?&m__uBVu'xڕܒ^y+#&*k߄QBuD~֗^OIf3h-$n/L3/ƽ+k㏈wx$ Dk{;i.%H) #,5_/wOſ xK/2GMWv6ol{;)EKDm*es#@hxeo~???dGHow[<=n|ߓF>}hx?"(?3P c<5 co_Heh)y~oϟfcv? <{oOUOx7WGνwy_g>oˮ/=^E|K~ο:u~ߴÚUů# rQ"{vGpQ@7Gc@VY~0|1^PRlG٬绑.X-yY8k`(?"(?3479s c_WR?6߳g}o}?fyvϓm}?E|~=Ӓ]6kV&H/;K 8Wf}i>Ɵ> |S>*x:u eƓyj1myZdq-<̹tـ$ҔW#,֟?-%򒴗ml7=Jk׻58KUtlVkR|kG _>מ ~3k뉼'?|+i:i4&𮧨Y:wai-eZX"i#LFa~"XӼCK~VOxb6^=Y}w}>Ͱ> oG٫W59}eψ~Gho&5&ՠݽ(T _H'c#VOIt;7{>ų~^45x?oD̆[ϳ]K5Dr7#/=G1_;z?k,׊;4?ivx+\[^i5M,Z|O0jj0V3N/=^E|/$~{'$:G~bhwsG1쮃/=^Ex1_;zU U$?ZG|O<yg~gϳns_O@ oG?Qek[:74WIjQbχaӟ@>ח$I_׀|/p~O y[Mg~[ ̼m;6eGxkg?"(?3K79mwc_WMGΑ߳g}W}?i3yNu}?Ex1_;zcv? <{%WI|Z>"xxuB? ";1yrl.|8] L@4?vVGjy?_+?_/_o}Ewah^5_ix6WQYm|>L\d;nH5hx~ڇuA52릙ok@R+SƝl[P"H k +gGx~JԼ UҥI7Z^yqsyi&ػ, 7Gc@W?$~,#G~Mmhw۱|Gﯧ7Gc@W?/$~{'$:G~bhwsG1쯧7Gc@Q oG>`OoYNkeZCx7+GO;|65E?Qg<33O+> 5] W>ZZ3qK]57r?S?n$-C'|> M֭MMw`M6x88(ӭZܹZJ;oNxX=iT"/<])=ݵIl~ޟDÕ_k5M~q]a|[gz!q])s&(5 ( (<мmOv>^o]oP oج:u42\GU?6)Ə}nOUQ.nnTHEn/7 WQ@d~Uo]{|E~>kn>1ӵ/:WUUsVҢ♟uܖve8{7m` _| sOg x6oo25? +/́hnmұ:HVh?|A'xd~BqϪjq&ukk%$m7W|? i~gشNO$idV4#e]q>7tƍij:{b[ۇ-54nnI+ݛ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (?>ȇs]tEt oR~!\? C?y7)Gjod?USox#P(((B MVOţrKqpfiYy\_{Q@Q@Q@Q@yOڏ컍?ƷOA.$3Zvr|D)ϋkrM:KP?n;gk x?J4/:Igm C^d>Ws1I'& ((((;6𧅴aI?'A.w-H }JxGV*X_jX:{oq_1Qph 9C{m'g/֟?C\Sj>4٥B Z[3?eb c;KGbQ yt~󵯳KucNȲlfC_qԤuRN)R|ѩ+8O&Z[ ~MP68 Zv;g%y'? J3r>ߩi ]JTO (8(((?h~#w4QzFWU/5[==+F<kAxRy2q|Ex➣n6~)o0|U5m+W}A4xùe`&AQEQEQEQEQEQEQEQEQEQEWsFo\{h$5M/[7W?eݼ?7@ĉoxWe}*俷cj1i 3{J|USF|bw.&2Exr71K?-Jb7q̲T?|UA|tΑ? ¯6X_͑yadUxtJ4f~Ҽ]3Bд?E4[H4>-l-@CHG"(@hP'x ºfi~hXi}[Z[ā"(4EUTP Т(((((((((((((((((((((e"u+ɿgH??usW2߳:BҹW񿙒V?OPiҧB((((((((((((((((((((((((((((((((((( kᯌ<M)4FW KBiVK5 E}q_jsPYΔf{;0u(SzJM&z]%fi;7|+  #2(?!me|E u~޾Tc~5ZҫRU%QEQEQEqW/ V|E{vAE,c\n&H kiH-uĽ'P?kO[O~|PkiĭB5?_r{Yx+ Uӵ[30-#lbgWc4k{J 櫥y L9Xc}68$ ( ( ( ( ( ( ( (ŏ %|ko?__[a-<(e7HqgP9 PAY,f/ z.Kj mkaoier8 $+?#oDUVyƟT1XaOq+kukEpV%x$b+YV⿊ZUZ)˸KVA)ȼ\jQ3D%PW/:D/,/$ocCǟa浅 !ӯ!.#cq??t}O.=+fdfnvA/Mn/|o=((((((((((((((((((((((((e"u+ɿgH??usW1n"jS^%Ju+gn1les-`$p35/njJ[Ogwr?s_=hs??5Ç'+Aο{њ~ÓFk9OWH*+5Ç'+?sM:TWFk9OW w9?_G#u#ب?s3\8rG4GQ^; w9?_G4f߃p}h9bw3\8rhs?9sEx4f߃p}њ~Ór?_=hs??5Ç'+Aο{њ~ÓFk9OWH*+5Ç'+?sM:TWFk9OW w9?_G#u#ب?s3\8rG4GQ^; w9?_G4f߃p}h9bw3\8rhs?9sEx4f߃p}њ~Ór?_=hs??5Ç'+Aο{њ~ÓFk9OWH*+5Ç'+?sM:TWFk9OW w9?_G#u#ب?s3\8rG4GQ^; w9?_G4f߃p}h9bw3\8rhs?9sEx4f߃p}њ~Ór?_=hs??5Ç'+Aο{њ~ÓFk9OWH*+5Ç'+?sM:TWFk9OW w9?_G#u#ب?s3\8rG4GQ^; w9?_G4f߃p}h9bw3\8rhs?9sEx4f߃p}њ~Ór?_=hs??5Ç'+Aο{њ~ÓFk9OWH*+5Ç'+裑M:wku??9TnS@x3֑yskie"59ǙnQW{CS|!c-RZ5)Mӫ-Vq4¬Jm4kTd6?uop'z”_V8(Š(((?d*@d ?m٧^i^6/]W_:W]Wog1ƲL#c1QEQEQEQEQEQEq?x7t𭾳_|s1{b++t 57I++Bk𭾻wvj$mYwDi G#$FS^a _g~ [7<K5VK >U ,WM ss]OUq☠[x|x50 \wnZkWů>?< !ֵ{omǧiT1,>M"H$X$@)$c/~2C q}Tyt S@$99'`x2'ì=\e'dOR&~~ɫeю1JY_MRwo]Mx}g_c>_xW O ?F!~,|@^U~VCJѼD;^7Ğ}̹F%}_|^ƍ*VZxo7wx<4a"RK)o(((~ Ϩxh7ju=~w+C[7<xYE#*qs@^'5߳jiWy; am#YI~ QGڊXp_}?tk|E(Y\Ҭ )aD9 /\'7/jy;nԮY83Q4ڊp}i?? ?ct}7l[2O\xB 6$&]|Y3u-Fk#YE! wf>EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE~/gr?y&E?ZX|M8M Y6_\쏯㟊@cIᑼAC?.5I,B?X4 c/C6՛˒+wul >xmGV |RԴeV|,5:q z뺁Oofc@-Q/C 7,ĺtS\x┎8GO]`xch{?|hŗ!\G2C?.5I>¸PC_/w~gJC |N51j~'zT_޾Ȏ肊(,(((=GlS߇7`djW5-V H2iv[s˹8̑˂Xtvv'My i)oׅoZ ,yVd2 <+qx+~ivڎ$*^XtDMyy(<ۛiJwf (((((((((((((((((((((((((((((((=Գ=4oE*?dT9 o/<]S=Կ릍\%?;Ouu>&E?`ilakҧ̓yF1*z?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<?`kQ_ʧ ̓yGl*6濕ٰ5z(?Tf<4WLDk[9^QzBz&G[H)ܵh?}CtNo^_ʼlWٰ5 ku??9T??~sP@_޾Pkm٧ľ6]W_Wl5]+o`Q) WGWeVP qK'wו7sxUoC\v,gZ>hz/iWr麂h$Z.sjI/>qG*X̕C~_ ;[ 5"?,[\bx5{B&>p!y >? ^𮙡hZf-V~anֶ H$#UUEI[NJk'=+^4- L]EO-$ 1D$q*VQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEOs$R7s7<]I=Կ릍\%?;Ouu>&E?cҧ4SQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEy&G[H)ܵh?}V?(أ?aO_g-ʽvlWEP 5o:?ŪWku??9TO~sCo_Uʞ6?ur]Y]QEQ@Q@gڦƞޡ9~x__h:eͥ[͠kFV S"KC+ y0͵@ICi%5/xxzx~,ѼIuTZ/{WgI#; :L,ж(w[gz_(xžֵM ğ|WZH4XQu0'q`>h ^V.om3^FK糏a/RLώ??m^?_?|: }*K[-[׈4 *[Ǩ$yY' ykߠ9t*ijRdBC(9*t?c?xPô@-> u8?~wi-?֜Vx}JXLHe"r2OPô@-i:[W@(|4]i_>!OptMG\xB㟍M/KVLF:z1#i:[W? 4Zί࿇> .8{?_1}qjz$^9^n/~9$%IR!ԣO.u R"C#!y(?c?x՟.j:LxӢӮ㟌Z=Q  ɩ;aI}F ̑}?_1}qj?c?xR7?b_x>=CfH4z j$0ǫ%$}=I5‡-PH|4X_o:w.o6sO5C}H-K1ga];O oڹ%7?[>s#rM{ۿZ+W-i>u[X,7 |/m٤}[5%׀MGItZu\\[sG!X5'u<00os94?c?xPô@-??K:t]x֥{4y%HRmo¾_ZŽp{.$2gFH.ry=xz?c hi1iz:<gt0ՂItJIvCop>@Q@Q@Q@Q@$?Ou/-W7#@!tKhhUP1*zM=AaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP~iQտZMZ oM/:^S{ɹk_a@6kȿf[?zQErt?!>5GƯQm&y5Eh]8݀gb_׃|f>Xƣ?+qQ|*]O?3 gD?[WV}^Ck~M6QE ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (>:u!g-@g7rt'/⸝Er287=B]'j&&馍\i|B* ?wjsMEX M(>5?-~Y(Aҧ __ʯ=O/K GCo&Z:5bT}//Gz_̗?r,Mt?fj/ __ʏcK=O/K GCo&Z:5bT}//Gz_̗?r,Mt?fj/ __ʏcK=O/K GCo&Z:5bT}//Gz_̗?r,Mt?fj/ __ʏcK=O/K GCo&Z:5bT}//Gz_̗?r,Mt?fj/ __ʏcK=O/p}UW24xSTDQlpa O~Vq/0 j޿nZt/>ViMG͟t*/ٳ@^XQ@7ٺMB\[gk:I B0kTq~? 6j: S}IzOM͟Jw}amWXZxS.,-d| 5 k++8:?wek+^ҧ4S ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (<Ubr zɹkпa]i&3MSHr;¹)6kȿf[?z`hQEsciscipy-1.0.1/util.c0000664000175000017500000000535412032035556013576 0ustar vinszvinsz#include "Python.h" #include "util.h" #include #include #include #include "api_scilab.h" const int sci_max_len = 1024 ; static const char* SCI_ETC_FILE = "/etc/sciscilab" ; /** Return the scilab type * * Returns the scilab type of the scilab variable name * * */ int read_sci_type(char *name) { char job[BUFSIZE] ; int m, n ; double type[1] ; SciErr sciErr; snprintf(job, BUFSIZE, "_tmp_value_ = type(%s);", name) ; SendScilabJob(job) ; sciErr = readNamedMatrixOfDouble(pvApiCtx, "_tmp_value_", &m, &n, NULL); if (sciErr.iErr) { printError(&sciErr, 0); } if (m*n != 1) { return -1 ; } sciErr = readNamedMatrixOfDouble(pvApiCtx, "_tmp_value_", &m, &n, &type[0]); if (sciErr.iErr) { printError(&sciErr, 0); } return (int) type[0] ; } ; /** Check if a matrix is real or not * * Returns 1 if the matrix is real * */ int is_real(char *name) { return !isNamedVarComplex(pvApiCtx, name); } void sci_debug(const char *format, ...) { #if SCIDEBUG == 1 va_list argp ; va_start(argp, format) ; vprintf(format, argp) ; va_end(argp) ; #endif } void sci_error(const char *format, ...) { va_list argp ; va_start(argp, format) ; vprintf(format, argp) ; va_end(argp) ; } /** Put a Python object in a list */ PyObject* create_list(PyObject *obj) { PyObject* new_list ; new_list = PyList_New(1) ; PyList_SET_ITEM(new_list, 0, obj) ; return new_list ; } ; /** Return the root directory of scilab Tries to open a file SCI_ETC_FILE and looks for a line SCI=where/is/scilab_root and return where/is/scilab_root sci must point to a big enough allocated space */ char *get_SCI(char *sci) { FILE* fd = NULL ; char var[sci_max_len] ; *sci = '\0' ; fd = fopen(SCI_ETC_FILE, "r") ; if (!fd) { return sci; } else while (!feof(fd)) { char *str = fgets(var, sci_max_len, fd) ; if (str == NULL) { goto finally ; } var[sci_max_len - 1] = '\0' ; if (strncmp(var, "SCI", 3) == 0) { char *ptr ; sci = &var[3] ; while (*sci == ' ' || *sci == '=' ) { sci++ ; } ptr = sci ; while (*ptr != '\0') if (*ptr == ' ' || *ptr == '\n') { *ptr = '\0' ; } else { ptr++ ; } goto finally ; } } finally: fclose(fd) ; return sci ; } sciscipy-1.0.1/sciscipy.c0000775000175000017500000001100212212710371014430 0ustar vinszvinsz/* This file is part of Sciscipy. Sciscipy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Sciscipy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . Copyright (c) 2009, Vincent Guffens. */ #include #include "sciconv_read.h" #include "sciconv_write.h" #include "util.h" #include "deallocator.h" #include "call_scilab.h" static int Initialize(void) { int res ; #ifdef _MSC_VER res = StartScilab(NULL, NULL, 0) == FALSE ; #else if (getenv("SCI") != NULL) { res = StartScilab(getenv("SCI"), NULL, 0) ; } else { char sci[sci_max_len] ; res = StartScilab(get_SCI(sci), NULL, 0) ; } #endif if (res == FALSE) { return -1; } else { return 0 ; } } /* Python interface */ static PyObject * sciscipy_read (PyObject *self, PyObject *args) { char *name ; SciErr sciErr ; int var_type ; int *addr ; if ( !PyArg_ParseTuple (args, "s", &name) ) { PyErr_SetString(PyExc_TypeError, "argument must be a string") ; return NULL ; } var_type = read_sci_type(name) ; sciErr = getVarAddressFromName(pvApiCtx, name, &addr) ; if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return 0; } return sciconv_read (addr, var_type) ; } ; static PyObject * sciscipy_write (PyObject *self, PyObject *args) { char *name ; PyObject *obj ; int er ; struct sciconv_write_struct *conv ; if (!PyArg_ParseTuple (args, "sO", &name, &obj)) { return NULL ; } Py_INCREF(Py_None) ; conv = sciconv_write_list ; while (conv) { if (conv->test_func(obj) > 0) { er = conv->conv_func(name, obj) ; if (er > 0) // success { return Py_None ; } } conv = conv->next ; } return Py_None ; } ; static PyObject * sciscipy_eval (PyObject *self, PyObject *args) { char *name ; if ( !PyArg_ParseTuple (args, "s", &name) ) { return NULL ; } SendScilabJob(name); while ( ScilabHaveAGraph() ) { // Py_BEGIN_ALLOW_THREADS ScilabDoOneEvent() ; // Py_END_ALLOW_THREADS } Py_INCREF(Py_None); return Py_None; } ; static void numpy_init(void) { #if NUMPY == 1 import_array() ; #endif } static PyMethodDef SciscipyMethods[] = { {"eval", sciscipy_eval, METH_VARARGS, "eval (cmd) : Execute the Scilab command cmd."}, {"read", sciscipy_read, METH_VARARGS, "read (sci_name): read a Scilab variable."}, {"write", sciscipy_write, METH_VARARGS, "write (sci_name, py_var): Write a Scilab variable."}, {NULL, NULL, 0, NULL} /* Sentinel */ } ; #ifdef PYTHON3 static struct PyModuleDef sciscipy = { PyModuleDef_HEAD_INIT, "sciscipy", /* name of module */ NULL, /* module documentation, may be NULL */ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ SciscipyMethods } ; #endif PyMODINIT_FUNC #ifdef PYTHON3 PyInit_sciscipy(void) #else initsciscipy(void) #endif { int er = Initialize() ; if (er != 0) { PyErr_SetString(PyExc_TypeError, "Can not initialize scilab") ; #ifdef PYTHON3 return NULL ; #endif } else { numpy_init() ; sciconv_read_init() ; sciconv_write_init() ; #if NUMPY == 1 _MyDeallocType.tp_new = PyType_GenericNew ; if (PyType_Ready(&_MyDeallocType) < 0) { PyErr_SetString(PyExc_TypeError, "Can not initialize deallocator") ; } Py_INCREF(&_MyDeallocType); #endif #ifdef PYTHON3 return PyModule_Create(&sciscipy) ; #else Py_InitModule("sciscipy", SciscipyMethods) ; #endif } } ; sciscipy-1.0.1/sciconv_write.c0000775000175000017500000003613212075466515015512 0ustar vinszvinsz/* This file is part of Sciscipy. Sciscipy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Sciscipy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . Copyright (c) 2009, Vincent Guffens. */ #include "sciconv_write.h" #include "util.h" #include "Scierror.h" struct sciconv_write_struct *sciconv_write_list = NULL ; /** list of string * * WARNING: This will not work with Python 3.0 */ static int write_listofstring(char *name, PyObject *obj) { int i, n ; int tot_size = 0; PyObject *item ; char *str_item, *buff, *ptr ; if (!PyList_Check(obj)) { obj = create_list(obj) ; } n = PyList_Size(obj) ; for (i = 0; i < n; ++i) { item = PyList_GetItem(obj, i) ; str_item = PyString_AsString(item) ; tot_size += strlen(str_item) ; } buff = (char *) malloc((strlen(name) + tot_size + 3 * n + 3) * sizeof(char)) ; ptr = buff ; strcpy(ptr, name) ; ptr += strlen(name) ; strcpy(ptr, "=[") ; ptr += 2 ; for (i = 0; i < n; ++i) { item = PyList_GetItem(obj, i) ; str_item = PyString_AsString(item) ; strcpy(ptr, "'") ; ptr++ ; strcpy(ptr, str_item) ; ptr += strlen(str_item) ; strcpy(ptr, "'") ; ptr++ ; if (i != n - 1) { strcpy(ptr, ",") ; ptr++ ; } } strcpy(ptr, "]") ; SendScilabJob(buff); return 1 ; } /** */ static int test_listofstring(PyObject *obj) { PyObject *item ; int n ; if (PyString_Check(obj)) { sci_debug("[sciconv_write] Match for list of string\n") ; return 1 ; } if (PyList_Check(obj)) { n = PyList_Size(obj) ; if (n == 0) { return -1 ; } item = PyList_GetItem(obj, 0) ; if (PyString_Check(item)) { sci_debug("[sciconv_write] Match for list of string\n") ; return 1 ; } } return -1 ; } /** * @param name: the name of the scilab variable we want to create * @return: negative on failure */ static int write_listoflist(char *name, PyObject *obj) { int i, j, m, n ; double *new_vec ; double *new_vec_img ; PyObject *item, *element ; int is_complex_found = 0 ; SciErr sciErr; m = PyList_Size(obj) ; item = PyList_GetItem(obj, 0) ; n = PyList_Size(item) ; new_vec = (double*) calloc(sizeof(double) * m * n, 1) ; if (!new_vec) { return -1 ; } new_vec_img = (double*) calloc(sizeof(double) * m * n, 1) ; if (!new_vec_img) { free(new_vec); return -1 ; } for (i = 0; i < m; i++) { item = PyList_GetItem(obj, i) ; for (j = 0; j < n; j++) { element = PyList_GetItem(item, j) ; if (PyComplex_Check(element)) { is_complex_found = 1 ; new_vec[j * m + i] = PyComplex_RealAsDouble(element) ; new_vec_img[j * m + i] = PyComplex_ImagAsDouble(element) ; continue ; } if (PyFloat_Check(element) || PyLong_Check(element) || PyInt_Check(element)) { new_vec[j * m + i] = PyFloat_AsDouble(element) ; continue ; } sci_debug("[write_listoflist] something found" \ "that is not real or complex") ; free(new_vec) ; free(new_vec_img) ; return -1 ; } } if (is_complex_found) { sciErr = createNamedComplexMatrixOfDouble(pvApiCtx, name, m, n, new_vec, new_vec_img); free(new_vec_img); free(new_vec); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, "Cannot create complex variable '%s'.\n", name); return 0; } } else { sciErr = createNamedMatrixOfDouble(pvApiCtx, name, m, n, new_vec); free(new_vec) ; free(new_vec_img) ; if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, "Error in Writematrix"); return 0; } } return 1 ; } static int test_listoflist(PyObject *obj) { int n ; PyObject *item, *el ; if (!PyList_Check(obj)) { return -1 ; } n = PyList_Size(obj) ; if (n == 0) { return -1 ; } item = PyList_GetItem(obj, 0) ; if (!PyList_Check(item) || PyList_Size(item) == 0) { return -1 ; } el = PyList_GetItem(item, 0) ; /* Only the first element is checked, the converter will fail later on if all items are not real or complex (This is for performance) */ if (PyFloat_Check(el) || PyLong_Check(el) || PyComplex_Check(el) || PyInt_Check(el)) { sci_debug("[sciconv_write] Match for list of list\n") ; return 1 ; } else { return -1 ; } } static int write_listofdouble(char *name, PyObject *obj) { int i, m ; int n = 1 ; double *new_vec ; double *new_vec_img ; PyObject *element ; int is_complex_found = 0 ; SciErr sciErr; if (!PyList_Check(obj)) { obj = create_list(obj) ; } m = PyList_Size(obj) ; new_vec = (double*) calloc(sizeof(double) * m, 1) ; if (!new_vec) { return -1 ; } new_vec_img = (double*) calloc(sizeof(double) * m, 1) ; if (!new_vec_img) { free(new_vec); return -1 ; } for (i = 0; i < m; i++) { element = PyList_GetItem(obj, i) ; if (PyComplex_Check(element)) { is_complex_found = 1 ; new_vec[i] = PyComplex_RealAsDouble(element) ; new_vec_img[i] = PyComplex_ImagAsDouble(element) ; continue ; } if (PyFloat_Check(element) || PyLong_Check(element) || PyInt_Check(element)) { new_vec[i] = PyFloat_AsDouble(element) ; continue ; } sci_debug("[write_listofdouble] something found" \ "that is not real or complex") ; free(new_vec) ; free(new_vec_img) ; return -1 ; } if (is_complex_found) { sciErr = createNamedComplexMatrixOfDouble(pvApiCtx, name, n, m, new_vec, new_vec_img); free(new_vec); free(new_vec_img); if (sciErr.iErr) { printError(&sciErr, 0); Scierror(999, "Cannot create complex variable '%s'.\n", name); return 0; } } else { sciErr = createNamedMatrixOfDouble(pvApiCtx, name, n, m, new_vec); free(new_vec); free(new_vec_img); if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, "Error in Writematrix") ; return 0; } } return 1 ; } static int test_listofdouble(PyObject *obj) { PyObject *item ; int n ; if (PyFloat_Check(obj) || PyLong_Check(obj) || PyComplex_Check(obj) || PyInt_Check(obj)) { sci_debug("[sciconv_write] Match for list of double\n") ; return 1 ; } if (PyList_Check(obj)) { n = PyList_Size(obj) ; if (n == 0) { return -1 ; } item = PyList_GetItem(obj, 0) ; if (PyFloat_Check(item) || PyLong_Check(item) || PyComplex_Check(item) || PyInt_Check(item)) { sci_debug("[sciconv_write] Match for list of double\n") ; return 1 ; } } return -1 ; } #if NUMPY == 1 static int write_numpy(char *name, PyObject *obj) { PyArrayObject * array = (PyArrayObject *) obj ; double * data ; double * data_img ; int i, j, m, n ; complex * item ; SciErr sciErr; // TODO: add support for 1D array if (array->nd != 1 && array->nd != 2) { sci_debug("[sciconv_write] Only 1D and 2D array are supported\n") ; return -1 ; } if (array->nd == 1) { m = array->dimensions[0] ; n = 1 ; } else { m = array->dimensions[0] ; n = array->dimensions[1] ; } if ((array->descr->type_num == PyArray_DOUBLE) || \ (array->descr->type_num == PyArray_INT) ) { data = (double*) malloc(m * n * sizeof(double)) ; if (!data) { sci_error("[sciconv_write] out of memory\n") ; return -1 ; } for (i = 0; i < m ; i++) for (j = 0; j < n ; j++) data[j * m + i] = *(double*)(array->data + i * array->strides[0] + \ j * array->strides[1]) ; sciErr = createNamedMatrixOfDouble(pvApiCtx, name, m, n, data); free(data); if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, "Error in Writematrix") ; return 0; } return 1 ; } if (array->descr->type_num == PyArray_CDOUBLE) { data = (double*) malloc(m * n * sizeof(double)) ; data_img = (double*) malloc(m * n * sizeof(double)) ; if (!data) { sci_error("[sciconv_write] out of memory\n") ; free(data_img); return -1 ; } for (i = 0; i < m ; i++) for (j = 0; j < n ; j++) { item = (complex*)(array->data + i * array->strides[0] + \ j * array->strides[1]) ; data[j * m + i] = (*item)[0] ; data_img[j * m + i] = (*item)[1] ; } sciErr = createNamedComplexMatrixOfDouble(pvApiCtx, name, m, n, data, data_img); if (sciErr.iErr) { printError(&sciErr, 0); free(data); free(data_img); Scierror(999, "Cannot create complex variable '%s'.\n", name); return 0; } free(data) ; free(data_img) ; return 1 ; } sci_debug("[sciconv_write] Array type not supported\n") ; return -1 ; } static int test_numpy(PyObject *obj) { if (PyArray_Check(obj)) { sci_debug("[sciconv_write] Match for numpy array\n") ; return 1 ; } else { return -1 ; } } #endif static int write_tlist(char *name, PyObject *obj) { int nb_item ; int *tlist_address ; SciErr sciErr ; nb_item = PyDict_Size(obj) - 1 ; sciErr = createNamedTList(pvApiCtx, name, nb_item, &tlist_address) ; PyObject *key, *value; Py_ssize_t pos = 0; PyObject *py_str_to_create = PyString_FromString("[") ; PyObject *py_value_str = PyString_FromString("") ; printf("Entering write 1\n") ; if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return -1; } printf("Entering write 2\n") ; // py_str_tocreate = // ['a_name', 'var1', ..., 'varN'] while (PyDict_Next(obj, &pos, &key, &value)) { char *str_key = NULL ; if (!PyString_Check(key)) { return -1 ; } str_key = PyString_AsString(key) ; if (strcmp(str_key, TLIST_NAME) == 0) { if (!PyString_Check(value)) { return -1 ; } PyString_Concat(&py_str_to_create, PyString_FromString("\"")) ; PyString_Concat(&py_str_to_create, value) ; PyString_Concat(&py_str_to_create, PyString_FromString("\"")) ; } printf("Entering write i\n") ; } printf("Entering write 3\n") ; pos = 0 ; while (PyDict_Next(obj, &pos, &key, &value)) { char *str_key = NULL ; if (!PyString_Check(key)) { return -1 ; } str_key = PyString_AsString(key) ; if (strcmp(str_key, TLIST_NAME) != 0) { char rnd_name[BUFSIZE] ; PyString_Concat(&py_str_to_create, PyString_FromString(",\"")) ; PyString_Concat(&py_str_to_create, key) ; PyString_Concat(&py_str_to_create, PyString_FromString("\"")) ; // TODO // write(rnd_name, value) snprintf(rnd_name, BUFSIZE - 1, ",rnd_var__%i", rand()) ; PyString_Concat(&py_value_str, PyString_FromString(rnd_name)) ; } } PyString_Concat(&py_str_to_create, PyString_FromString("]")) ; printf("%s = tlist(%s%s)\n", name, PyString_AsString(py_str_to_create), PyString_AsString(py_value_str)) ; // creates a string name = tlist(['a_name', 'var1', ..., 'varN'], var1,..., varN) // eval the string return 1 ; } static int test_dict_tlist(PyObject *obj) { PyObject *py_list_name = PyString_FromString(TLIST_NAME) ; if (PyDict_Check(obj) && PyDict_Contains(obj, py_list_name)) { sci_debug("[sciconv_write] Match for tlist\n") ; Py_DECREF(py_list_name) ; return 1 ; } else { Py_DECREF(py_list_name) ; return -1 ; } } /** * Add a new converter to the list * @param new_type: A scilab type number * @param func: The converter function */ static void sciconv_write_add(int (*test_func)(PyObject*), int(*func)(char*, PyObject *), WRITETYPE_t id) { struct sciconv_write_struct *new_conv = \ (struct sciconv_write_struct*) malloc(sizeof(struct sciconv_write_struct)) ; new_conv->test_func = test_func ; new_conv->conv_func = func ; new_conv->write_type = id ; if (sciconv_write_list == NULL) { sciconv_write_list = new_conv ; new_conv->next = NULL ; return ; } new_conv->next = sciconv_write_list->next ; sciconv_write_list->next = new_conv ; } /** * Initialization * Add all the known converter to the list */ void sciconv_write_init(void) { // The one added first is the one tested first // so the order can be important #if NUMPY == 1 sciconv_write_add(test_numpy, write_numpy, NUMPY_ARRAY) ; #endif sciconv_write_add(test_listoflist, write_listoflist, LISTOFLIST) ; sciconv_write_add(test_listofdouble, write_listofdouble, LISTOFDOUBLE) ; sciconv_write_add(test_listofstring, write_listofstring, LISTOFSTRING) ; sciconv_write_add(test_dict_tlist, write_tlist, TLIST) ; } sciscipy-1.0.1/deallocator.c0000664000175000017500000000332512032035556015106 0ustar vinszvinsz/** deallocator.c * * Pattern described in http://blog.enthought.com/?p=62 * */ #include "deallocator.h" void attach_deallocator(PyObject *array, void * mem) { PyObject *newobj ; newobj = _PyObject_New(&_MyDeallocType) ; ((struct _MyDeallocStruct *)newobj)->memory = mem ; PyArray_BASE(array) = newobj ; if (DEBUG_MEM_ALLOC == 1) { printf("ALLOCATED %p\n", mem) ; } } ; static void _mydealloc_dealloc(PyObject *self) { if (DEBUG_MEM_ALLOC == 1) { printf("FREEING %p\n", ((struct _MyDeallocStruct*) self)->memory) ; } free(((struct _MyDeallocStruct*) self)->memory); self->ob_type->tp_free((PyObject *) self); } ; PyTypeObject _MyDeallocType = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "mydeallocator", /*tp_name*/ sizeof(_MyDeallocObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ _mydealloc_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "Internal deallocator object", /* tp_doc */ } ; sciscipy-1.0.1/callpython/0000775000175000017500000000000012212711357014623 5ustar vinszvinszsciscipy-1.0.1/callpython/callpython.c0000664000175000017500000000145711403535226017153 0ustar vinszvinsz#include void py_initialize_c() { Py_Initialize() ; } void py_finalize_c() { Py_Finalize() ; } void py_eval_c(char * exec_str) { PyRun_SimpleString(exec_str) ; } // Read an integer value // @in py_var: the name of the python var to read // @out sci_var: the return variable void py_read_int_c(char * py_var, int * sci_var) { PyObject* main_module = PyImport_AddModule("__main__") ; PyObject* main_dict = PyModule_GetDict(main_module) ; if (PyDict_Contains(main_dict, PyString_FromString(py_var))) { PyObject * py_int = PyDict_GetItem(main_dict, PyString_FromString(py_var)) ; if (PyInt_Check(py_int)){ *sci_var = PyInt_AS_LONG(py_int) ; return ; } // Handle not an int error return ; } // Handle var not found error *sci_var = 0 ; }sciscipy-1.0.1/callpython/callpython.sci0000664000175000017500000000264111403535226017503 0ustar vinszvinsz// This modue provide three function to interact with a python interpretor: // // - py_write : write a scilab variable in python // - py_read : read a python variable in scilab // - py_eval : evaluate a python string // // A convenience function to call into python is also provided global GLOB_PY_INIT ; GLOB_PY_INIT = %F ; function py_write(pyname, scivar) // TODO endfunction function sci_var = py_read(py_name) var_type = py_type(py_name) // Call the right function accoring to var_type sci_var = call('py_read_int_c', py_name, 1, 'c','out', [1,1], 2, 'i') endfunction function ptype = py_type(py_name) // @param py_name: the name of a python variable // @return: an integer, ptype = 1 endfunction function py_eval(eval_str) call('py_eval_c',eval_str, 1, 'c','out') endfunction function py_initialize() global GLOB_PY_INIT if GLOB_PY_INIT == %F call('py_initialize_c', 'out') GLOB_PY_INIT = %T ; end endfunction function py_finalize() call('py_finalize_c', 'out') endfunction function call_python(funcname, varargin) for i=1:length(varargin) arg = varargin(i) pywrite(printf("_tmp%i_", arg)) end endfunction intf = [ 'py_initialize_c', 'py_finalize_c','py_eval_c', 'py_read_int_c'] ; libn = ilib_for_link(intf, 'callpython.c','', 'c' ,'make' , ... 'loader.sce' ,'callpython.lib','-LIBPATH:C:\Python26\libs', ... '-IC:\Python26\include') ; exec('loader.sce') ; py_initialize() sciscipy-1.0.1/sciconv_read.c0000775000175000017500000003176712032035556015272 0ustar vinszvinsz/* This file is part of Sciscipy. Sciscipy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Sciscipy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . Copyright (c) 2009, Vincent Guffens. */ /* Types defined in scilab: 1 : real or complex constant matrix. 2 : polynomial matrix. 4 : boolean matrix. 5 : sparse matrix. 6 : sparse boolean matrix. 8 : matrix of integers stored on 1 2 or 4 bytes 9 : matrix of graphic handles 10 : matrix of character strings. 11 : un-compiled function. 13 : compiled function. 14 : function library. 15 : list. 16 : typed list (tlist) 17 : mlist 128 : pointer NOTE: the way numpy vectors and matrices are created leads to a memory leak. */ #include "sciconv_read.h" #include "deallocator.h" #include "util.h" struct sciconv_read_struct *sciconv_read_list = NULL ; PyObject * sciconv_read (int *addr, int var_type) { char er_msg[BUFSIZE] ; struct sciconv_read_struct *conv = sciconv_read_list ; while (conv) { if (conv->scitype == var_type) { return conv->conv_func(addr) ; } conv = conv->next ; } snprintf(er_msg, BUFSIZE, "Type %i not supported", var_type) ; PyErr_SetString(PyExc_TypeError, er_msg) ; return NULL ; } ; #if NUMPY == 1 static PyObject * create_numpyarray(double *cxtmp, int m, int n) { PyObject *array ; npy_intp dim[2], mn ; if (m == 1 || n == 1) { mn = m * n ; array = PyArray_NewFromDescr(&PyArray_Type, \ PyArray_DescrFromType(PyArray_DOUBLE), \ 1, \ &mn, \ NULL, \ (void *) cxtmp, \ NPY_OWNDATA | NPY_FARRAY, \ NULL ) ; attach_deallocator(array, cxtmp) ; return array ; } dim[0] = m ; dim[1] = n ; array = PyArray_NewFromDescr(&PyArray_Type, \ PyArray_DescrFromType(PyArray_DOUBLE), \ 2, \ dim, \ NULL, \ (void *) cxtmp, \ NPY_OWNDATA | NPY_FARRAY, \ NULL ) ; attach_deallocator(array, cxtmp) ; return array ; } static PyObject * create_cnumpyarray(double *cxtmp, double *cxtmp_img, int m, int n) { PyObject * array ; int i, j ; npy_intp dim[2], mn ; complex * cxtmp_transpose ; cxtmp_transpose = (complex*) malloc(2 * m * n * sizeof(complex)); dim[0] = m ; dim[1] = n ; if (!cxtmp_transpose) { PyErr_SetString(PyExc_MemoryError, "out of memory") ; return NULL ; } for (i = 0; i < m; ++i) for (j = 0; j < n; ++j) { cxtmp_transpose[i * n + j][0] = cxtmp[j * m + i] ; cxtmp_transpose[i * n + j][1] = cxtmp_img[j * m + i] ; } if (m == 1 || n == 1) { mn = m * n ; array = PyArray_NewFromDescr(&PyArray_Type, \ PyArray_DescrFromType(PyArray_CDOUBLE), \ 1, \ &mn, \ NULL, \ (void *) cxtmp_transpose, \ NPY_OWNDATA | NPY_CARRAY, \ NULL ) ; } else array = PyArray_NewFromDescr(&PyArray_Type, \ PyArray_DescrFromType(PyArray_CDOUBLE), \ 2, \ dim, \ NULL, \ (void *) cxtmp_transpose, \ NPY_OWNDATA | NPY_CARRAY, \ NULL ) ; free(cxtmp) ; attach_deallocator(array, cxtmp_transpose) ; return array ; } #else static PyObject * create_listmatrix(double *cxtmp, double *cxtmp_img, int m, int n, int is_complex) { int i, j ; PyObject *new_list, *new_line ; Py_complex new_complex ; if (m == 1 || n == 1) { new_list = PyList_New(m * n) ; for (i = 0 ; i < m * n ; i++) { if (cxtmp_img != NULL) { new_complex.real = cxtmp[i] ; new_complex.imag = cxtmp_img[i] ; PyList_SET_ITEM(new_list, i, Py_BuildValue("D", &new_complex)) ; } else { PyList_SET_ITEM(new_list, i, Py_BuildValue("d", cxtmp[i])) ; } } } else { new_list = PyList_New(m) ; for (i = 0 ; i < m ; i++) { new_line = PyList_New(n) ; for (j = 0 ; j < n ; j++) if (cxtmp_img != NULL) { new_complex.real = cxtmp[j * m + i] ; new_complex.imag = cxtmp_img[j * m + i] ; PyList_SET_ITEM(new_line, j, Py_BuildValue("D", &new_complex)) ; } else { PyList_SET_ITEM(new_line, j, Py_BuildValue("d", cxtmp[j * m + i])) ; } PyList_SET_ITEM(new_list, i, new_line) ; } } free(cxtmp) ; return new_list ; }; #endif /** * Type 1 : real or complex constant matrix. * @param name: the name of the scilab variable we want to read * @return: A list of list */ static PyObject * read_matrix(int *addr) { int m, n ; SciErr sciErr ; double *cxtmp = NULL ; double *cx = NULL, *cx_img = NULL; double *cxtmp_img = NULL ; PyObject * matrix ; if (!isVarComplex(pvApiCtx, addr)) { sciErr = getMatrixOfDouble(pvApiCtx, addr, &m, &n, NULL) ; } else { sciErr = getComplexMatrixOfDouble(pvApiCtx, addr, &m, &n, NULL, NULL) ; } if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return 0; } cx = (double*)malloc((m * n) * sizeof(double)); if (!cx) { PyErr_SetString(PyExc_MemoryError, "out of memory") ; return NULL ; } if (!isVarComplex(pvApiCtx, addr)) { sciErr = getMatrixOfDouble(pvApiCtx, addr, &m, &n, &cxtmp) ; if (sciErr.iErr) { free(cx); PyErr_SetString(PyExc_TypeError, "Error in readmatrix") ; return 0; } memcpy(cx, cxtmp, sizeof(double) * n * m) ; #if NUMPY == 1 matrix = create_numpyarray(cx, m, n) ; #else matrix = create_listmatrix(cx, NULL, m, n) ; #endif } else { cx_img = (double*)malloc((m * n) * sizeof(double)); if (!cx_img) { free(cx) ; free(cxtmp) ; PyErr_SetString(PyExc_MemoryError, "out of memory") ; return NULL ; } sciErr = getComplexMatrixOfDouble(pvApiCtx, addr, &m, &n, &cxtmp, &cxtmp_img) ; if (sciErr.iErr) { free(cx) ; free(cx_img); PyErr_SetString(PyExc_TypeError, "Error in readmatrix") ; return 0; } memcpy(cx, cxtmp, sizeof(double) * n * m) ; memcpy(cx_img, cxtmp_img, sizeof(double) * n * m) ; #if NUMPY == 1 matrix = create_cnumpyarray(cx, cx_img, m, n) ; #else matrix = create_listmatrix(cx, cx_img, m, n) ; #endif free(cx_img); } return matrix ; } /** * Type 10 : Matrix of string. * @param name: the name of the scilab variable we want to read * @return: A list of string */ static PyObject * read_string(int *addr) { int m = 0, n = 0 ; int i = 0 ; int x = 0, y = 0 ; char ** variable_from_scilab = NULL ; SciErr sciErr; sciErr = getMatrixOfString(pvApiCtx, addr, &m, &n, NULL, NULL) ; if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return 0; } int *piLen = (int*)malloc(sizeof(int) * m * n); PyObject *new_list ; sciErr = getMatrixOfString(pvApiCtx, addr, &m, &n, piLen, NULL) ; if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return 0; } variable_from_scilab = (char **) malloc(sizeof(char*) * (m * n)) ; for (i = 0; i < m * n; i++) { variable_from_scilab[i] = (char*) malloc(sizeof(char) * (piLen[i])) ; } i = 0; new_list = PyList_New(m * n) ; sciErr = getMatrixOfString(pvApiCtx, addr, &m, &n, piLen, variable_from_scilab) ; if (sciErr.iErr) { PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return 0; } for (x = 0; x < m; x++) { for (y = 0; y < n; y++) { char *tmpStr = variable_from_scilab[x * m + y] ; PyList_SET_ITEM(new_list, i, Py_BuildValue("s", tmpStr)) ; free(tmpStr) ; i++; } } return new_list ; } /** * Type 16 : tlist (typed list). * * A tlist x = tlist(['test','a','b'],12,'item') * is transformed in python in * x = { "__tlist_name" : "test", * "a" : 12, * "b" : "item", * } * * @param tlist_address: the address of the scilab variable we want to read * @return: A dictionary */ static PyObject * read_tlist(int *tlist_address) { SciErr sciErr ; PyObject *new_dict = NULL ; PyObject *key_list = NULL ; int nb_item = 0, i; sciErr = getListItemNumber(pvApiCtx, tlist_address, &nb_item) ; if (sciErr.iErr) { goto handle_error ; } new_dict = PyDict_New() ; for (i = 1 ; i <= nb_item; ++i) { PyObject *py_item ; int *item_address = NULL ; int sci_type = 0 ; sciErr = getListItemAddress(pvApiCtx, tlist_address, i, &item_address) ; if (sciErr.iErr) { goto handle_error ; } sciErr = getVarType(pvApiCtx, item_address, &sci_type) ; if (sciErr.iErr) { goto handle_error ; } py_item = sciconv_read (item_address, sci_type) ; if (i == 1) { if (sci_type != 10) { PyErr_SetString(PyExc_TypeError, "First tlist item must be string") ; return 0 ; } key_list = py_item ; PyDict_SetItem(new_dict, Py_BuildValue("s", TLIST_NAME), \ PyList_GetItem(key_list, i - 1)) ; } else { PyObject *next_item = NULL ; next_item = PyList_GetItem(key_list, i - 1) ; if (next_item == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot read tlist (wrong number of key)") ; return 0 ; } PyDict_SetItem(new_dict, PyList_GetItem(key_list, i - 1), py_item) ; } } return new_dict; handle_error: PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; return 0; } /** * Add a new converter to the list * @param new_type: A scilab type number * @param func: The converter function */ static void sciconv_read_add(int new_type, PyObject * (*func)(char*)) { struct sciconv_read_struct *new_conv = \ (struct sciconv_read_struct*) malloc(sizeof(struct sciconv_read_struct)) ; new_conv->scitype = new_type ; new_conv->conv_func = func ; if (sciconv_read_list == NULL) { sciconv_read_list = new_conv ; new_conv->next = NULL ; return ; } new_conv->next = sciconv_read_list->next ; sciconv_read_list->next = new_conv ; } /** * Initialization * Add all the known converters to the list */ void sciconv_read_init(void) { // Most used should come last sciconv_read_add(16, read_tlist) ; sciconv_read_add(10, read_string) ; sciconv_read_add(1, read_matrix) ; } sciscipy-1.0.1/PKG-INFO0000664000175000017500000000040612075521046013544 0ustar vinszvinszMetadata-Version: 1.0 Name: sciscipy Version: 1.0.0 Summary: Scilab binding Home-page: http://forge.scilab.org/index.php/p/sciscipy/ Author: Sylvestre Ledru Author-email: sylvestre.ledru@scilab-enterprises.com License: GPL Description: UNKNOWN Platform: UNKNOWN sciscipy-1.0.1/tests/0000775000175000017500000000000012212711357013610 5ustar vinszvinszsciscipy-1.0.1/tests/test_call.py0000664000175000017500000000227111350772003016133 0ustar vinszvinszimport unittest from scilab import Scilab import sciscipy class test_call(unittest.TestCase): def setUp(self): self.sci = Scilab() def test_spec(self): """ [test_call] Testing spec """ spec1 = self.sci.spec([[1, 2],[3, 4]]) sciscipy.eval("spec1 = spec([1,2;3,4])") spec2 = sciscipy.read("spec1") for l1, l2 in zip(spec1, spec2): self.assertAlmostEqual(l1, l2) def test_mean(self): """ [test_call] Testing mean """ mean1 = self.sci.mean([[1, 2],[3, 4]]) sciscipy.eval("mean1 = mean([1,2;3,4])") mean2 = sciscipy.read("mean1") comp = mean1 == mean2 assert(comp) def test_strcat(self): """ [test_call] Testing strcat """ strcat1 = self.sci.strcat(["1", "4"], "x") sciscipy.eval("strcat1 = strcat(['1', '4'], 'x')") strcat2 = sciscipy.read("strcat1") comp = strcat1 == strcat2 assert(comp) def test_length(self): """ [test_call] Testing length """ strlength1 = self.sci.length(["3ch","5char","plenty of char"]) sciscipy.eval("strlength = length(['3ch','5char','plenty of char'])") strlength2 = sciscipy.read("strlength") for l1, l2 in zip(strlength1, strlength2): self.assertEquals(l1, l2) if __name__ == '__main__': unittest.main() sciscipy-1.0.1/tests/test_read.py0000664000175000017500000000117612212710371016134 0ustar vinszvinszimport unittest from sciscipy import read, eval import numpy try: import numpy numpy_is_avail = 1 except ImportError: numpy_is_avail = 0 class test_read(unittest.TestCase): def setUp(self): pass def test_read_tlist(self): eval("x=tlist(['test','a','b'],12,'item')") x=read('x') if numpy_is_avail: num = numpy.array(12) else: num = 12 py_x = {'__tlist_name': 'test', 'a': num, 'b': ['item']} assert x == py_x, str(py_x) + " != tlist(['test','a','b'],12,'item')" if __name__ == '__main__': unittest.main() sciscipy-1.0.1/tests/__init__.py0000664000175000017500000000000011333753662015717 0ustar vinszvinszsciscipy-1.0.1/tests/test_matrix.py0000664000175000017500000000322512075505172016532 0ustar vinszvinszimport unittest import sciscipy as sci try: import numpy numpy_is_avail = 1 except ImportError: numpy_is_avail = 0 class test_matrix(unittest.TestCase): def setUp(self): pass def test_readwrite1d(self): sci.eval("x=rand(1, 100)") sci.eval("my_sum=sum(x)") x = sci.read("x") my_sum = 0 for i in range(len(x)): my_sum += x[i] my_other_sum = sci.read("my_sum") assert(my_other_sum[0] == my_sum) def test_readwrite1dT(self): sci.eval("x=rand(100, 1)") sci.eval("my_sum=sum(x)") x = sci.read("x") my_sum = 0 for i in range(len(x)): my_sum += x[i] my_other_sum = sci.read("my_sum") assert(my_other_sum[0] == my_sum) def test_readwrite(self): sci.eval("x=[1,2,3 ; 4,5,6]") y = sci.read("x") sci.write("z", y) w = sci.read("z") if numpy_is_avail: assert(numpy.alltrue(numpy.equal(y, w))) else: assert(y == w) def test_bigmat(self): sci.eval("x=rand(1000,800)") y = sci.read("x") sci.write("xx", y) sci.eval("dist = sum((x - xx).^2)") dist = sci.read("dist") assert(dist[0] == 0) def test_complex(self): sci.eval("x=[1+11*%i, 2+222*%i, 3+333*%i ; 4+444*%i , 5+55*%i, 6+66*%i]") y = sci.read("x") sci.write("z", y) w = sci.read("z") if numpy_is_avail: assert(numpy.alltrue(numpy.equal(y, w))) else: assert(y == w) if __name__ == '__main__': unittest.main() sciscipy-1.0.1/sciconv_write.h0000775000175000017500000000257711405525204015510 0ustar vinszvinsz/* This file is part of Sciscipy. Sciscipy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Foobar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . Copyright (c) 2009, Vincent Guffens. */ #ifndef SCICONV_WRITE #define SCICONV_WRITE #include #if NUMPY == 1 #include "util.h" #include "numpy/arrayobject.h" #endif typedef enum { NUMPY_ARRAY, LISTOFLIST, LISTOFDOUBLE, LISTOFSTRING, TLIST } WRITETYPE_t ; struct sciconv_write_struct { int (*conv_func)(char*, PyObject*) ; // Create a new variable in scilab int (*test_func)(PyObject*) ; // Return one if this structure can handle the PyObject WRITETYPE_t write_type ; // Identifier for the type struct sciconv_write_struct *next ; } ; // List of converter functions extern struct sciconv_write_struct* sciconv_write_list ; void sciconv_write_init(void) ; #endif sciscipy-1.0.1/setup.py0000775000175000017500000001035412212710371014161 0ustar vinszvinsz#!/usr/bin/env python from distutils.core import setup, Extension, Command from unittest import TextTestRunner, TestLoader from glob import glob from os.path import splitext, basename, join as pjoin import os, sys # This should be customized for specific instals if os.name == 'nt': common_include_base = r"C:\Program Files (x86)\scilab-5.2.1\modules" sci_include = [ os.path.join(common_include_base, "core", "includes"), os.path.join(common_include_base, "call_scilab", "includes"), os.path.join(common_include_base, "api_scilab", "includes") ] sci_lib_dir = [r"C:\Program Files (x86)\scilab-5.2.1\bin"] sci_librairies = ['LibScilab', 'api_scilab'] elif os.name == 'posix': common_include_base = os.path.join("/","usr", "include", "scilab") sci_include = [ common_include_base, os.path.join(common_include_base, "core"), os.path.join(common_include_base, "call_scilab") ] sci_lib_dir = [os.path.join("/","usr", "lib", "scilab")] sci_librairies = [] sci_extra_link_args = ['-Wl,--no-as-needed', '-lscilab', '-lsciapi_scilab', '-lscicall_scilab', '-lscioutput_stream', '-lscicore', '-lscilinear_algebra', '-lsciconsole', '-lscilocalization', '-lscipolynomials', '-lsciio', '-lscielementary_functions', '-lscisparse', '-lscihistory_manager', '-lscihistory_browser', '-lscigraphics', '-lscicompletion', '-lscifunctions', '-lsciboolean', '-lsciwindows_tools', '-lscitime', '-lscifftw', '-lsciintersci', '-lscidouble', '-lscicommons'] else: raise NotImplementedError, "Only 'nt' and 'posix' are supported" sci_sources = ['sciscipy.c', 'sciconv_read.c', 'sciconv_write.c', 'util.c'] if os.environ.get('SCI'): common_include_base_call=os.path.join("/",os.environ.get('SCI'),"..","..","include","scilab") sci_include.append(os.path.join("/", common_include_base_call)) sci_include.append(os.path.join("/", common_include_base_call, "core")) sci_include.append(os.path.join("/",common_include_base_call, "call_scilab")) sci_lib_dir.append(os.path.join("/",os.environ.get('SCI'),"..","..","lib","scilab")) sci_install = os.path.join("/", "usr", "local", "share", "scilab") list_of_macros = [('SCI', '"' + sci_install + '"'), ('SCIDEBUG', 0)] # Test for python version if sys.version_info[0] >= 3: list_of_macros += [('PYTHON3', 1)] # Test for numpy try: import numpy import numpy.distutils.misc_util as misc sci_include += os.path.join(misc.get_numpy_include_dirs()) numpy_is_avail = 1 sci_sources += ['deallocator.c'] except ImportError: numpy_is_avail = 0 list_of_macros += [('NUMPY', numpy_is_avail)] class TestCommand(Command): user_options = [ ] def initialize_options(self): self._dir = os.getcwd() def finalize_options(self): pass def run(self): ''' Finds all the tests modules in test/, and runs them. ''' testfiles = [ ] for t in glob(pjoin(self._dir, 'tests', '*.py')): if not t.endswith('__init__.py'): testfiles.append('.'.join( ['tests', splitext(basename(t))[0]]) ) print(testfiles) tests = TestLoader().loadTestsFromNames(testfiles) t = TextTestRunner(verbosity = 2) t.run(tests) module1 = Extension('sciscipy', sources = sci_sources, include_dirs = sci_include, libraries = sci_librairies, library_dirs = sci_lib_dir, extra_link_args = sci_extra_link_args, define_macros = list_of_macros ) long_description = r""" The goal of sciscipy is to give an access to Scilab features inside python. from scilab import Scilab sci = Scilab() x = sci.rand(20, 20) y = x*x.transpose() y_inv = sci.inv(y) The function func in sci.func(x, y) can be a Scilab built-in or any user defined function so that Scilab libraries can be reused easily in python. """ setup ( name = 'sciscipy', version = '1.0.0', author = 'Vincent Guffens , Sylvestre Ledru ', url = "http://forge.scilab.org/index.php/p/sciscipy/", license = "GPL", description = 'Scilab binding', long_description = long_description, ext_modules = [module1], py_modules = ['scilab'], data_files = [('share/sciscipy', ['scilab.cfg'])], cmdclass = { 'test': TestCommand} )