diff --git a/Extras/ode/LICENSE-BSD.TXT b/Extras/ode/LICENSE-BSD.TXT deleted file mode 100644 index 485e1640e..000000000 --- a/Extras/ode/LICENSE-BSD.TXT +++ /dev/null @@ -1,34 +0,0 @@ - -This is the BSD-style license for the Open Dynamics Engine ----------------------------------------------------------- - -Open Dynamics Engine -Copyright (c) 2001-2004, Russell L. Smith. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -Neither the names of ODE's copyright owner nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Extras/ode/LICENSE.TXT b/Extras/ode/LICENSE.TXT deleted file mode 100644 index cfe59bcad..000000000 --- a/Extras/ode/LICENSE.TXT +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/Extras/ode/VC6/Samples/DrawStuff.dsp b/Extras/ode/VC6/Samples/DrawStuff.dsp deleted file mode 100644 index d1f83b069..000000000 --- a/Extras/ode/VC6/Samples/DrawStuff.dsp +++ /dev/null @@ -1,204 +0,0 @@ -# Microsoft Developer Studio Project File - Name="DrawStuff" - Package Owner=<4> - -# Microsoft Developer Studio Generated Build File, Format Version 6.00 - -# ** DO NOT EDIT ** - - - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - - - -CFG=DrawStuff - Win32 Debug - -!MESSAGE This is not a valid makefile. To build this project using NMAKE, - -!MESSAGE use the Export Makefile command and run - -!MESSAGE - -!MESSAGE NMAKE /f "DrawStuff.mak". - -!MESSAGE - -!MESSAGE You can specify a configuration when running NMAKE - -!MESSAGE by defining the macro CFG on the command line. For example: - -!MESSAGE - -!MESSAGE NMAKE /f "DrawStuff.mak" CFG="DrawStuff - Win32 Debug" - -!MESSAGE - -!MESSAGE Possible choices for configuration are: - -!MESSAGE - -!MESSAGE "DrawStuff - Win32 Release" (based on "Win32 (x86) Static Library") - -!MESSAGE "DrawStuff - Win32 Debug" (based on "Win32 (x86) Static Library") - -!MESSAGE - - - -# Begin Project - -# PROP AllowPerConfigDependencies 0 - -# PROP Scc_ProjName "" - -# PROP Scc_LocalPath "" - -CPP=cl.exe - -RSC=rc.exe - - - -!IF "$(CFG)" == "DrawStuff - Win32 Release" - - - -# PROP BASE Use_MFC 0 - -# PROP BASE Use_Debug_Libraries 0 - -# PROP Use_MFC 0 - -# PROP Use_Debug_Libraries 0 - -# PROP Output_Dir "DrawStuff_Release" - -# PROP Intermediate_Dir "DrawStuff_Release\Int" - -# PROP Target_Dir "" - -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c - -# ADD CPP /nologo /MD /W2 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c - -# ADD BASE RSC /l 0x409 /d "NDEBUG" - -# ADD RSC /l 0x409 /d "NDEBUG" - -BSC32=bscmake.exe - -# ADD BASE BSC32 /nologo - -# ADD BSC32 /nologo - -LIB32=link.exe -lib - -# ADD BASE LIB32 /nologo - -# ADD LIB32 /nologo /out:"..\..\..\..\lib\DrawStuff.lib" - - - -!ELSEIF "$(CFG)" == "DrawStuff - Win32 Debug" - - - -# PROP BASE Use_MFC 0 - -# PROP BASE Use_Debug_Libraries 1 - -# PROP Use_MFC 0 - -# PROP Use_Debug_Libraries 1 - -# PROP Output_Dir "DrawStuff_Debug" - -# PROP Intermediate_Dir "DrawStuff_Debug\Int" - -# PROP Target_Dir "" - -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c - -# ADD CPP /nologo /MDd /W2 /Gm /GX /ZI /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c - -# ADD BASE RSC /l 0x409 /d "_DEBUG" - -# ADD RSC /l 0x409 /d "_DEBUG" - -BSC32=bscmake.exe - -# ADD BASE BSC32 /nologo - -# ADD BSC32 /nologo - -LIB32=link.exe -lib - -# ADD BASE LIB32 /nologo - -# ADD LIB32 /nologo /out:"..\..\..\..\lib\DrawStuffd.lib" - - - -!ENDIF - - - -# Begin Target - - - -# Name "DrawStuff - Win32 Release" - -# Name "DrawStuff - Win32 Debug" - -# Begin Group "Source Files" - - - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" - -# Begin Source File - - - -SOURCE=..\..\drawstuff\src\drawstuff.cpp - -# End Source File - -# Begin Source File - - - -SOURCE=..\..\drawstuff\src\resources.rc - -# End Source File - -# Begin Source File - - - -SOURCE=..\..\drawstuff\src\windows.cpp - -# End Source File - -# End Group - -# Begin Group "Header Files" - - - -# PROP Default_Filter "h" - -# Begin Source File - - - -SOURCE=..\..\drawstuff\src\internal.h - -# End Source File - -# End Group - -# End Target - -# End Project - diff --git a/Extras/ode/VC6/Samples/DrawStuff.vcproj b/Extras/ode/VC6/Samples/DrawStuff.vcproj deleted file mode 100644 index 691040b2d..000000000 --- a/Extras/ode/VC6/Samples/DrawStuff.vcproj +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Extras/ode/VC6/Samples/MakeAllTests.sln b/Extras/ode/VC6/Samples/MakeAllTests.sln deleted file mode 100644 index 29556317a..000000000 --- a/Extras/ode/VC6/Samples/MakeAllTests.sln +++ /dev/null @@ -1,65 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DrawStuff", "DrawStuff.vcproj", "{72D5B37B-FB7B-48A0-B4CA-EC019DEF577B}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ode", "..\ode.vcproj", "{153C9883-E788-4FD5-A5B1-D09FEEAADFBF}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test_BulletBoxStack", "Test_BoxStack.vcproj", "{B1689C8C-9E82-48DE-B896-DE8DB08541B4}" - ProjectSection(ProjectDependencies) = postProject - {44672927-0084-4B70-8CDA-8697BF848C7F} = {44672927-0084-4B70-8CDA-8697BF848C7F} - {90F5975E-550B-EEC8-9A8A-B8581D3FCF97} = {90F5975E-550B-EEC8-9A8A-B8581D3FCF97} - {72D5B37B-FB7B-48A0-B4CA-EC019DEF577B} = {72D5B37B-FB7B-48A0-B4CA-EC019DEF577B} - {153C9883-E788-4FD5-A5B1-D09FEEAADFBF} = {153C9883-E788-4FD5-A5B1-D09FEEAADFBF} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BulletOdeCollide", "..\..\..\BulletOdeCollide\BulletOdeCollide_vc7.vcproj", "{44672927-0084-4B70-8CDA-8697BF848C7F}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbullet", "..\..\..\..\msvc\71\libbullet.vcproj", "{90F5975E-550B-EEC8-9A8A-B8581D3FCF97}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SourceCodeControl) = preSolution - SccNumberOfProjects = 1 - SccProjectUniqueName0 = ..\\ode.vcproj - SccProjectName0 = \u0022$/TR4/ODE\u0022,\u0020BHKAAAAA - SccLocalPath0 = ..\\.. - SccProvider0 = MSSCCI:ClearCase - SccProjectFilePathRelativizedFromConnection0 = VC6\\ - EndGlobalSection - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {72D5B37B-FB7B-48A0-B4CA-EC019DEF577B}.Debug.ActiveCfg = Debug|Win32 - {72D5B37B-FB7B-48A0-B4CA-EC019DEF577B}.Debug.Build.0 = Debug|Win32 - {72D5B37B-FB7B-48A0-B4CA-EC019DEF577B}.Release.ActiveCfg = Release|Win32 - {72D5B37B-FB7B-48A0-B4CA-EC019DEF577B}.Release.Build.0 = Release|Win32 - {153C9883-E788-4FD5-A5B1-D09FEEAADFBF}.Debug.ActiveCfg = Debug|Win32 - {153C9883-E788-4FD5-A5B1-D09FEEAADFBF}.Debug.Build.0 = Debug|Win32 - {153C9883-E788-4FD5-A5B1-D09FEEAADFBF}.Release.ActiveCfg = Release|Win32 - {153C9883-E788-4FD5-A5B1-D09FEEAADFBF}.Release.Build.0 = Release|Win32 - {B1689C8C-9E82-48DE-B896-DE8DB08541B4}.Debug.ActiveCfg = Debug|Win32 - {B1689C8C-9E82-48DE-B896-DE8DB08541B4}.Debug.Build.0 = Debug|Win32 - {B1689C8C-9E82-48DE-B896-DE8DB08541B4}.Release.ActiveCfg = Release|Win32 - {B1689C8C-9E82-48DE-B896-DE8DB08541B4}.Release.Build.0 = Release|Win32 - {44672927-0084-4B70-8CDA-8697BF848C7F}.Debug.ActiveCfg = Debug|Win32 - {44672927-0084-4B70-8CDA-8697BF848C7F}.Debug.Build.0 = Debug|Win32 - {44672927-0084-4B70-8CDA-8697BF848C7F}.Release.ActiveCfg = Release|Win32 - {44672927-0084-4B70-8CDA-8697BF848C7F}.Release.Build.0 = Release|Win32 - {90F5975E-550B-EEC8-9A8A-B8581D3FCF97}.Debug.ActiveCfg = Debug|Win32 - {90F5975E-550B-EEC8-9A8A-B8581D3FCF97}.Debug.Build.0 = Debug|Win32 - {90F5975E-550B-EEC8-9A8A-B8581D3FCF97}.Release.ActiveCfg = Release|Win32 - {90F5975E-550B-EEC8-9A8A-B8581D3FCF97}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/Extras/ode/VC6/Samples/Test_BoxStack.vcproj b/Extras/ode/VC6/Samples/Test_BoxStack.vcproj deleted file mode 100644 index 6274f8eca..000000000 --- a/Extras/ode/VC6/Samples/Test_BoxStack.vcproj +++ /dev/null @@ -1,197 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Extras/ode/VC6/Samples/Test_BulletGjk.dsp b/Extras/ode/VC6/Samples/Test_BulletGjk.dsp deleted file mode 100644 index 879fc3652..000000000 --- a/Extras/ode/VC6/Samples/Test_BulletGjk.dsp +++ /dev/null @@ -1,119 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Test_BulletGjk" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=Test_BulletGjk - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Test_BulletGjk.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Test_BulletGjk.mak" CFG="Test_BulletGjk - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Test_BulletGjk - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Test_BulletGjk - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Test_BulletGjk - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Test_BulletGjk_Release" -# PROP Intermediate_Dir "Test_BulletGjk_Release\Int" -# PROP Ignore_Export_Lib 0 -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /GX /O2 /I "..\..\include" /I "..\..\Include" /I "..\..\OPCODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /subsystem:windows /machine:I386 /libpath:"..\..\lib" -# Begin Special Build Tool -TargetPath=.\Test_BulletGjk_Release\Test_BulletGjk.exe -SOURCE="$(InputPath)" -PostBuild_Desc=- Copying .exe to test dir - -PostBuild_Cmds=copy $(TargetPath) ..\..\ode\test\ -# End Special Build Tool - -!ELSEIF "$(CFG)" == "Test_BulletGjk - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Test_BulletGjk_Debug" -# PROP Intermediate_Dir "Test_BulletGjk_Debug\Int" -# PROP Ignore_Export_Lib 0 -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\Include" /I "..\..\OPCODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 oded.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"..\..\lib" -# Begin Special Build Tool -TargetPath=.\Test_BulletGjk_Debug\Test_BulletGjk.exe -SOURCE="$(InputPath)" -PostBuild_Desc=- Copying .exe to test dir - -PostBuild_Cmds=copy $(TargetPath) ..\..\ode\test\ -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "Test_BulletGjk - Win32 Release" -# Name "Test_BulletGjk - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\ode\test\test_BulletGjk.cpp -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=..\..\drawstuff\src\resources.rc -# End Source File -# End Group -# Begin Group "DrawStuff headers" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\..\..\include\drawstuff\drawstuff.h -# End Source File -# End Group -# End Target -# End Project diff --git a/Extras/ode/VC6/Samples/Test_BulletGjk.vcproj b/Extras/ode/VC6/Samples/Test_BulletGjk.vcproj deleted file mode 100644 index 73956b560..000000000 --- a/Extras/ode/VC6/Samples/Test_BulletGjk.vcproj +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Extras/ode/VC6/Samples/Test_Trimesh.vcproj b/Extras/ode/VC6/Samples/Test_Trimesh.vcproj deleted file mode 100644 index 79c3723a5..000000000 --- a/Extras/ode/VC6/Samples/Test_Trimesh.vcproj +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Extras/ode/VC6/ode.dsp b/Extras/ode/VC6/ode.dsp deleted file mode 100644 index e2c6159d3..000000000 --- a/Extras/ode/VC6/ode.dsp +++ /dev/null @@ -1,304 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ode" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=ode - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ode.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ode.mak" CFG="ode - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ode - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "ode - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/TR4/ODE", BHKAAAAA" -# PROP Scc_LocalPath ".." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ode - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W2 /GX /O2 /I "..\Include" /I "..\OPCODE" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x809 /d "NDEBUG" -# ADD RSC /l 0x809 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\lib\ode.lib" - -!ELSEIF "$(CFG)" == "ode - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W2 /Gm /GX /ZI /Od /I "..\Include" /I "..\OPCODE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x809 /d "_DEBUG" -# ADD RSC /l 0x809 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"..\lib\oded.lib" - -!ENDIF - -# Begin Target - -# Name "ode - Win32 Release" -# Name "ode - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\ode\src\array.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_kernel.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_quadtreespace.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_space.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_std.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_transform.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_box.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_ccylinder.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_distance.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_ray.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_sphere.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_trimesh.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_util.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\error.cpp -# End Source File -# Begin Source File - -SOURCE="..\ode\src\export-dif.cpp" -# End Source File -# Begin Source File - -SOURCE=..\ode\src\fastdot.c -# End Source File -# Begin Source File - -SOURCE=..\ode\src\fastldlt.c -# End Source File -# Begin Source File - -SOURCE=..\ode\src\fastlsolve.c -# End Source File -# Begin Source File - -SOURCE=..\ode\src\fastltsolve.c -# End Source File -# Begin Source File - -SOURCE=..\ode\src\joint.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\lcp.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\mass.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\mat.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\matrix.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\memory.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\misc.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\obstack.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\ode.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\odemath.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\quickstep.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\rotation.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\step.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\stepfast.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\testing.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\timer.cpp -# End Source File -# Begin Source File - -SOURCE=..\ode\src\util.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\ode\src\array.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_kernel.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_space_internal.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_std.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_transform.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_trimesh_internal.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\collision_util.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\joint.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\lcp.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\mat.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\objects.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\obstack.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\quickstep.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\step.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\testing.h -# End Source File -# Begin Source File - -SOURCE=..\ode\src\util.h -# End Source File -# End Group -# End Target -# End Project diff --git a/Extras/ode/VC6/ode.dsw b/Extras/ode/VC6/ode.dsw deleted file mode 100644 index cef6e78f9..000000000 --- a/Extras/ode/VC6/ode.dsw +++ /dev/null @@ -1,53 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "OPCODE"=..\OPCODE\Opcode.dsp - Package Owner=<4> - -Package=<5> -{{{ - begin source code control - "$/TR4/ODE/VC6", WNKAAAAA - . - end source code control -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "ode"=.\ode.dsp - Package Owner=<4> - -Package=<5> -{{{ - begin source code control - "$/TR4/ODE/VC6", WNKAAAAA - . - end source code control -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name OPCODE - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - - diff --git a/Extras/ode/VC6/ode.vcproj b/Extras/ode/VC6/ode.vcproj deleted file mode 100644 index 0319711a6..000000000 --- a/Extras/ode/VC6/ode.vcproj +++ /dev/null @@ -1,813 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Extras/ode/config/README b/Extras/ode/config/README deleted file mode 100644 index 4aa5779fa..000000000 --- a/Extras/ode/config/README +++ /dev/null @@ -1,83 +0,0 @@ - - -variable names used in the per-platform makefile configuration files: - - - -platform stuff - --------------- - - - -WINDOWS set to 1 if this is a microsoft windows based platform - - - -filesystem stuff and commands - ------------------------------ - - - -THIS_DIR1 prefix to run a command from the current directory (from within make) -THIS_DIR2 prefix to run a command from the current directory (from command line) - -DEL_CMD the name of the delete command - - - -compiler stuff - --------------- - - - -CC the C/C++ compiler to use - -OBJ the object file extension - -C_FLAGS the standard set of compiler flags - -C_INC flag to add an include path - -C_OUT flag to specify the object file output - -C_EXEOUT flag to specify the executable file output - -C_DEF flag to add a define - -C_OPT flag to set the optimization level - -OPT the optimization level to use - - - -library archiver - ----------------- - - - -AR library archiver command - -RANLIB ranlib command, if necessary - -LIB_PREFIX library file prefix - -LIB_SUFFIX library file suffix - -LINK_OPENGL link flags to link in windowing stuff and opengl - -LINK_MATH link flags to link in the system math library - - - -windows specific stuff - ----------------------- - - - -RC_RULE makefile rule to use for the resource compiler - diff --git a/Extras/ode/config/makefile.cygwin b/Extras/ode/config/makefile.cygwin deleted file mode 100644 index f3c592441..000000000 --- a/Extras/ode/config/makefile.cygwin +++ /dev/null @@ -1,33 +0,0 @@ -WINDOWS=1 -THIS_DIR1=./ -THIS_DIR2=./ -DEL_CMD=rm -f -CC=gcc -OBJ=.o -C_FLAGS=-c -Wall -fno-exceptions -fno-rtti -DWIN32 -DCYGWIN -C_INC=-I -C_OUT=-o -C_EXEOUT=-o -C_DEF=-D -C_OPT=-O -AR=ar rc -RANLIB= -LIB_PREFIX=lib -LIB_SUFFIX=.a -LINK_OPENGL=-lstdc++ -lComctl32 -lkernel32 -luser32 -lgdi32 -lOpenGL32 -lGlu32 -LINK_MATH=-lm -RC_RULE=windres -I rc -O coff $< $@ - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=-fomit-frame-pointer -ffast-math -endif - -ifeq ($(BUILD),debug) -OPT=0 -C_FLAGS+=-g -endif - -I_AM_GCC=yes - - diff --git a/Extras/ode/config/makefile.mingw b/Extras/ode/config/makefile.mingw deleted file mode 100644 index 2bf3e8a5e..000000000 --- a/Extras/ode/config/makefile.mingw +++ /dev/null @@ -1,34 +0,0 @@ -WINDOWS=1 -THIS_DIR1= -THIS_DIR2= -DEL_CMD=tools/rm.exe -CC=gcc -OBJ=.o -C_FLAGS=-c -Wall -fno-exceptions -fno-rtti -DWIN32 -C_INC=-I -C_OUT=-o -C_EXEOUT=-o -C_DEF=-D -C_OPT=-O -AR=ar rc -RANLIB= -LIB_PREFIX=lib -LIB_SUFFIX=.a -LINK_OPENGL=-lstdc++ -lComctl32 -lkernel32 -luser32 -lgdi32 -lOpenGL32 -lGlu32 -LINK_MATH=-lm -RC_RULE=windres -I rc -O coff $< $@ - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=-fomit-frame-pointer -ffast-math -endif - -ifeq ($(BUILD),debug) -OPT=0 -C_FLAGS+=-g -endif - -I_AM_GCC=yes - - - diff --git a/Extras/ode/config/makefile.msvc b/Extras/ode/config/makefile.msvc deleted file mode 100644 index 4b93f76c1..000000000 --- a/Extras/ode/config/makefile.msvc +++ /dev/null @@ -1,28 +0,0 @@ -WINDOWS=1 -THIS_DIR1= -THIS_DIR2= -DEL_CMD=tools\\rm -CC=cl /nologo /DWIN32 -OBJ=.obj -C_FLAGS=/c /GR- /GX- /W3 /GF -C_INC=/I -C_OUT=/Fo -C_EXEOUT=/Fe -C_DEF=/D -C_OPT=/O -AR=lib /nologo /OUT: -RANLIB= -LIB_PREFIX= -LIB_SUFFIX=.lib -LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib -LINK_MATH= -RC_RULE=rc /r /fo$@ $< - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=/Oy -endif - -ifeq ($(BUILD),debug) -OPT=d -endif diff --git a/Extras/ode/config/makefile.msvc-cygwin b/Extras/ode/config/makefile.msvc-cygwin deleted file mode 100644 index ede5e84c9..000000000 --- a/Extras/ode/config/makefile.msvc-cygwin +++ /dev/null @@ -1,30 +0,0 @@ -# To build ODE using VC++ from the cygwin make environment - -WINDOWS=1 -THIS_DIR1=./ -THIS_DIR2= -DEL_CMD=rm -f -CC=cl /nologo /DWIN32 -OBJ=.obj -C_FLAGS=/c /GR- /GX- /W3 /GF -C_INC=/I -C_OUT=/Fo -C_EXEOUT=/Fe -C_DEF=/D -C_OPT=/O -AR=lib /nologo /OUT: -RANLIB= -LIB_PREFIX= -LIB_SUFFIX=.lib -LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib -LINK_MATH= -RC_RULE=rc /r /fo$@ $< - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=/Oy -endif - -ifeq ($(BUILD),debug) -OPT=d -endif diff --git a/Extras/ode/config/makefile.msvc-dll b/Extras/ode/config/makefile.msvc-dll deleted file mode 100644 index dea2f50a4..000000000 --- a/Extras/ode/config/makefile.msvc-dll +++ /dev/null @@ -1,36 +0,0 @@ -WINDOWS=1 -THIS_DIR1= -THIS_DIR2= -DEL_CMD=tools\rm -CC=cl /nologo /DWIN32 -OBJ=.obj -C_FLAGS=/c /GR- /GX- /W3 /GF -C_INC=/I -C_OUT=/Fo -C_EXEOUT=/Fe -C_DEF=/D -C_OPT=/O -AR=lib /nologo /OUT: -RANLIB= -LIB_PREFIX= -LIB_SUFFIX=.lib -LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib -LINK_MATH= -RC_RULE=rc /r /fo$@ $< - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=/Oy -endif - -ifeq ($(BUILD),debug) -OPT=d -endif - -ifdef OPCODE_DIRECTORY -DEFS_FILE=msvcdefs-trimesh.def -else -DEFS_FILE=msvcdefs.def -endif - -ODE_LIB_AR_RULE=link /dll /nologo /SUBSYSTEM:WINDOWS /LIBPATH:"C:\Programme\Micros~2\VC98\Lib" /def:config/$(DEFS_FILE) $(LINK_OPENGL) /OUT:$(patsubst %.lib,%.dll,$@) diff --git a/Extras/ode/config/makefile.msvc-dll-cygwin b/Extras/ode/config/makefile.msvc-dll-cygwin deleted file mode 100644 index 56bdb75b5..000000000 --- a/Extras/ode/config/makefile.msvc-dll-cygwin +++ /dev/null @@ -1,38 +0,0 @@ -# To build ODE.dll using VC++ from the cygwin make environment - -WINDOWS=1 -THIS_DIR1=./ -THIS_DIR2= -DEL_CMD=rm -f -CC=cl /nologo /DWIN32 -OBJ=.obj -C_FLAGS=/c /GR- /GX- /W3 /GF -C_INC=/I -C_OUT=/Fo -C_EXEOUT=/Fe -C_DEF=/D -C_OPT=/O -AR=lib /nologo /OUT: -RANLIB= -LIB_PREFIX= -LIB_SUFFIX=.lib -LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib -LINK_MATH= -RC_RULE=rc /r /fo$@ $< - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=/Oy -endif - -ifeq ($(BUILD),debug) -OPT=d -endif - -ifdef OPCODE_DIRECTORY -DEFS_FILE=msvcdefs-trimesh.def -else -DEFS_FILE=msvcdefs.def -endif - -ODE_LIB_AR_RULE=link /dll /nologo /SUBSYSTEM:WINDOWS /LIBPATH:"C:\Programme\Micros~2\VC98\Lib" /def:config/$(DEFS_FILE) $(LINK_OPENGL) /OUT:$(patsubst %.lib,%.dll,$@) diff --git a/Extras/ode/config/makefile.osx b/Extras/ode/config/makefile.osx deleted file mode 100644 index 45f8256f9..000000000 --- a/Extras/ode/config/makefile.osx +++ /dev/null @@ -1,31 +0,0 @@ -THIS_DIR1=./ -THIS_DIR2=./ -DEL_CMD=rm -f -CC=g++ -OBJ=.o -C_FLAGS=-c -Wall -fno-rtti -fno-exceptions -Wall -I/usr/X11R6/include -C_INC=-I -C_OUT=-o -C_EXEOUT=-o -C_DEF=-D -C_OPT=-O -AR=ar rc -RANLIB=ranlib -s -LIB_PREFIX=lib -LIB_SUFFIX=.a -LINK_OPENGL=-L/usr/X11R6/lib -lX11 -lGL -lGLU -LINK_MATH=-lm - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=-fomit-frame-pointer -ffast-math -endif - -ifeq ($(BUILD),debug) -OPT=0 -C_FLAGS+=-g -endif - -I_AM_GCC=yes - - diff --git a/Extras/ode/config/makefile.unix-gcc b/Extras/ode/config/makefile.unix-gcc deleted file mode 100644 index 59cdffc62..000000000 --- a/Extras/ode/config/makefile.unix-gcc +++ /dev/null @@ -1,33 +0,0 @@ -THIS_DIR1=./ -THIS_DIR2=./ -DEL_CMD=rm -f -CC=g++ -OBJ=.o -C_FLAGS=-c -Wall -fno-rtti -fno-exceptions -Wall -C_INC=-I -C_OUT=-o -C_EXEOUT=-o -C_DEF=-D -C_OPT=-O -AR=ar rc -RANLIB= -LIB_PREFIX=lib -LIB_SUFFIX=.a -LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU -LINK_MATH=-lm - -ifeq ($(BUILD),release) -OPT=2 -C_FLAGS+=-fomit-frame-pointer -ffast-math -endif - -ifeq ($(BUILD),debug) -OPT=0 -C_FLAGS+=-g -endif - -# some other possible flags: -# -malign-double -mpentiumpro -march=pentiumpro - -I_AM_GCC=yes - diff --git a/Extras/ode/config/makefile.unix-generic b/Extras/ode/config/makefile.unix-generic deleted file mode 100644 index da588587b..000000000 --- a/Extras/ode/config/makefile.unix-generic +++ /dev/null @@ -1,25 +0,0 @@ -THIS_DIR1=./ -THIS_DIR2=./ -DEL_CMD=rm -f -CC=CC -OBJ=.o -C_FLAGS=-c -C_INC=-I -C_OUT=-o -C_EXEOUT=-o -C_DEF=-D -C_OPT=-O -AR=ar rc -RANLIB= -LIB_PREFIX=lib -LIB_SUFFIX=.a -LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU -LINK_MATH=-lm - -ifeq ($(BUILD),release) -OPT=2 -endif - -ifeq ($(BUILD),debug) -OPT=0 -endif diff --git a/Extras/ode/config/msvcdefs-trimesh.def b/Extras/ode/config/msvcdefs-trimesh.def deleted file mode 100644 index a4a4180ff..000000000 --- a/Extras/ode/config/msvcdefs-trimesh.def +++ /dev/null @@ -1,660 +0,0 @@ -EXPORTS - -dAreConnected - -dAreConnectedExcluding - -dBodyAddForce - -dBodyAddForceAtPos - -dBodyAddForceAtRelPos - -dBodyAddRelForce - -dBodyAddRelForceAtPos - -dBodyAddRelForceAtRelPos - -dBodyAddRelTorque - -dBodyAddTorque - -dBodyCreate - -dBodyDestroy - -dBodyDisable - -dBodyEnable - -dBodyGetAngularVel - -dBodyGetAutoDisableAngularThreshold - -dBodyGetAutoDisableFlag - -dBodyGetAutoDisableLinearThreshold - -dBodyGetAutoDisableSteps - -dBodyGetAutoDisableTime - -dBodyGetData - -dBodyGetFiniteRotationAxis - -dBodyGetFiniteRotationMode - -dBodyGetForce - -dBodyGetGravityMode - -dBodyGetJoint - -dBodyGetLinearVel - -dBodyGetMass - -dBodyGetNumJoints - -dBodyGetPointVel - -dBodyGetPosition - -dBodyGetPosRelPoint - -dBodyGetQuaternion - -dBodyGetRelPointPos - -dBodyGetRelPointVel - -dBodyGetRotation - -dBodyGetTorque - -dBodyIsEnabled - -dBodySetAngularVel - -dBodySetAutoDisableAngularThreshold - -dBodySetAutoDisableDefaults - -dBodySetAutoDisableFlag - -dBodySetAutoDisableLinearThreshold - -dBodySetAutoDisableSteps - -dBodySetAutoDisableTime - -dBodySetData - -dBodySetFiniteRotationAxis - -dBodySetFiniteRotationMode - -dBodySetForce - -dBodySetGravityMode - -dBodySetLinearVel - -dBodySetMass - -dBodySetPosition - -dBodySetQuaternion - -dBodySetRotation - -dBodySetTorque - -dBodyVectorFromWorld - -dBodyVectorToWorld - -dBoxBox - -dBoxTouchesBox - -dClearUpperTriangle - -dCloseODE - -dClosestLineSegmentPoints - -dCollide - -dCreateBox - -dCreateCCylinder - -dCreateGeom - -dCreateGeomClass - -dCreateGeomTransform - -dCreatePlane - -dCreateRay - -dCreateSphere - -dCreateTriMesh - -dDebug - -dDQfromW - -dError - -dFactorCholesky - -dFactorLDLT - -dGeomBoxGetLengths - -dGeomBoxPointDepth - -dGeomBoxSetLengths - -dGeomCCylinderGetParams - -dGeomCCylinderPointDepth - -dGeomCCylinderSetParams - -dGeomDestroy - -dGeomDisable - -dGeomEnable - -dGeomGetAABB - -dGeomGetBody - -dGeomGetCategoryBits - -dGeomGetClass - -dGeomGetClassData - -dGeomGetCollideBits - -dGeomGetData - -dGeomGetPosition - -dGeomGetQuaternion - -dGeomGetRotation - -dGeomGetSpace - -dGeomIsEnabled - -dGeomIsSpace - -dGeomPlaneGetParams - -dGeomPlanePointDepth - -dGeomPlaneSetParams - -dGeomRayGet - -dGeomRayGetClosestHit - -dGeomRayGetLength - -dGeomRaySet - -dGeomRaySetClosestHit - -dGeomRaySetLength - -dGeomRaySetParams - -dGeomSetBody - -dGeomSetCategoryBits - -dGeomSetCollideBits - -dGeomSetData - -dGeomSetPosition - -dGeomSetQuaternion - -dGeomSetRotation - -dGeomSphereGetRadius - -dGeomSpherePointDepth - -dGeomSphereSetRadius - -dGeomTransformGetCleanup - -dGeomTransformGetGeom - -dGeomTransformGetInfo - -dGeomTransformSetCleanup - -dGeomTransformSetGeom - -dGeomTransformSetInfo - -dGeomTriMeshClearTCCache - -dGeomTriMeshDataBuildDouble - -dGeomTriMeshDataBuildSimple - -dGeomTriMeshDataBuildSingle - -dGeomTriMeshDataCreate - -dGeomTriMeshDataDestroy - -dGeomTriMeshEnableTC - -dGeomTriMeshGetArrayCallback - -dGeomTriMeshGetCallback - -dGeomTriMeshGetPoint - -dGeomTriMeshGetRayCallback - -dGeomTriMeshGetTriangle - -dGeomTriMeshGetTriangleCount - -dGeomTriMeshIsTCEnabled - -dGeomTriMeshSetArrayCallback - -dGeomTriMeshSetCallback - -dGeomTriMeshSetData - -dGeomTriMeshSetRayCallback - -dHashSpaceCreate - -dHashSpaceGetLevels - -dHashSpaceSetLevels - -dInfiniteAABB - -dInvertPDMatrix - -dIsPositiveDefinite - -dJointAddAMotorTorques - -dJointAddHinge2Torques - -dJointAddHingeTorque - -dJointAddSliderForce - -dJointAddUniversalTorques - -dJointAttach - -dJointCreateAMotor - -dJointCreateBall - -dJointCreateContact - -dJointCreateFixed - -dJointCreateHinge - -dJointCreateHinge2 - -dJointCreateSlider - -dJointCreateUniversal - -dJointDestroy - -dJointGetAMotorAngle - -dJointGetAMotorAngleRate - -dJointGetAMotorAxis - -dJointGetAMotorAxisRel - -dJointGetAMotorMode - -dJointGetAMotorNumAxes - -dJointGetAMotorParam - -dJointGetBallAnchor - -dJointGetBallAnchor2 - -dJointGetBody - -dJointGetData - -dJointGetFeedback - -dJointGetHinge2Anchor - -dJointGetHinge2Anchor2 - -dJointGetHinge2Angle1 - -dJointGetHinge2Angle1Rate - -dJointGetHinge2Angle2Rate - -dJointGetHinge2Axis1 - -dJointGetHinge2Axis2 - -dJointGetHinge2Param - -dJointGetHingeAnchor - -dJointGetHingeAnchor2 - -dJointGetHingeAngle - -dJointGetHingeAngleRate - -dJointGetHingeAxis - -dJointGetHingeParam - -dJointGetSliderAxis - -dJointGetSliderParam - -dJointGetSliderPosition - -dJointGetSliderPositionRate - -dJointGetType - -dJointGetUniversalAnchor - -dJointGetUniversalAnchor2 - -dJointGetUniversalAngle1 - -dJointGetUniversalAngle1Rate - -dJointGetUniversalAngle2 - -dJointGetUniversalAngle2Rate - -dJointGetUniversalAxis1 - -dJointGetUniversalAxis2 - -dJointGetUniversalParam - -dJointGroupCreate - -dJointGroupDestroy - -dJointGroupEmpty - -dJointSetAMotorAngle - -dJointSetAMotorAxis - -dJointSetAMotorMode - -dJointSetAMotorNumAxes - -dJointSetAMotorParam - -dJointSetBallAnchor - -dJointSetData - -dJointSetFeedback - -dJointSetFixed - -dJointSetHinge2Anchor - -dJointSetHinge2Axis1 - -dJointSetHinge2Axis2 - -dJointSetHinge2Param - -dJointSetHingeAnchor - -dJointSetHingeAxis - -dJointSetHingeParam - -dJointSetSliderAxis - -dJointSetSliderParam - -dJointSetUniversalAnchor - -dJointSetUniversalAxis1 - -dJointSetUniversalAxis2 - -dJointSetUniversalParam - -dLDLTAddTL - -dLDLTRemove - -dMakeRandomMatrix - -dMakeRandomVector - -dMassAdd - -dMassAdjust - -dMassRotate - -dMassSetBox - -dMassSetBoxTotal - -dMassSetCappedCylinder - -dMassSetCappedCylinderTotal - -dMassSetCylinder - -dMassSetCylinderTotal - -dMassSetParameters - -dMassSetSphere - -dMassSetSphereTotal - -dMassSetZero - -dMassTranslate - -dMaxDifference - -dMessage - -dMultiply0 - -dMultiply1 - -dMultiply2 - -dNormalize3 - -dNormalize4 - -dPlaneSpace - -dQFromAxisAndAngle - -dQfromR - -dQMultiply0 - -dQMultiply1 - -dQMultiply2 - -dQMultiply3 - -dQSetIdentity - -dQuadTreeSpaceCreate - -dRandGetSeed - -dRandInt - -dRandReal - -dRandSetSeed - -dRemoveRowCol - -dRFrom2Axes - -dRFromAxisAndAngle - -dRFromEulerAngles - -dRfromQ - -dRFromZAxis - -dRSetIdentity - -dSetDebugHandler - -dSetErrorHandler - -dSetMessageHandler - -dSetZero - -dSimpleSpaceCreate - -dSolveCholesky - -dSolveLDLT - -dSpaceAdd - -dSpaceClean - -dSpaceCollide - -dSpaceCollide2 - -dSpaceDestroy - -dSpaceGetCleanup - -dSpaceGetGeom - -dSpaceGetNumGeoms - -dSpaceQuery - -dSpaceRemove - -dSpaceSetCleanup - -dTestMatrixComparison - -dTestRand - -dTestSolveLCP - -dWorldCreate - -dWorldDestroy - -dWorldExportDIF - -dWorldGetAutoDisableAngularThreshold - -dWorldGetAutoDisableFlag - -dWorldGetAutoDisableLinearThreshold - -dWorldGetAutoDisableSteps - -dWorldGetAutoDisableTime - -dWorldGetAutoEnableDepthSF1 - -dWorldGetCFM - -dWorldGetERP - -dWorldGetGravity - -dWorldImpulseToForce - -dWorldSetAutoDisableAngularThreshold - -dWorldSetAutoDisableFlag - -dWorldSetAutoDisableLinearThreshold - -dWorldSetAutoDisableSteps - -dWorldSetAutoDisableTime - -dWorldSetAutoEnableDepthSF1 - -dWorldSetCFM - -dWorldSetERP - -dWorldSetGravity - -dWorldStep - -dWorldStepFast1 - -dWorldQuickStep - -dWorldSetQuickStepNumIterations - -dWorldGetQuickStepNumIterations - -dWorldSetQuickStepW - -dWorldGetQuickStepW - -dWorldSetContactMaxCorrectingVel - -dWorldGetContactMaxCorrectingVel - -dWorldSetContactSurfaceLayer - -dWorldGetContactSurfaceLayer - diff --git a/Extras/ode/config/msvcdefs.def b/Extras/ode/config/msvcdefs.def deleted file mode 100644 index 928244cc6..000000000 --- a/Extras/ode/config/msvcdefs.def +++ /dev/null @@ -1,622 +0,0 @@ -EXPORTS - -dAreConnected - -dAreConnectedExcluding - -dBodyAddForce - -dBodyAddForceAtPos - -dBodyAddForceAtRelPos - -dBodyAddRelForce - -dBodyAddRelForceAtPos - -dBodyAddRelForceAtRelPos - -dBodyAddRelTorque - -dBodyAddTorque - -dBodyCreate - -dBodyDestroy - -dBodyDisable - -dBodyEnable - -dBodyGetAngularVel - -dBodyGetAutoDisableAngularThreshold - -dBodyGetAutoDisableFlag - -dBodyGetAutoDisableLinearThreshold - -dBodyGetAutoDisableSteps - -dBodyGetAutoDisableTime - -dBodyGetData - -dBodyGetFiniteRotationAxis - -dBodyGetFiniteRotationMode - -dBodyGetForce - -dBodyGetGravityMode - -dBodyGetJoint - -dBodyGetLinearVel - -dBodyGetMass - -dBodyGetNumJoints - -dBodyGetPointVel - -dBodyGetPosition - -dBodyGetPosRelPoint - -dBodyGetQuaternion - -dBodyGetRelPointPos - -dBodyGetRelPointVel - -dBodyGetRotation - -dBodyGetTorque - -dBodyIsEnabled - -dBodySetAngularVel - -dBodySetAutoDisableAngularThreshold - -dBodySetAutoDisableDefaults - -dBodySetAutoDisableFlag - -dBodySetAutoDisableLinearThreshold - -dBodySetAutoDisableSteps - -dBodySetAutoDisableTime - -dBodySetData - -dBodySetFiniteRotationAxis - -dBodySetFiniteRotationMode - -dBodySetForce - -dBodySetGravityMode - -dBodySetLinearVel - -dBodySetMass - -dBodySetPosition - -dBodySetQuaternion - -dBodySetRotation - -dBodySetTorque - -dBodyVectorFromWorld - -dBodyVectorToWorld - -dBoxBox - -dBoxTouchesBox - -dClearUpperTriangle - -dCloseODE - -dClosestLineSegmentPoints - -dCollide - -dCreateBox - -dCreateCCylinder - -dCreateGeom - -dCreateGeomClass - -dCreateGeomTransform - -dCreatePlane - -dCreateRay - -dCreateSphere - -dDebug - -dDQfromW - -dError - -dFactorCholesky - -dFactorLDLT - -dGeomBoxGetLengths - -dGeomBoxPointDepth - -dGeomBoxSetLengths - -dGeomCCylinderGetParams - -dGeomCCylinderPointDepth - -dGeomCCylinderSetParams - -dGeomDestroy - -dGeomDisable - -dGeomEnable - -dGeomGetAABB - -dGeomGetBody - -dGeomGetCategoryBits - -dGeomGetClass - -dGeomGetClassData - -dGeomGetCollideBits - -dGeomGetData - -dGeomGetPosition - -dGeomGetQuaternion - -dGeomGetRotation - -dGeomGetSpace - -dGeomIsEnabled - -dGeomIsSpace - -dGeomPlaneGetParams - -dGeomPlanePointDepth - -dGeomPlaneSetParams - -dGeomRayGet - -dGeomRayGetClosestHit - -dGeomRayGetLength - -dGeomRaySet - -dGeomRaySetClosestHit - -dGeomRaySetLength - -dGeomRaySetParams - -dGeomSetBody - -dGeomSetCategoryBits - -dGeomSetCollideBits - -dGeomSetData - -dGeomSetPosition - -dGeomSetQuaternion - -dGeomSetRotation - -dGeomSphereGetRadius - -dGeomSpherePointDepth - -dGeomSphereSetRadius - -dGeomTransformGetCleanup - -dGeomTransformGetGeom - -dGeomTransformGetInfo - -dGeomTransformSetCleanup - -dGeomTransformSetGeom - -dGeomTransformSetInfo - -dHashSpaceCreate - -dHashSpaceGetLevels - -dHashSpaceSetLevels - -dInfiniteAABB - -dInvertPDMatrix - -dIsPositiveDefinite - -dJointAddAMotorTorques - -dJointAddHinge2Torques - -dJointAddHingeTorque - -dJointAddSliderForce - -dJointAddUniversalTorques - -dJointAttach - -dJointCreateAMotor - -dJointCreateBall - -dJointCreateContact - -dJointCreateFixed - -dJointCreateHinge - -dJointCreateHinge2 - -dJointCreateSlider - -dJointCreateUniversal - -dJointDestroy - -dJointGetAMotorAngle - -dJointGetAMotorAngleRate - -dJointGetAMotorAxis - -dJointGetAMotorAxisRel - -dJointGetAMotorMode - -dJointGetAMotorNumAxes - -dJointGetAMotorParam - -dJointGetBallAnchor - -dJointGetBallAnchor2 - -dJointGetBody - -dJointGetData - -dJointGetFeedback - -dJointGetHinge2Anchor - -dJointGetHinge2Anchor2 - -dJointGetHinge2Angle1 - -dJointGetHinge2Angle1Rate - -dJointGetHinge2Angle2Rate - -dJointGetHinge2Axis1 - -dJointGetHinge2Axis2 - -dJointGetHinge2Param - -dJointGetHingeAnchor - -dJointGetHingeAnchor2 - -dJointGetHingeAngle - -dJointGetHingeAngleRate - -dJointGetHingeAxis - -dJointGetHingeParam - -dJointGetSliderAxis - -dJointGetSliderParam - -dJointGetSliderPosition - -dJointGetSliderPositionRate - -dJointGetType - -dJointGetUniversalAnchor - -dJointGetUniversalAnchor2 - -dJointGetUniversalAngle1 - -dJointGetUniversalAngle1Rate - -dJointGetUniversalAngle2 - -dJointGetUniversalAngle2Rate - -dJointGetUniversalAxis1 - -dJointGetUniversalAxis2 - -dJointGetUniversalParam - -dJointGroupCreate - -dJointGroupDestroy - -dJointGroupEmpty - -dJointSetAMotorAngle - -dJointSetAMotorAxis - -dJointSetAMotorMode - -dJointSetAMotorNumAxes - -dJointSetAMotorParam - -dJointSetBallAnchor - -dJointSetData - -dJointSetFeedback - -dJointSetFixed - -dJointSetHinge2Anchor - -dJointSetHinge2Axis1 - -dJointSetHinge2Axis2 - -dJointSetHinge2Param - -dJointSetHingeAnchor - -dJointSetHingeAxis - -dJointSetHingeParam - -dJointSetSliderAxis - -dJointSetSliderParam - -dJointSetUniversalAnchor - -dJointSetUniversalAxis1 - -dJointSetUniversalAxis2 - -dJointSetUniversalParam - -dLDLTAddTL - -dLDLTRemove - -dMakeRandomMatrix - -dMakeRandomVector - -dMassAdd - -dMassAdjust - -dMassRotate - -dMassSetBox - -dMassSetBoxTotal - -dMassSetCappedCylinder - -dMassSetCappedCylinderTotal - -dMassSetCylinder - -dMassSetCylinderTotal - -dMassSetParameters - -dMassSetSphere - -dMassSetSphereTotal - -dMassSetZero - -dMassTranslate - -dMaxDifference - -dMessage - -dMultiply0 - -dMultiply1 - -dMultiply2 - -dNormalize3 - -dNormalize4 - -dPlaneSpace - -dQFromAxisAndAngle - -dQfromR - -dQMultiply0 - -dQMultiply1 - -dQMultiply2 - -dQMultiply3 - -dQSetIdentity - -dQuadTreeSpaceCreate - -dRandGetSeed - -dRandInt - -dRandReal - -dRandSetSeed - -dRemoveRowCol - -dRFrom2Axes - -dRFromAxisAndAngle - -dRFromEulerAngles - -dRfromQ - -dRFromZAxis - -dRSetIdentity - -dSetDebugHandler - -dSetErrorHandler - -dSetMessageHandler - -dSetZero - -dSimpleSpaceCreate - -dSolveCholesky - -dSolveLDLT - -dSpaceAdd - -dSpaceClean - -dSpaceCollide - -dSpaceCollide2 - -dSpaceDestroy - -dSpaceGetCleanup - -dSpaceGetGeom - -dSpaceGetNumGeoms - -dSpaceQuery - -dSpaceRemove - -dSpaceSetCleanup - -dTestMatrixComparison - -dTestRand - -dTestSolveLCP - -dWorldCreate - -dWorldDestroy - -dWorldExportDIF - -dWorldGetAutoDisableAngularThreshold - -dWorldGetAutoDisableFlag - -dWorldGetAutoDisableLinearThreshold - -dWorldGetAutoDisableSteps - -dWorldGetAutoDisableTime - -dWorldGetAutoEnableDepthSF1 - -dWorldGetCFM - -dWorldGetERP - -dWorldGetGravity - -dWorldImpulseToForce - -dWorldSetAutoDisableAngularThreshold - -dWorldSetAutoDisableFlag - -dWorldSetAutoDisableLinearThreshold - -dWorldSetAutoDisableSteps - -dWorldSetAutoDisableTime - -dWorldSetAutoEnableDepthSF1 - -dWorldSetCFM - -dWorldSetERP - -dWorldSetGravity - -dWorldStep - -dWorldStepFast1 - -dWorldQuickStep - -dWorldSetQuickStepNumIterations - -dWorldGetQuickStepNumIterations - -dWorldSetQuickStepW - -dWorldGetQuickStepW - -dWorldSetContactMaxCorrectingVel - -dWorldGetContactMaxCorrectingVel - -dWorldSetContactSurfaceLayer - -dWorldGetContactSurfaceLayer - diff --git a/Extras/ode/config/user-settings.example b/Extras/ode/config/user-settings.example deleted file mode 100644 index 2c3424622..000000000 --- a/Extras/ode/config/user-settings.example +++ /dev/null @@ -1,44 +0,0 @@ -# ODE user settings: the following variables must be set by the user - -# (1) the platform to use. this name should have a corresponding -# makefile.PLATFORM file. currently supported platforms are: -# msvc microsoft visual C/C++ -# msvc-dll microsoft visual C/C++, create a DLL -# mingw minimalist GNU for windows -# cygwin cygnus GNU for windows -# unix-gcc GNU gcc on unix -# unix-generic generic unix compiler. you may need to edit the CC -# variable in makefile.unix-generic -# osx Mac OS-X, with the gnu compiler. - -PLATFORM=unix-gcc - -# (2) the floating point precision to use (either "SINGLE" or "DOUBLE") - -#PRECISION=SINGLE -PRECISION=DOUBLE - -# (3) the library type to build (either "debug" if you are doing development, -# or "release" for the optimized library) - -#BUILD=debug -BUILD=release - -# (4) if you are using an old version of MS-Windows that has command line -# length limitations then you will need to set this to "1". otherwise, -# leave it at "0". - -WINDOWS16=0 - -# (5) If you want to use the TriList (triangle mesh) geometry class, you must -# have the OPCODE library installed somewhere. If this is the case then -# uncomment the following variable and set it to point to the directory -# where OPCODE is installed (note that you must have already compiled -# OPCODE, ODE's build system will not do that for you). -# See http://www.codercorner.com/Opcode.htm for more information about -# OPCODE. A recent version of OPCODE is provided in the ODE distribution -# in the OPCODE subdirectory. This code was originally written for and -# compiled on windows, but it has been ported so that it should compile -# under unix/gcc too. Your mileage may vary. - -#OPCODE_DIRECTORY=OPCODE diff --git a/Extras/ode/drawstuff/dstest/dstest.cpp b/Extras/ode/drawstuff/dstest/dstest.cpp deleted file mode 100644 index 27f042fc7..000000000 --- a/Extras/ode/drawstuff/dstest/dstest.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include - - -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - - -void start() -{ - // adjust the starting viewpoint a bit - float xyz[3],hpr[3]; - dsGetViewpoint (xyz,hpr); - hpr[0] += 7; - dsSetViewpoint (xyz,hpr); -} - - -void simLoop (int pause) -{ - float pos[3]; - float R[12]; - static float a = 0; - - if (!pause) a += 0.02f; - if (a > (2*M_PI)) a -= (float) (2*M_PI); - float ca = (float) cos(a); - float sa = (float) sin(a); - - dsSetTexture (DS_WOOD); - - float b = (a > M_PI) ? (2*(a-(float)M_PI)) : a*2; - pos[0] = -0.3f; - pos[1] = 0; - pos[2] = (float) (0.1f*(2*M_PI*b - b*b) + 0.65f); - R[0] = ca; R[1] = 0; R[2] = -sa; - R[4] = 0; R[5] = 1; R[6] = 0; - R[8] = sa; R[9] = 0; R[10] = ca; - dsSetColor (1,0.8f,0.6f); - dsDrawSphere (pos,R,0.3f); - - dsSetTexture (DS_NONE); - - pos[0] = -0.2f; - pos[1] = 0.8f; - pos[2] = 0.4f; - R[0] = ca; R[1] = -sa; R[2] = 0; - R[4] = sa; R[5] = ca; R[6] = 0; - R[8] = 0; R[9] = 0; R[10] = 1; - float sides[3] = {0.1f,0.4f,0.8f}; - dsSetColor (0.6f,0.6f,1); - dsDrawBox (pos,R,sides); - - dsSetTexture (DS_WOOD); - - float r = 0.3f; // cylinder radius - float d = (float)cos(a*2) * 0.4f; - float cd = (float)cos(-d/r); - float sd = (float)sin(-d/r); - pos[0] = -0.2f; - pos[1] = -1 + d; - pos[2] = 0.3f; - R[0] = 0; R[1] = 0; R[2] = -1; - R[4] = -sd; R[5] = cd; R[6] = 0; - R[8] = cd; R[9] = sd; R[10] = 0; - dsSetColor (0.4f,1,1); - dsDrawCylinder (pos,R,0.8f,r); - - pos[0] = 0; - pos[1] = 0; - pos[2] = 0.2f; - R[0] = 0; R[1] = sa; R[2] = -ca; - R[4] = 0; R[5] = ca; R[6] = sa; - R[8] = 1; R[9] = 0; R[10] = 0; - dsSetColor (1,0.9f,0.2f); - dsDrawCappedCylinder (pos,R,0.8f,0.2f); -} - - -void command (int cmd) -{ - dsPrint ("received command %d (`%c')\n",cmd,cmd); -} - - -int main (int argc, char **argv) -{ - // setup pointers to callback functions - dsFunctions fn; - fn.version = DS_VERSION; - fn.start = &start; - fn.step = &simLoop; - fn.command = command; - fn.stop = 0; - fn.path_to_textures = 0; // uses default - - // run simulation - dsSimulationLoop (argc,argv,400,400,&fn); - - return 0; -} diff --git a/Extras/ode/drawstuff/src/drawstuff.cpp b/Extras/ode/drawstuff/src/drawstuff.cpp deleted file mode 100644 index 585413582..000000000 --- a/Extras/ode/drawstuff/src/drawstuff.cpp +++ /dev/null @@ -1,1534 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -simple graphics. - -the following command line flags can be used (typically under unix) - -notex Do not use any textures - -noshadow[s] Do not draw any shadows - -pause Start the simulation paused - -TODO ----- - -manage openGL state changes better - -*/ - -#ifdef WIN32 -#include -#endif - -#include -#include -#include - -#include "drawstuff/drawstuff.h" -#include "internal.h" - -//*************************************************************************** -// misc - -#ifdef WIN32 -#define DEFAULT_PATH_TO_TEXTURES "..\\textures\\" -#else -#define DEFAULT_PATH_TO_TEXTURES "../textures/" -#endif - -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - -// constants to convert degrees to radians and the reverse -#define RAD_TO_DEG (180.0/M_PI) -#define DEG_TO_RAD (M_PI/180.0) - -// light vector. LIGHTZ is implicitly 1 -#define LIGHTX (1.0f) -#define LIGHTY (0.4f) - -// ground and sky -#define SHADOW_INTENSITY (0.65f) -#define GROUND_R (0.5f) // ground color for when there's no texture -#define GROUND_G (0.5f) -#define GROUND_B (0.3f) - -const float ground_scale = 1.0f/1.0f; // ground texture scale (1/size) -const float ground_ofsx = 0.5; // offset of ground texture -const float ground_ofsy = 0.5; -const float sky_scale = 1.0f/4.0f; // sky texture scale (1/size) -const float sky_height = 1.0f; // sky height above viewpoint - -//*************************************************************************** -// misc mathematics stuff - -#define dCROSS(a,op,b,c) \ - (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ - (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ - (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); - - -inline float dDOT (const float *a, const float *b) - { return ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]); } - - -static void normalizeVector3 (float v[3]) -{ - float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - if (len <= 0.0f) { - v[0] = 1; - v[1] = 0; - v[2] = 0; - } - else { - len = 1.0f / (float)sqrt(len); - v[0] *= len; - v[1] *= len; - v[2] *= len; - } -} - -//*************************************************************************** -// PPM image object - -typedef unsigned char byte; - -class Image { - int image_width,image_height; - byte *image_data; -public: - Image (char *filename); - // load from PPM file - ~Image(); - int width() { return image_width; } - int height() { return image_height; } - byte *data() { return image_data; } -}; - - -// skip over whitespace and comments in a stream. - -static void skipWhiteSpace (char *filename, FILE *f) -{ - int c,d; - for(;;) { - c = fgetc(f); - if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); - - // skip comments - if (c == '#') { - do { - d = fgetc(f); - if (d==EOF) dsError ("unexpected end of file in \"%s\"",filename); - } while (d != '\n'); - continue; - } - - if (c > ' ') { - ungetc (c,f); - return; - } - } -} - - -// read a number from a stream, this return 0 if there is none (that's okay -// because 0 is a bad value for all PPM numbers anyway). - -static int readNumber (char *filename, FILE *f) -{ - int c,n=0; - for(;;) { - c = fgetc(f); - if (c==EOF) dsError ("unexpected end of file in \"%s\"",filename); - if (c >= '0' && c <= '9') n = n*10 + (c - '0'); - else { - ungetc (c,f); - return n; - } - } -} - - -Image::Image (char *filename) -{ - FILE *f = fopen (filename,"rb"); - if (!f) dsError ("Can't open image file `%s'",filename); - - // read in header - if (fgetc(f) != 'P' || fgetc(f) != '6') - dsError ("image file \"%s\" is not a binary PPM (no P6 header)",filename); - skipWhiteSpace (filename,f); - - // read in image parameters - image_width = readNumber (filename,f); - skipWhiteSpace (filename,f); - image_height = readNumber (filename,f); - skipWhiteSpace (filename,f); - int max_value = readNumber (filename,f); - - // check values - if (image_width < 1 || image_height < 1) - dsError ("bad image file \"%s\"",filename); - if (max_value != 255) - dsError ("image file \"%s\" must have color range of 255",filename); - - // read either nothing, LF (10), or CR,LF (13,10) - int c = fgetc(f); - if (c == 10) { - // LF - } - else if (c == 13) { - // CR - c = fgetc(f); - if (c != 10) ungetc (c,f); - } - else ungetc (c,f); - - // read in rest of data - image_data = new byte [image_width*image_height*3]; - if (fread (image_data,image_width*image_height*3,1,f) != 1) - dsError ("Can not read data from image file `%s'",filename); - fclose (f); -} - - -Image::~Image() -{ - delete[] image_data; -} - -//*************************************************************************** -// Texture object. - -class Texture { - Image *image; - GLuint name; -public: - Texture (char *filename); - ~Texture(); - void bind (int modulate); -}; - - -Texture::Texture (char *filename) -{ - image = new Image (filename); - glGenTextures (1,&name); - glBindTexture (GL_TEXTURE_2D,name); - - // set pixel unpacking mode - glPixelStorei (GL_UNPACK_SWAP_BYTES, 0); - glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); - glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); - - // glTexImage2D (GL_TEXTURE_2D, 0, 3, image->width(), image->height(), 0, - // GL_RGB, GL_UNSIGNED_BYTE, image->data()); - gluBuild2DMipmaps (GL_TEXTURE_2D, 3, image->width(), image->height(), - GL_RGB, GL_UNSIGNED_BYTE, image->data()); - - // set texture parameters - will these also be bound to the texture??? - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - - glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); -} - - -Texture::~Texture() -{ - delete image; - glDeleteTextures (1,&name); -} - - -void Texture::bind (int modulate) -{ - glBindTexture (GL_TEXTURE_2D,name); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, - modulate ? GL_MODULATE : GL_DECAL); -} - -//*************************************************************************** -// the current drawing state (for when the user's step function is drawing) - -static float color[4] = {0,0,0,0}; // current r,g,b,alpha color -static int tnum = 0; // current texture number - -//*************************************************************************** -// OpenGL utility stuff - -static void setCamera (float x, float y, float z, float h, float p, float r) -{ - glMatrixMode (GL_MODELVIEW); - glLoadIdentity(); - glRotatef (90, 0,0,1); - glRotatef (90, 0,1,0); - glRotatef (r, 1,0,0); - glRotatef (p, 0,1,0); - glRotatef (-h, 0,0,1); - glTranslatef (-x,-y,-z); -} - - -// sets the material color, not the light color - -static void setColor (float r, float g, float b, float alpha) -{ - GLfloat light_ambient[4],light_diffuse[4],light_specular[4]; - light_ambient[0] = r*0.3f; - light_ambient[1] = g*0.3f; - light_ambient[2] = b*0.3f; - light_ambient[3] = alpha; - light_diffuse[0] = r*0.7f; - light_diffuse[1] = g*0.7f; - light_diffuse[2] = b*0.7f; - light_diffuse[3] = alpha; - light_specular[0] = r*0.2f; - light_specular[1] = g*0.2f; - light_specular[2] = b*0.2f; - light_specular[3] = alpha; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, light_ambient); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, light_diffuse); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, light_specular); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 5.0f); -} - - -static void setTransform (const float pos[3], const float R[12]) -{ - GLfloat matrix[16]; - matrix[0]=R[0]; - matrix[1]=R[4]; - matrix[2]=R[8]; - matrix[3]=0; - matrix[4]=R[1]; - matrix[5]=R[5]; - matrix[6]=R[9]; - matrix[7]=0; - matrix[8]=R[2]; - matrix[9]=R[6]; - matrix[10]=R[10]; - matrix[11]=0; - matrix[12]=pos[0]; - matrix[13]=pos[1]; - matrix[14]=pos[2]; - matrix[15]=1; - glPushMatrix(); - glMultMatrixf (matrix); -} - - -// set shadow projection transform - -static void setShadowTransform() -{ - GLfloat matrix[16]; - for (int i=0; i<16; i++) matrix[i] = 0; - matrix[0]=1; - matrix[5]=1; - matrix[8]=-LIGHTX; - matrix[9]=-LIGHTY; - matrix[15]=1; - glPushMatrix(); - glMultMatrixf (matrix); -} - - -static void drawBox (const float sides[3]) -{ - float lx = sides[0]*0.5f; - float ly = sides[1]*0.5f; - float lz = sides[2]*0.5f; - - // sides - glBegin (GL_TRIANGLE_STRIP); - glNormal3f (-1,0,0); - glVertex3f (-lx,-ly,-lz); - glVertex3f (-lx,-ly,lz); - glVertex3f (-lx,ly,-lz); - glVertex3f (-lx,ly,lz); - glNormal3f (0,1,0); - glVertex3f (lx,ly,-lz); - glVertex3f (lx,ly,lz); - glNormal3f (1,0,0); - glVertex3f (lx,-ly,-lz); - glVertex3f (lx,-ly,lz); - glNormal3f (0,-1,0); - glVertex3f (-lx,-ly,-lz); - glVertex3f (-lx,-ly,lz); - glEnd(); - - // top face - glBegin (GL_TRIANGLE_FAN); - glNormal3f (0,0,1); - glVertex3f (-lx,-ly,lz); - glVertex3f (lx,-ly,lz); - glVertex3f (lx,ly,lz); - glVertex3f (-lx,ly,lz); - glEnd(); - - // bottom face - glBegin (GL_TRIANGLE_FAN); - glNormal3f (0,0,-1); - glVertex3f (-lx,-ly,-lz); - glVertex3f (-lx,ly,-lz); - glVertex3f (lx,ly,-lz); - glVertex3f (lx,-ly,-lz); - glEnd(); -} - - -// This is recursively subdivides a triangular area (vertices p1,p2,p3) into -// smaller triangles, and then draws the triangles. All triangle vertices are -// normalized to a distance of 1.0 from the origin (p1,p2,p3 are assumed -// to be already normalized). Note this is not super-fast because it draws -// triangles rather than triangle strips. - -static void drawPatch (float p1[3], float p2[3], float p3[3], int level) -{ - int i; - if (level > 0) { - float q1[3],q2[3],q3[3]; // sub-vertices - for (i=0; i<3; i++) { - q1[i] = 0.5f*(p1[i]+p2[i]); - q2[i] = 0.5f*(p2[i]+p3[i]); - q3[i] = 0.5f*(p3[i]+p1[i]); - } - float length1 = (float)(1.0/sqrt(q1[0]*q1[0]+q1[1]*q1[1]+q1[2]*q1[2])); - float length2 = (float)(1.0/sqrt(q2[0]*q2[0]+q2[1]*q2[1]+q2[2]*q2[2])); - float length3 = (float)(1.0/sqrt(q3[0]*q3[0]+q3[1]*q3[1]+q3[2]*q3[2])); - for (i=0; i<3; i++) { - q1[i] *= length1; - q2[i] *= length2; - q3[i] *= length3; - } - drawPatch (p1,q1,q3,level-1); - drawPatch (q1,p2,q2,level-1); - drawPatch (q1,q2,q3,level-1); - drawPatch (q3,q2,p3,level-1); - } - else { - glNormal3f (p1[0],p1[1],p1[2]); - glVertex3f (p1[0],p1[1],p1[2]); - glNormal3f (p2[0],p2[1],p2[2]); - glVertex3f (p2[0],p2[1],p2[2]); - glNormal3f (p3[0],p3[1],p3[2]); - glVertex3f (p3[0],p3[1],p3[2]); - } -} - - -// draw a sphere of radius 1 - -static int sphere_quality = 1; - -static void drawSphere() -{ - // icosahedron data for an icosahedron of radius 1.0 -# define ICX 0.525731112119133606f -# define ICZ 0.850650808352039932f - static GLfloat idata[12][3] = { - {-ICX, 0, ICZ}, - {ICX, 0, ICZ}, - {-ICX, 0, -ICZ}, - {ICX, 0, -ICZ}, - {0, ICZ, ICX}, - {0, ICZ, -ICX}, - {0, -ICZ, ICX}, - {0, -ICZ, -ICX}, - {ICZ, ICX, 0}, - {-ICZ, ICX, 0}, - {ICZ, -ICX, 0}, - {-ICZ, -ICX, 0} - }; - - static int index[20][3] = { - {0, 4, 1}, {0, 9, 4}, - {9, 5, 4}, {4, 5, 8}, - {4, 8, 1}, {8, 10, 1}, - {8, 3, 10}, {5, 3, 8}, - {5, 2, 3}, {2, 7, 3}, - {7, 10, 3}, {7, 6, 10}, - {7, 11, 6}, {11, 0, 6}, - {0, 1, 6}, {6, 1, 10}, - {9, 0, 11}, {9, 11, 2}, - {9, 2, 5}, {7, 2, 11}, - }; - - static GLuint listnum = 0; - if (listnum==0) { - listnum = glGenLists (1); - glNewList (listnum,GL_COMPILE); - glBegin (GL_TRIANGLES); - for (int i=0; i<20; i++) { - drawPatch (&idata[index[i][2]][0], - &idata[index[i][1]][0], - &idata[index[i][0]][0], - sphere_quality); - } - glEnd(); - glEndList(); - } - glCallList (listnum); -} - - -static void drawSphereShadow (float px, float py, float pz, float radius) -{ - // calculate shadow constants based on light vector - static int init=0; - static float len2,len1,scale; - if (!init) { - len2 = LIGHTX*LIGHTX + LIGHTY*LIGHTY; - len1 = 1.0f/(float)sqrt(len2); - scale = (float) sqrt(len2 + 1); - init = 1; - } - - // map sphere center to ground plane based on light vector - px -= LIGHTX*pz; - py -= LIGHTY*pz; - - const float kx = 0.96592582628907f; - const float ky = 0.25881904510252f; - float x=radius, y=0; - - glBegin (GL_TRIANGLE_FAN); - for (int i=0; i<24; i++) { - // for all points on circle, scale to elongated rotated shadow and draw - float x2 = (LIGHTX*x*scale - LIGHTY*y)*len1 + px; - float y2 = (LIGHTY*x*scale + LIGHTX*y)*len1 + py; - glTexCoord2f (x2*ground_scale+ground_ofsx,y2*ground_scale+ground_ofsy); - glVertex3f (x2,y2,0); - - // rotate [x,y] vector - float xtmp = kx*x - ky*y; - y = ky*x + kx*y; - x = xtmp; - } - glEnd(); -} - - -static void drawTriangle (const float *v0, const float *v1, const float *v2, int solid) -{ - float u[3],v[3],normal[3]; - u[0] = v1[0] - v0[0]; - u[1] = v1[1] - v0[1]; - u[2] = v1[2] - v0[2]; - v[0] = v2[0] - v0[0]; - v[1] = v2[1] - v0[1]; - v[2] = v2[2] - v0[2]; - dCROSS (normal,=,u,v); - normalizeVector3 (normal); - - glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); - glNormal3fv (normal); - glVertex3fv (v0); - glVertex3fv (v1); - glVertex3fv (v2); - glEnd(); -} - -static void drawTriangleD (const double *v0, const double *v1, const double *v2, int solid) -{ - float u[3],v[3],normal[3]; - u[0] = float( v1[0] - v0[0] ); - u[1] = float( v1[1] - v0[1] ); - u[2] = float( v1[2] - v0[2] ); - v[0] = float( v2[0] - v0[0] ); - v[1] = float( v2[1] - v0[1] ); - v[2] = float( v2[2] - v0[2] ); - dCROSS (normal,=,u,v); - normalizeVector3 (normal); - - glBegin(solid ? GL_TRIANGLES : GL_LINE_STRIP); - glNormal3fv (normal); - glVertex3dv (v0); - glVertex3dv (v1); - glVertex3dv (v2); - glEnd(); -} - - -// draw a capped cylinder of length l and radius r, aligned along the x axis - -static int capped_cylinder_quality = 3; - -static void drawCappedCylinder (float l, float r) -{ - int i,j; - float tmp,nx,ny,nz,start_nx,start_ny,a,ca,sa; - // number of sides to the cylinder (divisible by 4): - const int n = capped_cylinder_quality*4; - - l *= 0.5; - a = float(M_PI*2.0)/float(n); - sa = (float) sin(a); - ca = (float) cos(a); - - // draw cylinder body - ny=1; nz=0; // normal vector = (0,ny,nz) - glBegin (GL_TRIANGLE_STRIP); - for (i=0; i<=n; i++) { - glNormal3d (ny,nz,0); - glVertex3d (ny*r,nz*r,l); - glNormal3d (ny,nz,0); - glVertex3d (ny*r,nz*r,-l); - // rotate ny,nz - tmp = ca*ny - sa*nz; - nz = sa*ny + ca*nz; - ny = tmp; - } - glEnd(); - - // draw first cylinder cap - start_nx = 0; - start_ny = 1; - for (j=0; j<(n/4); j++) { - // get start_n2 = rotated start_n - float start_nx2 = ca*start_nx + sa*start_ny; - float start_ny2 = -sa*start_nx + ca*start_ny; - // get n=start_n and n2=start_n2 - nx = start_nx; ny = start_ny; nz = 0; - float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; - glBegin (GL_TRIANGLE_STRIP); - for (i=0; i<=n; i++) { - glNormal3d (ny2,nz2,nx2); - glVertex3d (ny2*r,nz2*r,l+nx2*r); - glNormal3d (ny,nz,nx); - glVertex3d (ny*r,nz*r,l+nx*r); - // rotate n,n2 - tmp = ca*ny - sa*nz; - nz = sa*ny + ca*nz; - ny = tmp; - tmp = ca*ny2- sa*nz2; - nz2 = sa*ny2 + ca*nz2; - ny2 = tmp; - } - glEnd(); - start_nx = start_nx2; - start_ny = start_ny2; - } - - // draw second cylinder cap - start_nx = 0; - start_ny = 1; - for (j=0; j<(n/4); j++) { - // get start_n2 = rotated start_n - float start_nx2 = ca*start_nx - sa*start_ny; - float start_ny2 = sa*start_nx + ca*start_ny; - // get n=start_n and n2=start_n2 - nx = start_nx; ny = start_ny; nz = 0; - float nx2 = start_nx2, ny2 = start_ny2, nz2 = 0; - glBegin (GL_TRIANGLE_STRIP); - for (i=0; i<=n; i++) { - glNormal3d (ny,nz,nx); - glVertex3d (ny*r,nz*r,-l+nx*r); - glNormal3d (ny2,nz2,nx2); - glVertex3d (ny2*r,nz2*r,-l+nx2*r); - // rotate n,n2 - tmp = ca*ny - sa*nz; - nz = sa*ny + ca*nz; - ny = tmp; - tmp = ca*ny2- sa*nz2; - nz2 = sa*ny2 + ca*nz2; - ny2 = tmp; - } - glEnd(); - start_nx = start_nx2; - start_ny = start_ny2; - } - - glPopMatrix(); -} - -// draw a cylinder of length l and radius r, aligned along the z axis - -static void drawCylinder2 (float l, float radius1, float radius2,float zoffset) -{ - int i; - float tmp,ny,nz,a,ca,sa; - const int n = 24; // number of sides to the cylinder (divisible by 4) - - l *= 0.5; - a = float(M_PI*2.0)/float(n); - sa = (float) sin(a); - ca = (float) cos(a); - - // draw cylinder body - ny=1; nz=0; // normal vector = (0,ny,nz) - glBegin (GL_TRIANGLE_STRIP); - for (i=0; i<=n; i++) { - glNormal3d (ny,nz,0); - glVertex3d (ny*radius1,nz*radius1,l+zoffset); - glNormal3d (ny,nz,0); - glVertex3d (ny*radius2,nz*radius2,-l+zoffset); - // rotate ny,nz - tmp = ca*ny - sa*nz; - nz = sa*ny + ca*nz; - ny = tmp; - } - glEnd(); - - // draw top cap - glShadeModel (GL_FLAT); - ny=1; nz=0; // normal vector = (0,ny,nz) - glBegin (GL_TRIANGLE_FAN); - glNormal3d (0,0,1); - glVertex3d (0,0,l+zoffset); - for (i=0; i<=n; i++) { - if (i==1 || i==n/2+1) - setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); - glNormal3d (0,0,1); - glVertex3d (ny*radius1,nz*radius1,l+zoffset); - if (i==1 || i==n/2+1) - setColor (color[0],color[1],color[2],color[3]); - - // rotate ny,nz - tmp = ca*ny - sa*nz; - nz = sa*ny + ca*nz; - ny = tmp; - } - glEnd(); - - // draw bottom cap - ny=1; nz=0; // normal vector = (0,ny,nz) - glBegin (GL_TRIANGLE_FAN); - glNormal3d (0,0,-1); - glVertex3d (0,0,-l+zoffset); - for (i=0; i<=n; i++) { - if (i==1 || i==n/2+1) - setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); - glNormal3d (0,0,-1); - glVertex3d (ny*radius2,nz*radius2,-l+zoffset); - if (i==1 || i==n/2+1) - setColor (color[0],color[1],color[2],color[3]); - - // rotate ny,nz - tmp = ca*ny + sa*nz; - nz = -sa*ny + ca*nz; - ny = tmp; - } - glEnd(); -} - -static void drawCone(float l, float r, float zoffset) -{ - drawCylinder2(l,0,r,zoffset); -} - - - -// draw a cylinder of length l and radius r, aligned along the z axis - -static void drawCylinder (float l, float r, float zoffset) -{ - drawCylinder2(l,r,r,zoffset); - -} - -//*************************************************************************** -// motion model - -// current camera position and orientation -static float view_xyz[3]; // position x,y,z -static float view_hpr[3]; // heading, pitch, roll (degrees) - - -// initialize the above variables - -static void initMotionModel() -{ - view_xyz[0] = 2; - view_xyz[1] = 0; - view_xyz[2] = 1; - view_hpr[0] = 180; - view_hpr[1] = 0; - view_hpr[2] = 0; -} - - -static void wrapCameraAngles() -{ - for (int i=0; i<3; i++) { - while (view_hpr[i] > 180) view_hpr[i] -= 360; - while (view_hpr[i] < -180) view_hpr[i] += 360; - } -} - - -// call this to update the current camera position. the bits in `mode' say -// if the left (1), middle (2) or right (4) mouse button is pressed, and -// (deltax,deltay) is the amount by which the mouse pointer has moved. - -void dsMotion (int mode, int deltax, int deltay) -{ - float side = 0.01f * float(deltax); - float fwd = (mode==4) ? (0.01f * float(deltay)) : 0.0f; - float s = (float) sin (view_hpr[0]*DEG_TO_RAD); - float c = (float) cos (view_hpr[0]*DEG_TO_RAD); - - if (mode==1) { - view_hpr[0] += float (deltax) * 0.5f; - view_hpr[1] += float (deltay) * 0.5f; - } - else { - view_xyz[0] += -s*side + c*fwd; - view_xyz[1] += c*side + s*fwd; - if (mode==2 || mode==5) view_xyz[2] += 0.01f * float(deltay); - } - wrapCameraAngles(); -} - -//*************************************************************************** -// drawing loop stuff - -// the current state: -// 0 = uninitialized -// 1 = dsSimulationLoop() called -// 2 = dsDrawFrame() called -static int current_state = 0; - -// textures and shadows -static int use_textures=1; // 1 if textures to be drawn -static int use_shadows=1; // 1 if shadows to be drawn -static Texture *sky_texture = 0; -static Texture *ground_texture = 0; -static Texture *wood_texture = 0; - - -#ifndef macintosh - -void dsStartGraphics (int width, int height, dsFunctions *fn) -{ - char *prefix = DEFAULT_PATH_TO_TEXTURES; - if (fn->version >= 2 && fn->path_to_textures) prefix = fn->path_to_textures; - char *s = (char*) alloca (strlen(prefix) + 20); - - strcpy (s,prefix); - strcat (s,"/sky.ppm"); - sky_texture = new Texture (s); - - strcpy (s,prefix); - strcat (s,"/ground.ppm"); - ground_texture = new Texture (s); - - strcpy (s,prefix); - strcat (s,"/wood.ppm"); - wood_texture = new Texture (s); -} - -#else // macintosh - -void dsStartGraphics (int width, int height, dsFunctions *fn) -{ - // All examples build into the same dir - char *prefix = "::::drawstuff:textures"; - char *s = (char*) alloca (strlen(prefix) + 20); - - strcpy (s,prefix); - strcat (s,":sky.ppm"); - sky_texture = new Texture (s); - - strcpy (s,prefix); - strcat (s,":ground.ppm"); - ground_texture = new Texture (s); - - strcpy (s,prefix); - strcat (s,":wood.ppm"); - wood_texture = new Texture (s); -} - -#endif - - -void dsStopGraphics() -{ - delete sky_texture; - delete ground_texture; - delete wood_texture; - sky_texture = 0; - ground_texture = 0; - wood_texture = 0; -} - - -static void drawSky (float view_xyz[3]) -{ - glDisable (GL_LIGHTING); - if (use_textures) { - glEnable (GL_TEXTURE_2D); - sky_texture->bind (0); - } - else { - glDisable (GL_TEXTURE_2D); - glColor3f (0,0.5,1.0); - } - - // make sure sky depth is as far back as possible - glShadeModel (GL_FLAT); - glEnable (GL_DEPTH_TEST); - glDepthFunc (GL_LEQUAL); - glDepthRange (1,1); - - const float ssize = 1000.0f; - static float offset = 0.0f; - - float x = ssize*sky_scale; - float z = view_xyz[2] + sky_height; - - glBegin (GL_QUADS); - glNormal3f (0,0,-1); - glTexCoord2f (-x+offset,-x+offset); - glVertex3f (-ssize+view_xyz[0],-ssize+view_xyz[1],z); - glTexCoord2f (-x+offset,x+offset); - glVertex3f (-ssize+view_xyz[0],ssize+view_xyz[1],z); - glTexCoord2f (x+offset,x+offset); - glVertex3f (ssize+view_xyz[0],ssize+view_xyz[1],z); - glTexCoord2f (x+offset,-x+offset); - glVertex3f (ssize+view_xyz[0],-ssize+view_xyz[1],z); - glEnd(); - - offset = offset + 0.002f; - if (offset > 1) offset -= 1; - - glDepthFunc (GL_LESS); - glDepthRange (0,1); -} - - -static void drawGround() -{ - glDisable (GL_LIGHTING); - glShadeModel (GL_FLAT); - glEnable (GL_DEPTH_TEST); - glDepthFunc (GL_LESS); - // glDepthRange (1,1); - - if (use_textures) { - glEnable (GL_TEXTURE_2D); - ground_texture->bind (0); - } - else { - glDisable (GL_TEXTURE_2D); - glColor3f (GROUND_R,GROUND_G,GROUND_B); - } - - // ground fog seems to cause problems with TNT2 under windows - /* - GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1}; - glEnable (GL_FOG); - glFogi (GL_FOG_MODE, GL_EXP2); - glFogfv (GL_FOG_COLOR, fogColor); - glFogf (GL_FOG_DENSITY, 0.05f); - glHint (GL_FOG_HINT, GL_NICEST); // GL_DONT_CARE); - glFogf (GL_FOG_START, 1.0); - glFogf (GL_FOG_END, 5.0); - */ - - const float gsize = 100.0f; - const float offset = 0; // -0.001f; ... polygon offsetting doesn't work well - - glBegin (GL_QUADS); - glNormal3f (0,0,1); - glTexCoord2f (-gsize*ground_scale + ground_ofsx, - -gsize*ground_scale + ground_ofsy); - glVertex3f (-gsize,-gsize,offset); - glTexCoord2f (gsize*ground_scale + ground_ofsx, - -gsize*ground_scale + ground_ofsy); - glVertex3f (gsize,-gsize,offset); - glTexCoord2f (gsize*ground_scale + ground_ofsx, - gsize*ground_scale + ground_ofsy); - glVertex3f (gsize,gsize,offset); - glTexCoord2f (-gsize*ground_scale + ground_ofsx, - gsize*ground_scale + ground_ofsy); - glVertex3f (-gsize,gsize,offset); - glEnd(); - - glDisable (GL_FOG); -} - - -static void drawPyramidGrid() -{ - // setup stuff - glEnable (GL_LIGHTING); - glDisable (GL_TEXTURE_2D); - glShadeModel (GL_FLAT); - glEnable (GL_DEPTH_TEST); - glDepthFunc (GL_LESS); - - // draw the pyramid grid - for (int i=-1; i<=1; i++) { - for (int j=-1; j<=1; j++) { - glPushMatrix(); - glTranslatef ((float)i,(float)j,(float)0); - if (i==1 && j==0) setColor (1,0,0,1); - else if (i==0 && j==1) setColor (0,0,1,1); - else setColor (1,1,0,1); - const float k = 0.03f; - glBegin (GL_TRIANGLE_FAN); - glNormal3f (0,-1,1); - glVertex3f (0,0,k); - glVertex3f (-k,-k,0); - glVertex3f ( k,-k,0); - glNormal3f (1,0,1); - glVertex3f ( k, k,0); - glNormal3f (0,1,1); - glVertex3f (-k, k,0); - glNormal3f (-1,0,1); - glVertex3f (-k,-k,0); - glEnd(); - glPopMatrix(); - } - } -} - - -void dsDrawFrame (int width, int height, dsFunctions *fn, int pause) -{ - if (current_state < 1) dsDebug ("internal error"); - current_state = 2; - - // setup stuff - glEnable (GL_LIGHTING); - glEnable (GL_LIGHT0); - glDisable (GL_TEXTURE_2D); - glDisable (GL_TEXTURE_GEN_S); - glDisable (GL_TEXTURE_GEN_T); - glShadeModel (GL_FLAT); - glEnable (GL_DEPTH_TEST); - glDepthFunc (GL_LESS); - glEnable (GL_CULL_FACE); - glCullFace (GL_BACK); - glFrontFace (GL_CCW); - - // setup viewport - glViewport (0,0,width,height); - glMatrixMode (GL_PROJECTION); - glLoadIdentity(); - const float vnear = 0.1f; - const float vfar = 100.0f; - const float k = 0.8f; // view scale, 1 = +/- 45 degrees - if (width >= height) { - float k2 = float(height)/float(width); - glFrustum (-vnear*k,vnear*k,-vnear*k*k2,vnear*k*k2,vnear,vfar); - } - else { - float k2 = float(width)/float(height); - glFrustum (-vnear*k*k2,vnear*k*k2,-vnear*k,vnear*k,vnear,vfar); - } - - // setup lights. it makes a difference whether this is done in the - // GL_PROJECTION matrix mode (lights are scene relative) or the - // GL_MODELVIEW matrix mode (lights are camera relative, bad!). - static GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; - static GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; - static GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; - glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); - glColor3f (1.0, 1.0, 1.0); - - // clear the window - glClearColor (0.5,0.5,0.5,0); - glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // snapshot camera position (in MS Windows it is changed by the GUI thread) - float view2_xyz[3]; - float view2_hpr[3]; - memcpy (view2_xyz,view_xyz,sizeof(float)*3); - memcpy (view2_hpr,view_hpr,sizeof(float)*3); - - // go to GL_MODELVIEW matrix mode and set the camera - glMatrixMode (GL_MODELVIEW); - glLoadIdentity(); - setCamera (view2_xyz[0],view2_xyz[1],view2_xyz[2], - view2_hpr[0],view2_hpr[1],view2_hpr[2]); - - // set the light position (for some reason we have to do this in model view. - static GLfloat light_position[] = { LIGHTX, LIGHTY, 1.0, 0.0 }; - glLightfv (GL_LIGHT0, GL_POSITION, light_position); - - // draw the background (ground, sky etc) - drawSky (view2_xyz); - drawGround(); - - // draw the little markers on the ground - drawPyramidGrid(); - - // leave openGL in a known state - flat shaded white, no textures - glEnable (GL_LIGHTING); - glDisable (GL_TEXTURE_2D); - glShadeModel (GL_FLAT); - glEnable (GL_DEPTH_TEST); - glDepthFunc (GL_LESS); - glColor3f (1,1,1); - setColor (1,1,1,1); - - // draw the rest of the objects. set drawing state first. - color[0] = 1; - color[1] = 1; - color[2] = 1; - color[3] = 1; - tnum = 0; - if (fn->step) fn->step (pause); -} - - -int dsGetShadows() -{ - return use_shadows; -} - - -void dsSetShadows (int a) -{ - use_shadows = (a != 0); -} - - -int dsGetTextures() -{ - return use_textures; -} - - -void dsSetTextures (int a) -{ - use_textures = (a != 0); -} - -//*************************************************************************** -// C interface - -// sets lighting and texture modes, sets current color -static void setupDrawingMode() -{ - glEnable (GL_LIGHTING); - if (tnum) { - if (use_textures) { - glEnable (GL_TEXTURE_2D); - wood_texture->bind (1); - glEnable (GL_TEXTURE_GEN_S); - glEnable (GL_TEXTURE_GEN_T); - glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); - glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); - static GLfloat s_params[4] = {1.0f,1.0f,0.0f,1}; - static GLfloat t_params[4] = {0.817f,-0.817f,0.817f,1}; - glTexGenfv (GL_S,GL_OBJECT_PLANE,s_params); - glTexGenfv (GL_T,GL_OBJECT_PLANE,t_params); - } - else { - glDisable (GL_TEXTURE_2D); - } - } - else { - glDisable (GL_TEXTURE_2D); - } - setColor (color[0],color[1],color[2],color[3]); - - if (color[3] < 1) { - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - } - else { - glDisable (GL_BLEND); - } -} - - -static void setShadowDrawingMode() -{ - glDisable (GL_LIGHTING); - if (use_textures) { - glEnable (GL_TEXTURE_2D); - ground_texture->bind (1); - glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); - glEnable (GL_TEXTURE_2D); - glEnable (GL_TEXTURE_GEN_S); - glEnable (GL_TEXTURE_GEN_T); - glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); - glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); - static GLfloat s_params[4] = {ground_scale,0,0,ground_ofsx}; - static GLfloat t_params[4] = {0,ground_scale,0,ground_ofsy}; - glTexGenfv (GL_S,GL_EYE_PLANE,s_params); - glTexGenfv (GL_T,GL_EYE_PLANE,t_params); - } - else { - glDisable (GL_TEXTURE_2D); - glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, - GROUND_B*SHADOW_INTENSITY); - } - glDepthRange (0,0.9999); -} - - -extern "C" void dsSimulationLoop (int argc, char **argv, - int window_width, int window_height, - dsFunctions *fn) -{ - if (current_state != 0) dsError ("dsSimulationLoop() called more than once"); - current_state = 1; - - // look for flags that apply to us - int initial_pause = 0; - for (int i=1; iversion > DS_VERSION) - dsDebug ("bad version number in dsFunctions structure"); - - initMotionModel(); - dsPlatformSimLoop (window_width,window_height,fn,initial_pause); - - current_state = 0; -} - - -extern "C" void dsSetViewpoint (float xyz[3], float hpr[3]) -{ - if (current_state < 1) dsError ("dsSetViewpoint() called before simulation started"); - if (xyz) { - view_xyz[0] = xyz[0]; - view_xyz[1] = xyz[1]; - view_xyz[2] = xyz[2]; - } - if (hpr) { - view_hpr[0] = hpr[0]; - view_hpr[1] = hpr[1]; - view_hpr[2] = hpr[2]; - wrapCameraAngles(); - } -} - - -extern "C" void dsGetViewpoint (float xyz[3], float hpr[3]) -{ - if (current_state < 1) dsError ("dsGetViewpoint() called before simulation started"); - if (xyz) { - xyz[0] = view_xyz[0]; - xyz[1] = view_xyz[1]; - xyz[2] = view_xyz[2]; - } - if (hpr) { - hpr[0] = view_hpr[0]; - hpr[1] = view_hpr[1]; - hpr[2] = view_hpr[2]; - } -} - - -extern "C" void dsSetTexture (int texture_number) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - tnum = texture_number; -} - - -extern "C" void dsSetColor (float red, float green, float blue) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - color[0] = red; - color[1] = green; - color[2] = blue; - color[3] = 1; -} - - -extern "C" void dsSetColorAlpha (float red, float green, float blue, - float alpha) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - color[0] = red; - color[1] = green; - color[2] = blue; - color[3] = alpha; -} - - -extern "C" void dsDrawBox (const float pos[3], const float R[12], - const float sides[3]) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glShadeModel (GL_FLAT); - setTransform (pos,R); - drawBox (sides); - glPopMatrix(); - - if (use_shadows) { - setShadowDrawingMode(); - setShadowTransform(); - setTransform (pos,R); - drawBox (sides); - glPopMatrix(); - glPopMatrix(); - glDepthRange (0,1); - } -} - - -extern "C" void dsDrawSphere (const float pos[3], const float R[12], - float radius) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glEnable (GL_NORMALIZE); - glShadeModel (GL_SMOOTH); - setTransform (pos,R); - glScaled (radius,radius,radius); - drawSphere(); - glPopMatrix(); - glDisable (GL_NORMALIZE); - - // draw shadows - if (use_shadows) { - glDisable (GL_LIGHTING); - if (use_textures) { - ground_texture->bind (1); - glEnable (GL_TEXTURE_2D); - glDisable (GL_TEXTURE_GEN_S); - glDisable (GL_TEXTURE_GEN_T); - glColor3f (SHADOW_INTENSITY,SHADOW_INTENSITY,SHADOW_INTENSITY); - } - else { - glDisable (GL_TEXTURE_2D); - glColor3f (GROUND_R*SHADOW_INTENSITY,GROUND_G*SHADOW_INTENSITY, - GROUND_B*SHADOW_INTENSITY); - } - glShadeModel (GL_FLAT); - glDepthRange (0,0.9999); - drawSphereShadow (pos[0],pos[1],pos[2],radius); - glDepthRange (0,1); - } -} - - -extern "C" void dsDrawTriangle (const float pos[3], const float R[12], - const float *v0, const float *v1, - const float *v2, int solid) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glShadeModel (GL_FLAT); - setTransform (pos,R); - drawTriangle (v0, v1, v2, solid); - glPopMatrix(); -} - -void dsDrawCone(const float pos[3], const float R[12], - float length, float radius) -{ - - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glShadeModel (GL_SMOOTH); - setTransform (pos,R); - drawCone(length,radius,0); - glPopMatrix(); - - if (use_shadows) { - setShadowDrawingMode(); - setShadowTransform(); - setTransform (pos,R); - drawCone (length,radius,0); - glPopMatrix(); - glPopMatrix(); - glDepthRange (0,1); - } -} -void dsDrawCylinder2 (const float pos[3], const float R[12], - float length, float radius1,float radius2) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glShadeModel (GL_SMOOTH); - setTransform (pos,R); - drawCylinder2 (length,radius1,radius2,0); - glPopMatrix(); - - if (use_shadows) { - setShadowDrawingMode(); - setShadowTransform(); - setTransform (pos,R); - drawCylinder2 (length,radius1,radius2,0); - glPopMatrix(); - glPopMatrix(); - glDepthRange (0,1); - } -} - - -extern "C" void dsDrawCylinder (const float pos[3], const float R[12], - float length, float radius) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glShadeModel (GL_SMOOTH); - setTransform (pos,R); - drawCylinder (length,radius,0); - glPopMatrix(); - - if (use_shadows) { - setShadowDrawingMode(); - setShadowTransform(); - setTransform (pos,R); - drawCylinder (length,radius,0); - glPopMatrix(); - glPopMatrix(); - glDepthRange (0,1); - } -} - - -extern "C" void dsDrawCappedCylinder (const float pos[3], const float R[12], - float length, float radius) -{ - if (current_state != 2) dsError ("drawing function called outside simulation loop"); - setupDrawingMode(); - glShadeModel (GL_SMOOTH); - setTransform (pos,R); - drawCappedCylinder (length,radius); - glPopMatrix(); - - if (use_shadows) { - setShadowDrawingMode(); - setShadowTransform(); - setTransform (pos,R); - drawCappedCylinder (length,radius); - glPopMatrix(); - glPopMatrix(); - glDepthRange (0,1); - } -} - - -void dsDrawLine (const float pos1[3], const float pos2[3]) -{ - setupDrawingMode(); - glColor3f (color[0],color[1],color[2]); - glDisable (GL_LIGHTING); - glLineWidth (2); - glShadeModel (GL_FLAT); - glBegin (GL_LINES); - glVertex3f (pos1[0],pos1[1],pos1[2]); - glVertex3f (pos2[0],pos2[1],pos2[2]); - glEnd(); -} - - -void dsDrawBoxD (const double pos[3], const double R[12], - const double sides[3]) -{ - int i; - float pos2[3],R2[12],fsides[3]; - for (i=0; i<3; i++) pos2[i]=(float)pos[i]; - for (i=0; i<12; i++) R2[i]=(float)R[i]; - for (i=0; i<3; i++) fsides[i]=(float)sides[i]; - dsDrawBox (pos2,R2,fsides); -} - - -void dsDrawSphereD (const double pos[3], const double R[12], float radius) -{ - int i; - float pos2[3],R2[12]; - for (i=0; i<3; i++) pos2[i]=(float)pos[i]; - for (i=0; i<12; i++) R2[i]=(float)R[i]; - dsDrawSphere (pos2,R2,radius); -} - - -void dsDrawTriangleD (const double pos[3], const double R[12], - const double *v0, const double *v1, - const double *v2, int solid) -{ - int i; - float pos2[3],R2[12]; - for (i=0; i<3; i++) pos2[i]=(float)pos[i]; - for (i=0; i<12; i++) R2[i]=(float)R[i]; - - setupDrawingMode(); - glShadeModel (GL_FLAT); - setTransform (pos2,R2); - drawTriangleD (v0, v1, v2, solid); - glPopMatrix(); -} - - -void dsDrawCylinderD (const double pos[3], const double R[12], - float length, float radius) -{ - int i; - float pos2[3],R2[12]; - for (i=0; i<3; i++) pos2[i]=(float)pos[i]; - for (i=0; i<12; i++) R2[i]=(float)R[i]; - dsDrawCylinder (pos2,R2,length,radius); -} - - -void dsDrawCappedCylinderD (const double pos[3], const double R[12], - float length, float radius) -{ - int i; - float pos2[3],R2[12]; - for (i=0; i<3; i++) pos2[i]=(float)pos[i]; - for (i=0; i<12; i++) R2[i]=(float)R[i]; - dsDrawCappedCylinder (pos2,R2,length,radius); -} - - -void dsDrawLineD (const double _pos1[3], const double _pos2[3]) -{ - int i; - float pos1[3],pos2[3]; - for (i=0; i<3; i++) pos1[i]=(float)_pos1[i]; - for (i=0; i<3; i++) pos2[i]=(float)_pos2[i]; - dsDrawLine (pos1,pos2); -} - - -void dsSetSphereQuality (int n) -{ - sphere_quality = n; -} - - -void dsSetCappedCylinderQuality (int n) -{ - capped_cylinder_quality = n; -} diff --git a/Extras/ode/drawstuff/src/internal.h b/Extras/ode/drawstuff/src/internal.h deleted file mode 100644 index de1aa1162..000000000 --- a/Extras/ode/drawstuff/src/internal.h +++ /dev/null @@ -1,50 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* functions supplied and used by the platform specific code */ - -#ifndef __DS_INTERNAL_H -#define __DS_INTERNAL_H - -#include "drawstuff/drawstuff.h" - - -// supplied by platform specific code - -void dsPlatformSimLoop (int window_width, int window_height, - dsFunctions *fn, int initial_pause); - - -// used by platform specific code - -void dsStartGraphics (int width, int height, dsFunctions *fn); -void dsDrawFrame (int width, int height, dsFunctions *fn, int pause); -void dsStopGraphics(); -void dsMotion (int mode, int deltax, int deltay); - -int dsGetShadows(); -void dsSetShadows (int a); - -int dsGetTextures(); -void dsSetTextures (int a); - -#endif diff --git a/Extras/ode/drawstuff/src/resource.h b/Extras/ode/drawstuff/src/resource.h deleted file mode 100644 index 15802b604..000000000 --- a/Extras/ode/drawstuff/src/resource.h +++ /dev/null @@ -1,28 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by resources.rc -// -#define IDD_MSGDLG 101 -#define IDR_MENU1 102 -#define IDD_ABOUT 103 -#define IDR_ACCELERATOR1 104 -#define IDC_LIST1 1000 -#define IDM_EXIT 40001 -#define IDM_ABOUT 40002 -#define IDM_PAUSE 40003 -#define IDM_PERF_MONITOR 40004 -#define IDM_SHADOWS 40005 -#define IDM_TEXTURES 40006 -#define IDM_SAVE_SETTINGS 40007 -#define IDM_SINGLE_STEP 40008 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 108 -#define _APS_NEXT_COMMAND_VALUE 40009 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/Extras/ode/drawstuff/src/resources.rc b/Extras/ode/drawstuff/src/resources.rc deleted file mode 100644 index 1340e0221..000000000 --- a/Extras/ode/drawstuff/src/resources.rc +++ /dev/null @@ -1,153 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -//#include "afxres.h" - -// added by RLS to make this work with windres -#include "winresrc.h" -#define IDC_STATIC (-1) - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUT DIALOG DISCARDABLE 0, 0, 257, 105 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "About" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,200,84,50,14 - LTEXT "Simulation test environment",IDC_STATIC,7,7,243,8 - LTEXT "Change the camera position by clicking + dragging in the main window.", - IDC_STATIC,7,24,243,8 - LTEXT "Left button - pan and tilt.",IDC_STATIC,25,37,225,8 - LTEXT "Right button - forward and sideways.",IDC_STATIC,25,48, - 225,8 - LTEXT "Left + Right button (or middle button) - sideways and up.", - IDC_STATIC,25,59,225,8 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - //"#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU1 MENU DISCARDABLE -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Exit\tCtrl+X", IDM_EXIT - END - POPUP "&Simulation" - BEGIN - MENUITEM "&Pause\tCtrl+P", IDM_PAUSE - MENUITEM "Single Step\tCtrl+O", IDM_SINGLE_STEP - MENUITEM "Performance &Monitor", IDM_PERF_MONITOR - MENUITEM SEPARATOR - MENUITEM "&Shadows\tCtrl+S", IDM_SHADOWS, CHECKED - MENUITEM "&Textures\tCtrl+T", IDM_TEXTURES, CHECKED - MENUITEM SEPARATOR - MENUITEM "S&ave Settings", IDM_SAVE_SETTINGS - END - POPUP "&Help" - BEGIN - MENUITEM "&About", IDM_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_ABOUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 250 - VERTGUIDE, 25 - TOPMARGIN, 7 - BOTTOMMARGIN, 98 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE -BEGIN - "O", IDM_SINGLE_STEP, VIRTKEY, CONTROL, NOINVERT - "P", IDM_PAUSE, VIRTKEY, CONTROL, NOINVERT - "S", IDM_SHADOWS, VIRTKEY, CONTROL, NOINVERT - "T", IDM_TEXTURES, VIRTKEY, CONTROL, NOINVERT - "X", IDM_EXIT, VIRTKEY, CONTROL, NOINVERT -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Extras/ode/drawstuff/src/windows.cpp b/Extras/ode/drawstuff/src/windows.cpp deleted file mode 100644 index 239a0b06d..000000000 --- a/Extras/ode/drawstuff/src/windows.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifdef WIN32 // this prevents warnings when dependencies built -#include -#endif -#include -#include - -#include "resource.h" -#include "internal.h" - -//*************************************************************************** -// application globals - -static HINSTANCE ghInstance = 0; -static int gnCmdShow = 0; -static HACCEL accelerators = 0; -static HWND main_window = 0; - -//*************************************************************************** -// error and message handling - -static void errorBox (char *title, char *msg, va_list ap) -{ - char s[1000]; - vsprintf (s,msg,ap); - MessageBox (0,s,title,MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION); -} - - -static void dsWarning (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - errorBox ("Warning",msg,ap); -} - - -extern "C" void dsError (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - errorBox ("Error",msg,ap); - exit (1); -} - - -extern "C" void dsDebug (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - errorBox ("INTERNAL ERROR",msg,ap); - // *((char *)0) = 0; ... commit SEGVicide ? - abort(); - exit (1); // should never get here, but just in case... -} - - -extern "C" void dsPrint (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - vprintf (msg,ap); -} - -//*************************************************************************** -// rendering thread - -// globals used to communicate with rendering thread - -static volatile int renderer_run = 1; -static volatile int renderer_pause = 0; // 0=run, 1=pause -static volatile int renderer_ss = 0; // single step command -static volatile int renderer_width = 1; -static volatile int renderer_height = 1; -static dsFunctions *renderer_fn = 0; -static volatile HDC renderer_dc = 0; -static volatile int keybuffer[16]; // fifo ring buffer for keypresses -static volatile int keybuffer_head = 0; // index of next key to put in (modified by GUI) -static volatile int keybuffer_tail = 0; // index of next key to take out (modified by renderer) - - -static void setupRendererGlobals() -{ - renderer_run = 1; - renderer_pause = 0; - renderer_ss = 0; - renderer_width = 1; - renderer_height = 1; - renderer_fn = 0; - renderer_dc = 0; - keybuffer[16]; - keybuffer_head = 0; - keybuffer_tail = 0; -} - - -static DWORD WINAPI renderingThread (LPVOID lpParam) -{ - // create openGL context and make it current - HGLRC glc = wglCreateContext (renderer_dc); - if (glc==NULL) dsError ("could not create OpenGL context"); - if (wglMakeCurrent (renderer_dc,glc) != TRUE) - dsError ("could not make OpenGL context current"); - - // test openGL capabilities - int maxtsize=0; - glGetIntegerv (GL_MAX_TEXTURE_SIZE,&maxtsize); - if (maxtsize < 128) dsWarning ("max texture size too small (%dx%d)", - maxtsize,maxtsize); - - dsStartGraphics (renderer_width,renderer_height,renderer_fn); - if (renderer_fn->start) renderer_fn->start(); - - while (renderer_run) { - // need to make local copy of renderer_ss to help prevent races - int ss = renderer_ss; - dsDrawFrame (renderer_width,renderer_height,renderer_fn, - renderer_pause && !ss); - if (ss) renderer_ss = 0; - - // read keys out of ring buffer and feed them to the command function - while (keybuffer_head != keybuffer_tail) { - if (renderer_fn->command) renderer_fn->command (keybuffer[keybuffer_tail]); - keybuffer_tail = (keybuffer_tail+1) & 15; - } - - // swap buffers - SwapBuffers (renderer_dc); - } - - if (renderer_fn->stop) renderer_fn->stop(); - dsStopGraphics(); - - // delete openGL context - wglMakeCurrent (NULL,NULL); - wglDeleteContext (glc); - - return 123; // magic value used to test for thread termination -} - -//*************************************************************************** -// window handling - -// callback function for "about" dialog box - -static LRESULT CALLBACK AboutDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, - LPARAM lParam) -{ - switch (uMsg) { - case WM_INITDIALOG: - return TRUE; - case WM_COMMAND: - switch (wParam) { - case IDOK: - EndDialog (hDlg, TRUE); - return TRUE; - } - break; - } - return FALSE; -} - - -// callback function for the main window - -static LRESULT CALLBACK mainWndProc (HWND hWnd, UINT msg, WPARAM wParam, - LPARAM lParam) -{ - static int button=0,lastx=0,lasty=0; - int ctrl = wParam & MK_CONTROL; - - switch (msg) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - if (msg==WM_LBUTTONDOWN) button |= 1; - else if (msg==WM_MBUTTONDOWN) button |= 2; - else button |= 4; - lastx = SHORT(LOWORD(lParam)); - lasty = SHORT(HIWORD(lParam)); - SetCapture (hWnd); - break; - - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - if (msg==WM_LBUTTONUP) button &= ~1; - else if (msg==WM_MBUTTONUP) button &= ~2; - else button &= ~4; - if (button==0) ReleaseCapture(); - break; - - case WM_MOUSEMOVE: { - int x = SHORT(LOWORD(lParam)); - int y = SHORT(HIWORD(lParam)); - if (button) dsMotion (button,x-lastx,y-lasty); - lastx = x; - lasty = y; - break; - } - - case WM_CHAR: { - if (wParam >= ' ' && wParam <= 126) { - int nexth = (keybuffer_head+1) & 15; - if (nexth != keybuffer_tail) { - keybuffer[keybuffer_head] = wParam; - keybuffer_head = nexth; - } - } - break; - } - - case WM_SIZE: - // lParam will contain the size of the *client* area! - renderer_width = LOWORD(lParam); - renderer_height = HIWORD(lParam); - break; - - case WM_COMMAND: - switch (wParam & 0xffff) { - case IDM_ABOUT: - DialogBox (ghInstance,MAKEINTRESOURCE(IDD_ABOUT),hWnd, - (DLGPROC) AboutDlgProc); - break; - case IDM_PAUSE: { - renderer_pause ^= 1; - CheckMenuItem (GetMenu(hWnd),IDM_PAUSE, - renderer_pause ? MF_CHECKED : MF_UNCHECKED); - if (renderer_pause) renderer_ss = 0; - break; - } - case IDM_SINGLE_STEP: { - renderer_ss = 1; - break; - } - case IDM_PERF_MONITOR: { - dsWarning ("Performance monitor not yet implemented."); - break; - } - case IDM_TEXTURES: { - static int tex = 1; - tex ^= 1; - CheckMenuItem (GetMenu(hWnd),IDM_TEXTURES, - tex ? MF_CHECKED : MF_UNCHECKED); - dsSetTextures (tex); - break; - } - case IDM_SHADOWS: { - static int shadows = 1; - shadows ^= 1; - CheckMenuItem (GetMenu(hWnd),IDM_SHADOWS, - shadows ? MF_CHECKED : MF_UNCHECKED); - dsSetShadows (shadows); - break; - } - case IDM_SAVE_SETTINGS: { - dsWarning ("\"Save Settings\" not yet implemented."); - break; - } - case IDM_EXIT: - PostQuitMessage (0); - break; - } - break; - - case WM_CLOSE: - PostQuitMessage (0); - break; - - default: - return (DefWindowProc (hWnd, msg, wParam, lParam)); - } - - return 0; -} - - -// this comes from an MSDN example. believe it or not, this is the recommended -// way to get the console window handle. - -static HWND GetConsoleHwnd() -{ - // the console window title to a "unique" value, then find the window - // that has this title. - char title[1024]; - wsprintf (title,"DrawStuff:%d/%d",GetTickCount(),GetCurrentProcessId()); - SetConsoleTitle (title); - Sleep(40); // ensure window title has been updated - return FindWindow (NULL,title); -} - - -static void drawStuffStartup() -{ - static int startup_called = 0; - if (startup_called) return; - startup_called = 1; - ghInstance = GetModuleHandleA (NULL); - gnCmdShow = SW_SHOWNORMAL; // @@@ fix this later - - // redirect standard I/O to a new console (except on cygwin) -#ifndef CYGWIN - FreeConsole(); - if (AllocConsole()==0) dsError ("AllocConsole() failed"); - if (freopen ("CONIN$","rt",stdin)==0) dsError ("could not open stdin"); - if (freopen ("CONOUT$","wt",stdout)==0) dsError ("could not open stdout"); - if (freopen ("CONOUT$","wt",stderr)==0) dsError ("could not open stderr"); - BringWindowToTop (GetConsoleHwnd()); - SetConsoleTitle ("DrawStuff Messages"); -#endif - - // register the window class - WNDCLASS wc; - wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; - wc.lpfnWndProc = mainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = ghInstance; - wc.hIcon = LoadIcon (NULL,IDI_APPLICATION); - wc.hCursor = LoadCursor (NULL,IDC_ARROW); - wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); - wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); - wc.lpszClassName = "SimAppClass"; - if (RegisterClass (&wc)==0) dsError ("could not register window class"); - - // load accelerators - accelerators = LoadAccelerators (ghInstance, - MAKEINTRESOURCE(IDR_ACCELERATOR1)); - if (accelerators==NULL) dsError ("could not load accelerators"); -} - - -void dsPlatformSimLoop (int window_width, int window_height, - dsFunctions *fn, int initial_pause) -{ - drawStuffStartup(); - setupRendererGlobals(); - renderer_pause = initial_pause; - - // create window - but first get window size for desired size of client area. - // if this adjustment isn't made then the openGL area will be shifted into - // the nonclient area and determining the frame buffer coordinate from the - // client area coordinate will be hard. - RECT winrect; - winrect.left = 50; - winrect.top = 80; - winrect.right = winrect.left + window_width; - winrect.bottom = winrect.top + window_height; - DWORD style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; - AdjustWindowRect (&winrect,style,1); - char title[100]; - sprintf (title,"Simulation test environment v%d.%02d", - DS_VERSION >> 8,DS_VERSION & 0xff); - main_window = CreateWindow ("SimAppClass",title,style, - winrect.left,winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top, - NULL,NULL,ghInstance,NULL); - if (main_window==NULL) dsError ("could not create main window"); - ShowWindow (main_window, gnCmdShow); - - HDC dc = GetDC (main_window); // get DC for this window - if (dc==NULL) dsError ("could not get window DC"); - - // set pixel format for DC - - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd - 1, // version number - PFD_DRAW_TO_WINDOW | // support window - PFD_SUPPORT_OPENGL | // support OpenGL - PFD_DOUBLEBUFFER, // double buffered - PFD_TYPE_RGBA, // RGBA type - 24, // 24-bit color depth - 0, 0, 0, 0, 0, 0, // color bits ignored - 0, // no alpha buffer - 0, // shift bit ignored - 0, // no accumulation buffer - 0, 0, 0, 0, // accum bits ignored - 32, // 32-bit z-buffer - 0, // no stencil buffer - 0, // no auxiliary buffer - PFD_MAIN_PLANE, // main layer - 0, // reserved - 0, 0, 0 // layer masks ignored - }; - // get the best available match of pixel format for the device context - int iPixelFormat = ChoosePixelFormat (dc,&pfd); - if (iPixelFormat==0) - dsError ("could not find a good OpenGL pixel format"); - // set the pixel format of the device context - if (SetPixelFormat (dc,iPixelFormat,&pfd)==FALSE) - dsError ("could not set DC pixel format for OpenGL"); - - // ********** - // start the rendering thread - - // set renderer globals - renderer_dc = dc; - renderer_width = window_width; - renderer_height = window_height; - renderer_fn = fn; - - DWORD threadId, thirdParam = 0; - HANDLE hThread; - - hThread = CreateThread( - NULL, // no security attributes - 0, // use default stack size - renderingThread, // thread function - &thirdParam, // argument to thread function - 0, // use default creation flags - &threadId); // returns the thread identifier - - if (hThread==NULL) dsError ("Could not create rendering thread"); - - // ********** - // start GUI message processing - - MSG msg; - while (GetMessage (&msg,main_window,0,0)) { - if (!TranslateAccelerator (main_window,accelerators,&msg)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - } - - // terminate rendering thread - renderer_run = 0; - DWORD ret = WaitForSingleObject (hThread,2000); - if (ret==WAIT_TIMEOUT) dsWarning ("Could not kill rendering thread (1)"); - DWORD exitcode=0; - if (!(GetExitCodeThread (hThread,&exitcode) && exitcode == 123)) - dsWarning ("Could not kill rendering thread (2)"); - CloseHandle (hThread); // dont need thread handle anymore - - // destroy window - DestroyWindow (main_window); -} - - -extern "C" void dsStop() -{ - // just calling PostQuitMessage() here wont work, as this function is - // typically called from the rendering thread, not the GUI thread. - // instead we must post the message to the GUI window explicitly. - - if (main_window) PostMessage (main_window,WM_QUIT,0,0); -} - -//*************************************************************************** -// windows entry point -// -// NOTE: WinMain is not guaranteed to be called with MinGW, because MinGW -// always calls main if it is defined and most users of this library will -// define their own main. So the startup functionality is kept in -// zDriverStartup(), which is also called when dsSimulationLoop() is called. - -extern "C" int main (int argc, char **argv); - - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow) -{ - drawStuffStartup(); - return main (0,0); // @@@ should really pass cmd line arguments -} diff --git a/Extras/ode/drawstuff/src/x11.cpp b/Extras/ode/drawstuff/src/x11.cpp deleted file mode 100644 index 4de3b0af0..000000000 --- a/Extras/ode/drawstuff/src/x11.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// main window and event handling for X11 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "internal.h" - -//*************************************************************************** -// error handling for unix - -static void printMessage (char *msg1, char *msg2, va_list ap) -{ - fflush (stderr); - fflush (stdout); - fprintf (stderr,"\n%s: ",msg1); - vfprintf (stderr,msg2,ap); - fprintf (stderr,"\n"); - fflush (stderr); -} - - -extern "C" void dsError (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - printMessage ("Error",msg,ap); - exit (1); -} - - -extern "C" void dsDebug (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - printMessage ("INTERNAL ERROR",msg,ap); - // *((char *)0) = 0; ... commit SEGVicide ? - abort(); -} - - -extern "C" void dsPrint (char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - vprintf (msg,ap); -} - -//*************************************************************************** -// openGL window - -// X11 display info -static Display *display=0; -static int screen=0; -static XVisualInfo *visual=0; // best visual for openGL -static Colormap colormap=0; // window's colormap -static Atom wm_protocols_atom = 0; -static Atom wm_delete_window_atom = 0; - -// window and openGL -static Window win=0; // X11 window, 0 if not initialized -static int width=0,height=0; // window size -static GLXContext glx_context=0; // openGL rendering context -static int last_key_pressed=0; // last key pressed in the window -static int run=1; // 1 if simulation running -static int pause=0; // 1 if in `pause' mode -static int singlestep=0; // 1 if single step key pressed -static int writeframes=0; // 1 if frame files to be written - - -static void createMainWindow (int _width, int _height) -{ - // create X11 display connection - display = XOpenDisplay (NULL); - if (!display) dsError ("can not open X11 display"); - screen = DefaultScreen(display); - - // get GL visual - static int attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16, - GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, - GLX_BLUE_SIZE,4, None}; - visual = glXChooseVisual (display,screen,attribList); - if (!visual) dsError ("no good X11 visual found for OpenGL"); - - // create colormap - colormap = XCreateColormap (display,RootWindow(display,screen), - visual->visual,AllocNone); - - // initialize variables - win = 0; - width = _width; - height = _height; - glx_context = 0; - last_key_pressed = 0; - - if (width < 1 || height < 1) dsDebug (0,"bad window width or height"); - - // create the window - XSetWindowAttributes attributes; - attributes.background_pixel = BlackPixel(display,screen); - attributes.colormap = colormap; - attributes.event_mask = ButtonPressMask | ButtonReleaseMask | - KeyPressMask | KeyReleaseMask | ButtonMotionMask | PointerMotionHintMask | - StructureNotifyMask; - win = XCreateWindow (display,RootWindow(display,screen),50,50,width,height, - 0,visual->depth, InputOutput,visual->visual, - CWBackPixel | CWColormap | CWEventMask,&attributes); - - // associate a GLX context with the window - glx_context = glXCreateContext (display,visual,0,GL_TRUE); - if (!glx_context) dsError ("can't make an OpenGL context"); - - // set the window title - XTextProperty window_name; - window_name.value = (unsigned char *) "Simulation"; - window_name.encoding = XA_STRING; - window_name.format = 8; - window_name.nitems = strlen((char *) window_name.value); - XSetWMName (display,win,&window_name); - - // participate in the window manager 'delete yourself' protocol - wm_protocols_atom = XInternAtom (display,"WM_PROTOCOLS",False); - wm_delete_window_atom = XInternAtom (display,"WM_DELETE_WINDOW",False); - if (XSetWMProtocols (display,win,&wm_delete_window_atom,1)==0) - dsError ("XSetWMProtocols() call failed"); - - // pop up the window - XMapWindow (display,win); - XSync (display,win); -} - - -static void destroyMainWindow() -{ - glXDestroyContext (display,glx_context); - XDestroyWindow (display,win); - XSync (display,0); - display = 0; - win = 0; - glx_context = 0; -} - - -static void handleEvent (XEvent &event, dsFunctions *fn) -{ - static int mx=0,my=0; // mouse position - static int mode = 0; // mouse button bits - - switch (event.type) { - - case ButtonPress: { - if (event.xbutton.button == Button1) mode |= 1; - if (event.xbutton.button == Button2) mode |= 2; - if (event.xbutton.button == Button3) mode |= 4; - mx = event.xbutton.x; - my = event.xbutton.y; - } - return; - - case ButtonRelease: { - if (event.xbutton.button == Button1) mode &= (~1); - if (event.xbutton.button == Button2) mode &= (~2); - if (event.xbutton.button == Button3) mode &= (~4); - mx = event.xbutton.x; - my = event.xbutton.x; - } - return; - - case MotionNotify: { - if (event.xmotion.is_hint) { - Window root,child; - unsigned int mask; - XQueryPointer (display,win,&root,&child,&event.xbutton.x_root, - &event.xbutton.y_root,&event.xbutton.x,&event.xbutton.y, - &mask); - } - dsMotion (mode, event.xmotion.x - mx, event.xmotion.y - my); - mx = event.xmotion.x; - my = event.xmotion.y; - } - return; - - case KeyPress: { - KeySym key; - XLookupString (&event.xkey,NULL,0,&key,0); - if ((event.xkey.state & ControlMask) == 0) { - if (key >= ' ' && key <= 126 && fn->command) fn->command (key); - } - else if (event.xkey.state & ControlMask) { - switch (key) { - case 't': case 'T': - dsSetTextures (dsGetTextures() ^ 1); - break; - case 's': case 'S': - dsSetShadows (dsGetShadows() ^ 1); - break; - case 'x': case 'X': - run = 0; - break; - case 'p': case 'P': - pause ^= 1; - singlestep = 0; - break; - case 'o': case 'O': - if (pause) singlestep = 1; - break; - case 'v': case 'V': { - float xyz[3],hpr[3]; - dsGetViewpoint (xyz,hpr); - printf ("Viewpoint = (%.4f,%.4f,%.4f,%.4f,%.4f,%.4f)\n", - xyz[0],xyz[1],xyz[2],hpr[0],hpr[1],hpr[2]); - break; - } - case 'w': case 'W': - writeframes ^= 1; - if (writeframes) printf ("Now writing frames to PPM files\n"); - break; - } - } - last_key_pressed = key; // a kludgy place to put this... - } - return; - - case KeyRelease: { - // hmmmm... - } - return; - - case ClientMessage: - if (event.xclient.message_type == wm_protocols_atom && - event.xclient.format == 32 && - Atom(event.xclient.data.l[0]) == wm_delete_window_atom) { - run = 0; - return; - } - return; - - case ConfigureNotify: - width = event.xconfigure.width; - height = event.xconfigure.height; - return; - } -} - - -// return the index of the highest bit -static int getHighBitIndex (unsigned int x) -{ - int i = 0; - while (x) { - i++; - x >>= 1; - } - return i-1; -} - - -// shift x left by i, where i can be positive or negative -#define SHIFTL(x,i) (((i) >= 0) ? ((x) << (i)) : ((x) >> (-i))) - - -static void captureFrame (int num) -{ - fprintf (stderr,"capturing frame %04d\n",num); - - char s[100]; - sprintf (s,"frame/frame%04d.ppm",num); - FILE *f = fopen (s,"wb"); - if (!f) dsError ("can't open \"%s\" for writing",s); - fprintf (f,"P6\n%d %d\n255\n",width,height); - XImage *image = XGetImage (display,win,0,0,width,height,~0,ZPixmap); - - int rshift = 7 - getHighBitIndex (image->red_mask); - int gshift = 7 - getHighBitIndex (image->green_mask); - int bshift = 7 - getHighBitIndex (image->blue_mask); - - for (int y=0; yred_mask,rshift); - b[1] = SHIFTL(pixel & image->green_mask,gshift); - b[2] = SHIFTL(pixel & image->blue_mask,bshift); - fwrite (b,3,1,f); - } - } - fclose (f); - XDestroyImage (image); -} - - -void dsPlatformSimLoop (int window_width, int window_height, dsFunctions *fn, - int initial_pause) -{ - pause = initial_pause; - createMainWindow (window_width, window_height); - glXMakeCurrent (display,win,glx_context); - - dsStartGraphics (window_width,window_height,fn); - - fprintf (stderr, - "\n" - "Simulation test environment v%d.%02d\n" - " Ctrl-P : pause / unpause (or say `-pause' on command line).\n" - " Ctrl-O : single step when paused.\n" - " Ctrl-T : toggle textures (or say `-notex' on command line).\n" - " Ctrl-S : toggle shadows (or say `-noshadow' on command line).\n" - " Ctrl-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" - " Ctrl-W : write frames to ppm files: frame/frameNNN.ppm\n" - " Ctrl-X : exit.\n" - "\n" - "Change the camera position by clicking + dragging in the window.\n" - " Left button - pan and tilt.\n" - " Right button - forward and sideways.\n" - " Left + Right button (or middle button) - sideways and up.\n" - "\n",DS_VERSION >> 8,DS_VERSION & 0xff); - - if (fn->start) fn->start(); - - int frame = 1; - run = 1; - while (run) { - // read in and process all pending events for the main window - XEvent event; - while (run && XPending (display)) { - XNextEvent (display,&event); - handleEvent (event,fn); - } - - dsDrawFrame (width,height,fn,pause && !singlestep); - singlestep = 0; - - glFlush(); - glXSwapBuffers (display,win); - XSync (display,0); - - // capture frames if necessary - if (pause==0 && writeframes) { - captureFrame (frame); - frame++; - } - }; - - if (fn->stop) fn->stop(); - dsStopGraphics(); - - destroyMainWindow(); -} - - -extern "C" void dsStop() -{ - run = 0; -} diff --git a/Extras/ode/drawstuff/textures/ground.ppm b/Extras/ode/drawstuff/textures/ground.ppm deleted file mode 100644 index 69a438c0e..000000000 --- a/Extras/ode/drawstuff/textures/ground.ppm +++ /dev/null @@ -1,5 +0,0 @@ -P6 -# Created by Paint Shop Pro -256 256 -255 -››”‹„‹œ››¦§¨œ¤¦ƒ„„œ¤¦œ¤¦ƒ„„œ¤¦„„Š“““¦§¨›”›“Œ”¦§¨mtt‹…’œ››‹’Š’ŒŒ”š”‚v{œ¤¦‘ˆ}”››{{tdc\„Š„‹‹‹„Š}dc\…‹‹„Š„‹’Š”››„Š}¦§¨ƒ||UTSu{{bVU{{t‹„„„Š„|„…Œ”•lritt{‹‹‹‹‹‹zllf]c‹„‹“Œ”SKJŒ‹“™š¤Œ”•‹…’|„…{ttlekzll””‹‹‹„|‚z[[Ttslƒƒ|uztœ¤¦‹’ŠlriŒ”•„Š„””‹ƒ„„“““ƒƒ|ƒƒ|“Œ”ƒ‚uƒ||ƒ}ƒƒ}ƒ¨©´„„Šmtttts“Œ”lks}|’Œ‹“lekŒ‹“›”›‹‹‹lld|‚z”š”|‚zSKJ]bZƒ}ƒttsddc{tt[TTult{tttll‚v{tllŠƒ}cbV‹„„dc\lrijcVsre[TTsleSKJj]\\[[¦§¨:97*)(ztlJHFlddJHFVTL‘…„bVUVTLddcb[U…‹‹lrib[Uultmttlldllklld|„…dc\|‚z‹‹‹mtt“““‹‹‹Œ”•tslƒƒ|‚|utts‹„‹ddc„Š„{{tŒ”•mtt\UZ‹„„‹„„Œ‹“‹„„lj‘Œ…ƒ||ŠŠ}ttslldkd\lddult|‚z|‚zu{{ek]ƒƒ|lri|‚zztltsltslztl[[T„„Š{u{Œ”•]bZldd]cddc\mttUMRlddƒ}ƒVZTSKJD;9mttlld\[[Œ”•JHFUTSJHF[TT‹‹‹Œ‹“Œ”•‹„„ƒ||Œ”•œ¤¦tzlŒ”•mttŒ‹“|„…lksddc|„……„’“Œ”Œ”•{{ƒ}‡’|„…œ§²}|’”“›™š¤|„…}|’|„…„„Š{{ƒ›²„„ŠŒŒš™š¤„†™Œ”•™š¤›²{{ƒ{{ƒŒ”•}‡’…‹š¬¶Ã™š¤™š¤¬¶Ãœ§²…‹‹tts“Œ”llk“““‹‹„{{tš””{||„Š„ƒ||‹‹‹{||…‹‹”š”„Š}¤¤¦§¨›¢›¦§¨«²«‹’Šmttd\\tllultVTL‹„‹ƒƒ|‹‹„cbVœ››{ttƒ}ƒ{ttµ¶·“Œ”ult‹„‹r]gultf]c‹’Šƒ„„bVU‘ˆ}Š}ƒtll“Œ”„Š„tlllekztl{{t{tt”››mttult“Œ”{u{tllultŠƒ}{||‹„‹‹„‹“Œ”{{ƒŒŒšldd…‹’{{ƒ™š¤]cdƒ}ƒ“Œ”£œ¥ª³·…‹‹¦§¨ª³·‹„„{{ƒ‹„‹ƒ„„|„…u{{„„Š…‹‹{{ƒlksŒ”•”“›ª³·ƒ„„’…‹‹‹‹‹„„UUYldddc\ŠŠ}{{t‹‹„‹„‹‹„„’ŒŒ‘…„ultŠƒ}sre{zmttsj]\VTL„Š„SKJrg]iWU‚v{ekd¦§¨:97$kd\uztultultlddbVUVTLSKJkk]ŠŠ}‘Œ…ŠŠ}››”ztlVTLtzl{||lld‚|utts””‹tsl‹‹‹‹‹‹tsl…‹‹dc\tzlsle|„…u{{ekdtyglri”“›{||]cd{u{tzl‚v{ztl{{t|‚z‹„‹‚v{‚|uƒ||VTLddcb[UbVZ|‚z[TT[[Tlri{tt{u{rfklldttsd\\ult‹„‹‹„„{tti\Vredtzlllk{{ƒiq]{ttdc\ekddc\ztlƒ„„tzl]cd…‹‹JHFjcVLKRŠƒ}™š¤¦§¨uzt{{ƒ”“››¢›mttd\\\[[|„…|‚zuztnv‚mttlks{{ƒ„„Šœ¤¦}‡’^^qŒ”•mttddcŒ”•ŒŒš{{ƒnv‚}|’|„…lks}‡’…‹’yl„nv‚›²ª³·…„’ª³·nv‚Œ‹“}‡’{{ƒŒ—£Œ”•ª³·™š¤™š¤™š¤Œ”•ŒŒš“““Œ‹“Œ”•edk{{ƒ”“›Œ”•f]c|‚z‚|u”š”ƒƒ|{{t””‹ƒ„„ƒƒ||„…””‹„Š}{||JHF|„…{{ƒultredƒ}ƒŒ”•|‚z{||ª³·“Œ”ƒ}ƒzll›¢›‹’Š‹’Šƒ„„’…‹‹„‹|‚z„Š}jcVtll„Š}¤¤‰‰w{||„Š}ttsmttœ¤¦u{{tt{ttsu{{VTLlrimtt\[[|‚zlrilldmtttt{lks|„…tsl|„…„Š„™š¤‹…’\[bf]c‹…’lkslriƒ|||„……‹‹lks‹’Šƒ}Šdc\ultƒ}Š{u{tts…„’ŒŒš”𔋒Šu{{ddc|„…‹‹‹‹„‹UUYŠƒ}]bZtslddc“Œ”slesre‹„„‚v{lddslecbVSKJ{{tdc\kd\tzltslƒ||‰v|j]\[[T“Œ”:97:97cbVlrid\\tlltllldd[[T|‚zcbV„„Š””‹‹’ŠŠŠ}£››ŠŠ}“““{||lkscbV””‹„Š}tzl{u{ƒ„„{tt„Š}ekd{{tek]f]c{u{‹’Šddctll{u{lekƒ}ƒtll‹‹„dc\‹„„{tt{||{||ult‰v|ultult]bZ‹‹„‘Œ…{||tzledk]cd…‹‹‹‹‹fkktllsle[[T\[[ttslriekdmtt|„…tsllri\[[b[U{{t‹„‹‹‹„uzt[[Tddc[[T|‚z{{ƒd\\UTSult{tt{{tyl„lkstt{ult|„…|„…{{ƒ{{ƒ{{ƒ|„…{{t{{ƒŒ”•lks{{ƒ…„’Œ”•|„…nv‚{{ƒ|„…Œ—£fkk…‹’{{ƒ}|’^fsŒ”•™š¤Œ—£lkslksnv‚}‡’™š¤Œ—£Œ—£Œ—£|„…nv‚}‡’¡¡»ÂÇ»ÂǪ³·œ¤¦Œ”•ekd¦§¨…‹‹uztƒ„„‹‹„¦§¨“Œ”‚utlld‹‹„”“›Œ”•„Š}™š¤™š¤{{ƒ™š¤”š”œ¤¦„Š„ddcedkddclritsl{{ƒŒŒš‹‹‹‹‹‹lek””‹‚|u‹‹„lddztlred’ŒŒ‚|uŒ‹“]bZtslSKJf]cœ››‘ˆ}œ¤¦[[T‰v|“Œ”ƒ||{{ƒ‹„‹ƒ}ƒŠ}ƒult“Œ”f]c[TTlddd\\ƒ||\[b[TTUMRult|„…£œ¥¦§¨š””ƒ||¦§¨lld“Œ”‹‹‹|„…lksd\\{tttt{{|||„…‹‹‹ƒƒ|‹‹‹{u{rfkŒŒštt{ª³·|„…›¢›…‹‹|„…‹’Š”››uztf]clddrfk{{tsle‹„‹‘Œ…tll‚|urfkzllb[Ukk]ztlztldc\cbV|‚z{{tbVZ[TTSKJ‚utllk¦§¨LKR*)(rg]llk‹’Šlekult{u{VTLVTLllkƒƒ|uztVTLVTLedk|‚z{{t”“›‹„‹tsl|‚z|‚z“““ddcddcekd”š”VTLlri‹‹„f]cult…‹’ƒ„„tslŠƒ}™š¤{{ƒztl{{ttslƒ||sle]cdtll{{t{{tultŠ}ƒ|‚z{{tult{||mttVZ[JHF]bZ|„…lks‚v{f]cekdtt{‹„‹tll[[Tƒ}ƒƒ||Œ‹“{{ƒ{u{{{t]bZ{tt””‹¤¤‚|u‹’Štts‹‹„lld]bZ\[bSKJlksd\\tll“Œ”{{ƒttsu{{Œ”•tslu{{{{ƒmttek]}‡’„„Š|„…{{ƒ„†™u{{Œ”•Œ”•mtt|„…„„Šttsmttyl„nv‚^^q\[b\[bnv‚tt{†~‘u{{}‡’\[bnv‚n…œ§²Œ—£œ§²n…œ¤¦œ››Œ”•”𔋒Ћ‹„{{tŒ”•”𔍩´œ¤¦ƒ„„™š¤{||Œ‹“’ŒŒ“Œ”…‹’Œ‹“‹‹‹”š”™š¤œ››ƒ}ƒ‚utult™š¤lekddc…„’„„Š„„Š”“›{{ƒ‹„‹tsl‹„„‹‹„“““{{tƒ„„leklks¦§¨{tt¨©´‹„„“Œ”’…‹‹„‹„„Š|„…£››Š}|“““ƒ}ƒ²¬µbVZultlksŒ—£ƒ„„„„Šedktsl{{t…‹‹lks|„…llkdc\ttsfkk|‚z|‚zuztuztztllld››”{tt¦§¨u{{|‚zƒƒ|“““Œ‹“””‹‹„„„Š„tt{“Œ”…‹‹™š¤‹’Šuztœ¤¦œ¤¦{u{‹’Š„„ŠŒ”•‹’Šdc\{u{ƒƒ|‹‹„lldtt{£››‚v{ƒ||j]\‚ut{{trg]PF=]bZ[TTlri{{t{{tddcSKJbVUlldUTS¦§¨JHF*)(d\\ŠŠ}‹‹„{tt‹„‹lddlldsref]cf]clritslsleƒ„„llkš””„Š„u{{‹‹‹ekdlrilrimttlks{zm|‚z‹’ŠaWM‹„„lek‹…’|„…red\[[dc\ttsUTSš””››”‹„‹Š~‹tsl›”›‹„„kk]ult{{tƒƒ|ultd\\‚|uultf]cLKR:97MRKŒ”•“““›¢›””‹llk‹’Š{||{{ttzllri\[[llktslu{{¦§¨ƒƒ|ƒ„„œ››[[Tztlƒ‚u{{ƒ[[Tlrirfk\[[VTLmtt‹’Š{||‚v‚ƒ}ƒ‹„‹{{t|„…uzt”››]cd|„…tt{fkk{{ƒ|„…{{ƒŒŒš{{ƒ|„…Œ—£~’“‰Š¡|„…”“›|„…ttsnv‚…‹’}‡’}‡’{{ƒŒŒšnv‚lks{{ƒ…‹’™š¤}|’…„’ƒ}ŠŒŒšnv‚mk…Œ”•Œ”•™š¤ƒ}ƒƒ„„Œ”•{{t™š¤‹’Š«²«œ¤¦™š¤Œ‹“…‹‹™š¤¦§¨”“›tts‹‹‹llk™š¤”“›{{ƒƒ}Šult£œ¥{{ƒlks|„…\UZ£œ¥’ŒŒ¨©´”“›‹„‹“Œ”£œ¥tts£œ¥“Œ”|„…œ››œ››²¬µ£››f]c“““red|‚zuzttts{{tJHFƒ||’…‹lddldd{ttultSKJ‹„‹›”›VZT{u{uzt…‹’{{ƒ|„…ƒ‚u”“›““““Œ”ƒ}ƒ‹‹‹|‚z£œ¥ƒ„„œ¤¦uztƒ}Š|„…‚v{‹…’|„…Œ‹“…‹’tt{edk|„…lks‹„‹{{ƒmtt]cdŒ”•|„…{{ƒtt{tll{{tmtt„Š}‹„‹lldrfk„Š}Š}ƒŒ”•ultrfk‘Œ…ztl””‹Šƒ}ztf{zmd\\|‚zdc\dc\]bZƒ}ƒaWMtt{\UZFD;™š¤?;C?;Cred””‹lldj]\f]ctlllldƒ„„{{ƒllk„„Šekdƒ||j]\ultlektt{\[[ldd…‹‹tygek]ult\UZ]bZƒ||lridc\{ttult…‹‹„Š}{u{rfk…‹’lri|„…ult‹‹„{||ƒ||tslŒ”•|„…ƒ‚uƒƒ|{{tdc\cbVƒ„„¦§¨„Š„„Š„MRK*)(UTSlldƒ„„”››mtt„Š„ddc”“›ekdllkttsllk{u{]bZƒ„„\[[…‹‹‚|u””‹„Š}ƒƒ|‹„„ddcleklldŠƒ}kjVSKJUMR‹’Šƒ}ƒ™š¤£œ¥…‹‹tts|„…|„…Œ‹“lks{{ƒ“Œ”u{{‹‹‹mtt†~‘Œ—£Œ”•Ž¡›}‡’}‡’™š¤¨©´…‹‹|„…^^q}‡’n…tt{Œ—£{{ƒ…‹’™š¤™š¤“Œ”…„’Œ—£™š¤Œ”•|‚zu{{Œ”•ƒƒ|ª³·‹’Š›¢›‹„„{||‹’Š|„…”š””››|‚z‹„‹œ››ƒ„„¦§¨²««¨©´™š¤llk„„Štt{œ¤¦œ§²’…‹Œ”•‹…š‹’Š|„…lks‚v‚ttsllk”“›™š¤“““…‹‹…‹‹ƒ||›¢›‹’Š‘…„’ŒŒƒ„„red£›››”›sre””‹’ˆ{{t{zmuztlddlldsle„Š„\UZtts‰Š¡tts|„…{u{{{ƒ‹…š’ŒŒ“Œ”‹„‹{{tuztƒ„„¦§¨””‹{tt‹‹„ƒƒ|rg]kk]ƒ„„’ŒŒ‹’Š“““™š¤¨©´”››¨©´|„…„„Š{{tœ¤¦…‹’”š”Œ‹“|„…|„…u{{fkk‹’Š”››”š”mtt|„…ª³·‹‹‹JHF‚v{™š¤tzli\VtslbVU‚v{”š”rfkr]gyleSKJtsl\[[„Š„leklldƒƒ|JHFztfb[U]bZ[[T¦§¨UUY:97lldsleuztrfkr]gekdVTLj]\d\\\[bdc\‚|u””‹ƒ||{u{{||tsl|„…‰ƒv[TTkk]lri‚|u|‚zu{{{tttsl{tt‹‹‹’…‹{||‹‹‹ultsle{u{\[[|„…‹‹‹…‹‹¦§¨š””ƒƒ|‹„‹{||ekd“““bVU‹’Šƒ„„“““lldtts{ttJHF:97o€wVTLuzttzlƒƒ|‹‹„lldrg]j]\ƒ‚usreJHFlrillkrg]dc\’ŒŒ‘Œ…ŠŠ}ddcƒ„„|‚z]bZ|„…mttSKJmwf]cf]clkslks“Œ”„„Š‹’Š|‚z|„…ult{{ƒ{{ƒƒ„„{||‹’Š…„’mttŒ—£{{ƒ}‡’„„Šn…{{ƒyl„Œ‹“mtt|„…{{ƒ}|’nv‚™š¤Œ—£^fs{{ƒ…‹’mtt¨©´™š¤Œ—£œ§²…„’Œ—£}|’lksedk›¢›“Œ”””‹“““›¢›œ¤¦··Ä‹„„™š¤„„Šƒ}ƒ£²£››¨©´”“›¨©´‹…’tts{{ƒmtt{{tŒ”•‹‹„llk”š”…„’ztl{{ƒ\[bŒ‹“bVZred{||ztl‹’Ф¤¦§¨„Š„””‹u{{ekdlek”“›mttœ¤¦Œ”•tslœ¤¦Œ”•lriu{{tts{||’ŒŒ…‹’{u{\[b‹…’{u{{{ƒ|„…ŒŒš…‹‹f]ctll”š”Œ”•|‚z]cd|„…edk|„……„’{{ƒ”››ttsŒ‹“u{{{{ƒŒ‹“{{ƒ²¬µ™š¤„„ŠŒ”•lek‹’Š››”tts…‹‹mttlkstt{„Š„Œ”•„Š„lriddc|„…|„…uzt™š¤sreUMR„„Š|„…tllbVUƒ||Š}ƒ“““SKJ‚utŠƒ}kd\‚wlultdc\“Œ”‹‹„””‹llkPF=]bZSKJVTL¨©´f]c:97lekztl‘Œ…ƒ‚uƒ„„‹‹‹tzllek[TTf]clks]bZ””‹‹‹„u{{{{ƒtsltll{||Š}|„Š}\[[u{{“Œ”mttVTL„Š}{tt‹„„‹‹„{{ƒ‹„‹œ››srettsLKRmtt{||sletzl‹‹„””‹“Œ”†~‘ulttts‹„„lks“““‹„„›”›f]cbVZUTSVTL[TT]cdƒ}ƒƒ||lddf]c{tt“Œ”[TT[TT{u{d\\UMRJHFJHFlekekdŠƒ}tzl]cdkd\ultu{{„Š„„Š„r]gf]cJHFddclrilriultŒ‹“Œ‹“…‹’Œ”•„vŒ{u{\[blks|„…mtt|„…]cdmttŒŒšmtt…‹‹Œ—£ƒ}Й𤅄’|„…|„…\[bmttOS`Œ—£lksŒ—£{{ƒ™š¤}‡’¨©´œ¤¦¬¶Ã…‹š|„…{{ƒŒ—£œ§²…‹šƒ}ƒ‹…’£²¨©´Œ”•›¢›œ¤¦‹„„›”›“““tts›¢›”“›“Œ”‹„„“Œ”slekk]”“›ƒƒ|tt{tts‹’Š{||uzt“““‹‹„ultztlekdtll{tttslƒ||››”‹‹‹ƒ||£œ¥”“›f]c“Œ”‹„„““““Œ”‹„‹“Œ”tt{„vŒlddJHFMRKfkkiq]uzttts™š¤Œ‹“lks™š¤\[b]bZlksultŒ—£]cdlri]cdSKJbVU‹„„MSS{{ƒ|„…\UZult|„…Œ”•tt{u{{ŒŒšƒ„„{u{lddŒ‹“mttlld‹„‹{||””‹œ››lrilri””‹|‚z‹‹„lldtsldc\dc\ƒƒ|mtt|‚zuztSKJtllkd\{ttultzlliWUztlsleSKJzllslekd\‚v{ekdtslUTS]bZllkVTLd\\VTLek]…‹‹\[b*)(f]credtllsre{{tekd[TTddcult‹„‹dc\dc\tsltsl|‚zu{{‹’Š„„Šƒ}ƒsreƒ‚u››”Œ”•ztl„Š„””‹‹„„ŠŠ}b[Ub[UŒ”•\UZlekulttt{„Š}|‚z„„Š„„Š”š”{u{ƒƒ|™š¤sletslsreœ¤¦“““’ŒŒƒƒ|{u{f]cedkUUYUMR|„…{{ƒ…‹‹Œ‹“lri„Š„ztl{u{|‚ztllUMR‹’ŠVTL\[[ƒƒ||‚zkd\sle””‹llk[TTult{tt“Œ”kd\D;9edkJHFllkd\\sretts|„…Š}ƒœ››llklkslks\[b}‡’ekd…‹’{{ƒo€w…‹’¦§¨|„…{{ƒlks{||ult{{ƒmttmtt^fsu{{}|’}‡’nv‚nv‚|„…|„…mttœ¤¦}‡’œ§²}‡’Œ”•¬¶Ã„„ŠŒ—£Œ”•|„…Œ‹“ª³·Œ”•„Š„›²œ¤¦··Ä™š¤uztlriœ¤¦Œ”•ƒƒ|„„ЄЄtzl””‹b[Uƒ||ƒ„„Š~‹ƒ„„u{{‹’Š{||‹„„lks™š¤lek„„Š…‹‹™š¤“Œ”ztlƒ||¤¤¦§¨””‹lri‹„‹¨©´””‹”“›£››ƒƒ|{{tdc\¦§¨ultŠŠ}‹„„„Š„‹„„ƒƒ|››”|‚zƒ}ƒœ››ƒ„„Œ‹“lek]cd\[bUTStt{ƒ}Š{{tSKJ[TTtt{lldŒ”•fkkŒ—£Š~‹Œ”•{{ƒŒŒšŒ”•“““‹…’ult”“›ttsultƒ||\[bultf]c‹„„…„’u{{{u{|„…™š¤tt{ttslddŠ}|‹‹„|‚zdc\j]\d\\VTLlri¤¤{ttf]ctslldd‚v‚š””ztl{ttldd‹„‹‚v{cbVuztƒ}ƒtllVTLllktsl¦§¨\[b)+2mtt‚|utlltsllekb[Urg]ƒ‚uƒ„„{||dc\ek]|‚z“Œ”¨©´›”›™š¤‹„‹zllsreƒƒ||„…{|||‚z|‚z‚|uƒ‚ulldztlttstt{ultttsulttt{rg]ƒ||{u{”“›‘Œ…’…‹ƒƒ|ult‚v‚Œ”•red’ŒŒŒ‹“‹„‹ldd’ŒŒ‹„‹ƒ}ƒd\\[TTƒ||ƒ}ƒlek|„…‹‹‹lri{u{lld{||\[[ek]SKJtsl[TTb[Ulld|„…dc\ƒ‚usresle\UZldd{u{ztltsl[TT>B9o€wulttslnv‚“Œ”£œ¥Œ‹“Œ‹“…„’ŒŒš}‡’{||”“›Œ”•|„…ultnv‚Œ”•™š¤{{ƒ„†™™š¤…„’ŒŒšŒ”•u{{u{{|„…lksmk…Œ—£œ§²{{ƒ‰Š¡Œ”•}‡’{{ƒ™š¤Œ”•˜Ž£™š¤™š¤ŒŒš™š¤„Š„|‚z”››œ››{||”š””š”£››‹„‹““““““redƒ„„…‹‹‹‹„{u{‹’Šlri””‹‹„„|‚zƒ||‹‹„š””{tttslƒ||ƒ„„™š¤„„Š{tt„Š„sle‹‹‹’ŒŒ‹’Šz‚l”››ƒƒ|uzt¦§¨ŒŒš{u{’ŒŒ›”›{u{„Š„ztl{{tlldœ¤¦ƒ‚usle“““sleŠŠ}tt{j]\f]cf]cultult™š¤˜Ž£lks{ttedk\[b{{ƒllkddc]bZ{{tlld{ttƒ}ƒ¦§¨‹„„]cd„„Š{u{tts…‹‹UTS|‚ztts“““uztekdlld|„…›¢›ztl\[b‹‹„£œ¥“““‹‹‹„„Šmtt›¢›lksSKJ{ttlrikk]dc\UUYsle[[TjcVmttkd\ƒ||rg]tts{||‹‹„tllsleJHFddcdc\b[Uult{||›”›\[[:97‹„„zll{{ttslztlsreUMRztltts\UZ{{t{{tttslekŠ}|”“›ult…„’{{tŠƒ}kk]d\\{u{„‰vtzlŒ”•‹„„tslzlllrif]c‹„‹‚|u‚utUTSult‹‹‹tzl“Œ”’ŒŒ“““Œ‹“f]cƒ||‹‹‹‹„‹‹„„ult{u{{u{ƒƒ|Š}ƒldd[TTSKJ{{t“Œ”Š~‹ztl{tt{ttreddc\{tt‹„„‹…’‹„„””‹{||uztSKJ{zmek]lrittsldd‚v‚u{{UMRultD;9UTSLKRlri…‹’›¢›{u{{u{’ŒŒ{{ƒŒ”•{{ƒtt{lekttslriƒ}ƒtts]cd{{ƒu{{{{ƒlks˜Ž£‰Š¡„†™‹„‹¦§¨ª³·mtt{{ƒ^fsœ¤¦…„’…‹’…‹šŒŒš|„…œ¤¦Œ—£mttœ¤¦Œ”•œ¤¦{{ƒŒ”•~’“™š¤tt{…‹‹”“›tllƒ„„“Œ”Œ”•ŒŒš“Œ”„„Š{{ƒ‹…’Œ‹“””‹{|||‚zedk|„…|„…¦§¨„Š„{tt“Œ”’ŒŒ£››ƒ„„SKJ’ŒŒš””{ttŠ}|j]\tllJHF{{ƒ™š¤{{ƒlri|‚zdc\ƒ„„tsl{||{{ƒ‹’Š„„Š{{ƒkd\ztl””‹š””„„Š…‹‹\UZƒ}ƒƒƒ|{||f]c‚v‚Š~‹f]c{{ƒ˜Ž£¦§¨{tt”››ƒ||lek‚|u{ttuztult…‹’ttsŒ”•ƒ}ƒƒ||Š}ƒƒ}ƒ””‹lldƒ}ƒ{tt‹…’™š¤“Œ”u{{ultlks’…‹“““Œ”•{{ƒ‹„„œ››‹‹‹Œ”•tts|‚z\UZllk[TTddctsl]bZtzlSKJreduzt”“›u{{lddŠ}|‹‹„{ttekd‹„„ztfred[[T{{tek]redllkŠƒ}¦§¨[TT:97‹‹„zll””‹kk]d\\kd\lldred\[bf]clldlri{u{„„Š’ŒŒ{||tzllddœ¤¦f]cƒƒ|llkult’ŒŒ{zmztl”“›ŠŠ}‚v{kd\tts‘…„£œ¥lks‹„‹ƒ}ƒmttu{{mttuzt‹„„ƒ„„]cd‹„„’ŒŒult‚ut|„…“““ƒ„„¤¤„Š„„Š„ƒƒ|[[T|„…{ttƒƒ|ƒ„„{||ƒ||lri„Š„ƒ||‹…’ztlbVZ“““[[T‹‹„ƒ||cbVlldMRKd\\ekdƒ}ƒƒ„„SKJj]\SKJUMRultƒ„„{zmƒƒ|mwŒ‹“Œ‹“{{ƒŒ”•ƒ}ƒƒ}Šult…‹‹…„’„†™Œ‹“‹‹„{{ƒƒ„„›²„„Š|„…œ¤¦…„’”“›”››Œ”•]cd]cd}‡’lkslks…„’tt{˜Ž£{{ƒ\[b{{ƒf]c…‹’mtt™š¤„„Š…‹‹™š¤{zmƒ}Š‚v{”“›„„Š…‹’œ¤¦œ¤¦™š¤¨©´¨©´¬¶Ã“““‹’Ф¤‹’Š‹’Ѝ©´‹‹‹ª³·œ¤¦›¢›{zm‹’Š‹‹„ƒ„„“Œ”tts|„…„„Š]cd“Œ”„„Šlek…‹‹tsltt{ztltts|‚ztsl{zm£››£œ¥tsl‹‹‹ultu{{tll‰|vƒƒ|tlltsl{{ƒŠŠ}b[U‰Š¡™š¤“Œ”‹…š‚v{ƒ}ƒ‚v{ldd”“›{{ƒ”“›…‹‹fkkƒ}ŠUTSƒ}ƒ“Œ”‹„‹“Œ”‹‹‹{|||„…„„Šllk{tt{{t‹„‹š””£››‹„‹£››ƒ}ƒtlllek‚v‚ƒ}Šldd{u{ƒ||tt{Œ‹“|„……„’‹‹‹{u{‹„„cbV„„Š|„…lldiq]jV[Šƒ}”››››”ztl‹„„tslSKJ‚utVTLlri‚v‚lriUTSlddJHFFD;llktts›¢›SKJ:97lld{u{Œ”•‘…„£››ƒ||rg]JHFlek[[T|‚zekdldd™š¤bVU‹‹‹|‚zVTLek]|‚zdc\…‹‹|‚z„Š}‹‹‹‹‹„š””ƒƒ|ƒƒ|tsl‹‹‹…‹’£œ¥tll‹„‹‹‹‹„„Š‚ut{||tt{‹‹„llk“Œ”ekd‘…„tllƒ‚uƒ„„{{t[[Tœ››{{ƒ…‹‹|‚z{{ƒVTLtt{””‹tllttsŠ}ƒtsl“Œ”{tttts[TTyl„{u{lddekdVTLUMR‚wlsre{u{kd\lksu{{\UZf]csleg\rred™š¤mtt‚v{{||Œ‹“{u{ƒ}ƒƒ||lek{||{{ƒ{{ƒŒ‹“™š¤{||‹…š}‡’‹„‹„„Š{{ƒ…‹šŒ”•tt{„„Š…‹’|„…mttmtt^fs{{ƒ‰Š¡|„…„„Š{{ƒ{{ƒŒ‹“Œ”•{{ƒ¦§¨|„…Œ‹“Œ”•‹‹‹¨©´¦§¨™š¤…‹’™š¤¨©´„Š„›¢›}‡’¦§¨¨©´··Äƒ„„‹‹‹ƒ}ƒldd‚v{‹‹‹‹’ŠšŒ›¢›””‹™š¤tlluzt“Œ”tsl{{tf]cJHFf]cult¦§¨Œ”•tt{œ¤¦Œ”•œ››ƒ‚u”š”Œ”•‹‹‹ƒƒ||„…œ¤¦™š¤”“›[[Tsle[[Tkd\f]c‹„„›”›“Œ”Œ‹“ƒ||tt{\UZ{{ƒ|„…\[blkslri]bZ¦§¨ttssle{ttŒ”•tts„Š„zllkd\tllultŠ}ƒlekmttedk“Œ”{{ƒ“Œ”{{ƒ{{ƒ…‹‹{{ƒlld¨©´ƒ„„|‚z„Š„lld‹‹‹¦§¨¦§¨œ››lri¦§¨tts…‹‹‹’ŠcbVUTStt{|‚z\[[{{t\UZ{ttttssre„Š„slerfkƒ||‚|u{ttƒ„„fkkddc[[Tllkz‚lmttlriztl¦§¨UMR:97ƒƒ|‚|ukd\ztlu{{šŒylekd\{tttll„Š„ek]llk|„…{ttƒ||{||‚wl„Š}]bZ‹’Šlriuzt…‹‹””‹ldd”“›ƒ}ƒ{{t‚|u‹„‹uztult“Œ”{{ƒult{||”š”ƒ||“““ƒƒ||‚z{{ƒf]czllultƒ||SKJ{ttsleuztƒ||{{ƒMRKUMRlek‘Œ…””‹“Œ”š””f]c{ttdc\tlld\\tsltllj]\VTLVTL‹u…tt{‚v‚tslƒƒ|[[T[TT\UZult’ŒŒzll“Œ”ultedkldd|‚z””‹{u{›”›lddddc{{ƒtts{{ƒ”“›Œ”•…‹’‹„‹{{ƒyl„„„Š™š¤lksŒŒšŒ—£|„…\UZŒ‹“mtt|„…{{ƒnv‚{{ƒ…‹š¦§¨˜Ž£“Œ”Œ‹“™š¤‹„‹|„…”“›{{ƒnv‚{{ƒ{{ƒ}‡’”›››¢›‹‹„Œ—£››”‹…’¦§¨“““’ŒŒ¨©´ª³·u{{”››”››„Š}™š¤‹’Š…‹‹Œ”•lri‹‹‹uzt”š”llk‹‹„lek{||f]c\[[›”›¤¤œ›››¢›“Œ”Œ‹“”“›…‹‹‹‹‹“““„„Š‹’Šllk|‚zŒ”•Œ”•{ttultmwlekb[Ulri”𔑅„”››mtt’…‹“““f]cƒ„„sle“Œ”›¢›{ttVZ[mtt‹’Š]cdnv‚|„…lks]bZŒ”•£››››”Œ”•Œ”•‹‹„‹‹„‹„‹¦§¨‹…’“Œ”“Œ”ª³·‹‹‹zlltsl‹‹‹”š”ldd{ttultfkku{{“““{{ƒ™š¤Œ”•‹„‹‹…’ldd„Š„tsl\[[lri{{t¤¤tt{d\\VTLƒ||‹‹‹””‹ttslrikd\ƒƒ|SKJaWM[[Tf]c[TTVTL‹’Šlldlri«²«JHFUUYsleƒ||lddƒ||‹’Š‹„‹…‹‹{ttultedk‰ƒvlritsltts{{ƒƒ||{zmult’ŒŒƒ‚ntzlsretts|‚zztl‹‹„{tt{{t{{ƒ|‚z‹‹„£²tll£››‚ut”𔍩´’ŒŒƒƒ|]bZkd\’ŒŒŒ‹“{u{ztlldd{{ƒd\\edktt{‹‹„œ››ƒ||UUY[[TLKR{{ƒf]cultttslksultUMRlksddc\UZ\UZlekƒ}ƒrfkŠ}|‹„„tsl|„…{{tultttsƒ}ƒ{||šŒtll“Œ”f]cmtt{{tj]\f]cƒ}ƒmk…{tt|‚zmttu{{lks{{ƒ|„…lksult\UZtlllek‹…’ƒ„„\[bƒƒ|^^qŒ”•\[[mtt|„…Œ”•n…{{ƒMSSultœ§²¨©´›²{{ƒ~’“{{ƒœ¤¦^fs}‡’Œ—£œ¤¦‰Š¡š””𔔦§¨“““‹‹‹¦§¨‹„„‹’Š“““œ¤¦›¢›{||„„Š}‡’Œ‹“™š¤|„…›¢›œ¤¦‹’ŠŒ”•llk{ttƒƒ|]bZƒƒ|‹‹‹„Š„„Š}ƒ„„{{ƒ‚ut“Œ”tll‹’Ѝ©´œ››‹„„“““ƒƒ|ƒ‚uƒ||‹„„‹„‹¦§¨œ¤¦{{tƒ||‹‹‹…‹‹lriŒ”•|‚z‹„‹tt{{||SKJekdƒ„„{{t„Š„œ¤¦|„…{{ƒlri|„…Œ‹“œ››ƒƒ|‹„‹{{t“““‹‹‹uzt”š””››‹’Šœ¤¦”››œ››Œ‹“¦§¨”“›‹‹‹£œ¥””‹“Œ”“Œ”{u{ƒ}ƒŒ—£mttfkkult‚|uuztuzt”››lks¨©´ult“Œ”ttsb[U|‚zult””‹lekƒ||ƒƒ|srerg]ƒ||d\\ddc„Š„ztllldFD;f]clkskk]|‚z|‚z””‹””‹››”llk3+*ttsUMRf]cr]g{u{‹„‹Œ”•tsl‹„„lek{zmsletzl…‹‹š””„Š„lek’…‹””‹£œ¥Šƒ}Šƒ}ttsldd|‚zztl{{t{u{{||Š}ƒƒ||Š}|Š}|‹„„kd\ult{{ƒ‹’Š›¢›Œ”•…‹‹tslƒƒ|ƒ}Š‹„‹{u{[[TddclldŒ‹“„Š„ƒ„„{||VTLJHFVZTtsllks‹„„{u{„„Š“““{||{{t{{ƒ„„Š\[[\[[„Š}f]c{ttlldš””tts‹‹„f]c‚|uttskk]aWMVTLedklksmttƒ||f]clddtt{\[bult{||Œ‹“ŒŒš„„Š™š¤ŒŒšŒŒš{{ƒ‹„‹{u{|„…{{t™š¤ƒ}ЄЄ{{ƒttstts…‹’mtt™š¤\[bedk\[bŒŒš™š¤™š¤™š¤…‹šmttª³·Œ”•{{ƒmttnv‚Œ”•œ§²µ¶·£œ¥£²Š~‹{{t’ŒŒ‹‹‹”››¦§¨¦§¨…‹‹ttssreƒƒ|tts{||‹…’œ¤¦|„…‹’Š›¢›¦§¨|„…‹’Štts…‹‹|‚z„Š}œ¤¦‹’Š|‚z„Š}”››„Š„¦§¨“““¦§¨{{t|‚z‚wlƒ‚u£››’ŒŒ’ŒŒ²««{u{ultŒŒš›”›tt{œ››lek””‹“““‹’Š™š¤\[[ƒ||{||llk{{ƒ\[blks}‡’}‡’VZ[UMRedk…‹’uzt™š¤ƒ}ƒ{{t™š¤¨©´ª³·œ¤¦œ¤¦™š¤›¢›”𔋒Д››œ¤¦œ¤¦fkk{{ƒ{{ƒ{{ƒ‘…„f]cŠ}ƒ“““‹„‹ultult[[Tmttfkk„„Šƒ„„…‹‹‹„‹lek{tt„Š„{tt¨©´ƒƒ|‹„„ddckk]yfdtts£œ¥ƒ||kk]|„…ttsSKJtt{tzl[[T]cdlek‘ˆ}²««UTS*)(“Œ”ultbVZlek{{t{u{ƒ||{{ƒ‚wluztlri””‹u{{{||f]cu{{|‚zƒ||‹„„£››Š}|šŒultrg]››”‚wl””‹£››Œ”•‹‹„sle‚utƒ||{ttƒƒ|tt{…‹’œ››{{t|‚z’ŒŒƒƒ|‹’ŠŒ‹“uztf]c[TTddctlld\\tllkd\ldd\[[ultttsekdlks‹„‹lksƒ||UTSd\\llk…‹‹VTLtt{ttsƒƒ|{||{||[[Tg\rLKR‹„„lksf]cek]dc\‹„„VTLkd\]cd]cdek]ƒ||ƒ„„‹…’™š¤”“›…„’ƒ}Š…‹‹…„’“““ultŒ”•|„…llk¦§¨”“›œ¤¦™š¤lks“Œ”mtt{{ƒ{{ƒ|„…{{ƒedk|„…\[[edk{{ƒ{{ƒ„vŒŒ”•uzt{{ƒ™š¤{{ƒtt{™š¤Œ”•œ¤¦™š¤¦§¨ƒ„„Š}ƒ{u{‹„„|‚z››”‹’Š“Œ”™š¤tsllksultultƒ||œ¤¦„„Štllƒƒ|Œ”•¨©´|„…{||„„Šœ››…‹‹Œ”•]bZtts”“›tt{…‹‹…‹‹\[[lri””‹|‚z¦§¨tzl]bZttsu{{tll‚wlƒ}Šƒ„„ƒ‚uƒ„„|‚zedkuztu{{Œ”•{{ƒ™š¤ƒ„„…‹’mttult{{t{{ƒlri\[b]cdmtt|‚zz}lri|„…lksœ¤¦„„Ѝ©´Œ”•œ¤¦…‹’Œ”•œ¤¦ª³·”››f]c|„…‹’Šš””u{{œ››Œ‹““Œ”\UZŠ}|ultƒ}ƒtll{tt‚|uUMRllk“Œ”{{t£œ¥™š¤lksultlks‹…’{u{mttttsŠƒ}ƒ}ƒ[[TSKJbVZŠƒ}tt{‹„„„Š}[TTllktslkd\ƒ||sle|‚ztll{{t¦§¨llk74,SKJtll’…‹ddcmttldd{{tsle‘Œ…“Œ”f]cslesle|„…lri|‚z‚|u{tt‹‹„£››¦§¨‚|u…‹‹ƒ„„‹’Šsreƒƒ|Œ‹“™š¤’ŒŒlld‹‹‹mtt‹„„ƒƒ|ddctt{”𔋒ЄЄ{u{tslr]Zu{{‹‹„‚|uultllkfkkSKJ]bZ]bZF=CF=Cmttlriœ¤¦ƒ„„|„…{{t‹…’Œ”•tsllkstlltts]bZlekuzt|„…ddc„Š„lkslrid\\sleu{{slesred\\cbVtllƒ}ƒuztlritll{tt„„Š…‹‹Œ‹“ŒŒš£œ¥œ§²{{ƒ‹„‹œ¤¦™š¤ŒŒšllk™š¤‹„‹Œ‹“‹„‹{u{ƒ}ƒlks|„…{{ƒŒ”•|„…tt{|„…|„…›²›”›nv‚|„…{{ƒlks“Œ”{||…„’ƒ}Š£²“Œ”£œ¥™š¤{{ƒ™š¤tll‹„„tts[TT{ttŒŒš”“›¦§¨¦§¨ƒ}ƒ’…‹‚v{š””‹‹‹ztlƒ||mtt{u{…„’{||Œ”•œ¤¦ƒ„„™š¤SKJŒ‹“‚|u{{tŠ~‹…‹’Œ‹“{{ƒ|„…”š”edk|„…tsltzl{{t‹’Š‹‹‹›¢››¢›’ŒŒ{{ƒƒ„„lekŒ”•Œ‹“tt{Œ”•…‹’{{ƒmttldd]cd‚v‚lksu{{\[bUUYŒ—£mttŒ—£|„…{{ƒ{{ƒVZ[„„Š…‹‹Œ”•«²«™š¤¦§¨|„…mtt”“›™š¤™š¤tt{„„Šlks™š¤lks…„’Œ‹“ult\[[dc\ƒ||UMRyflreddc\j]\„„Šj]\{ttllkedkb[Uultult]cddc\[TTVTLtll[[Ttllr]gƒ}ƒ{{t››”‹‹„ekdultbVZj]\UTSC8.JHFldd²««›¢›JHF!ekd{{ƒ{{tultllksle|‚zb[Uš””‹„‹{{ƒ“Œ”£››ƒ||œ››…‹‹ƒƒ|’ŒŒŠŠ}{ttŠŠ}‹„„œ››‚v{‹„„‘Œ…ƒƒ|ttssle’ŒŒƒ‚uƒ„„„Š„‹„‹œ¤¦”››f]cŠƒ}’ŒŒmtt{{t…‹‹lri|„…‹’Š{||‹„‹tt{™š¤dc\tllekdlld‚v‚mk…mttŒ”•œ››Œ”•„„Š{|||„…„Š„rfkekdƒ„„[TTekdlld‹‹„mttek]…‹‹ƒ}ƒ‹„„lek\UZVTLlksŠ}ƒred’ŒŒult„„Š‹‹„d\\“““››”…„’”“›…‹’‹…’{{ƒŒŒš{||¦§¨}‡’˜Ž£\[[ddcult{||ƒ}Šƒ„„¦§¨lks|„…ttsŒ”•„Š„ŒŒš‹‹‹|„…”››„vŒ‹…’…‹‹„„Š|„…”››|„…”››™š¤Œ‹“Š~‹™š¤‹…’Œ”•|„…Œ”•œ¤¦™š¤”››Œ”•›”›‹‹„£œ¥”“›lks{u{£œ¥›”›…‹‹“““…‹‹…‹‹ldd{{ƒ‹‹‹mttœ¤¦Œ”•œ¤¦MSSUTSttsŒ”•“~ˆztl‹„‹‰v|]bZ””‹cbV¦§¨””‹|‚z””‹Œ‹“Œ‹“„„Š„„Š„„Š\UZddc\[[[TT{||™š¤Œ”•|„…™š¤mtt\UZlksultJHF\[bŒŒšUMRƒ}Š|„…Œ”•ƒ||œ››“““ult{{tultœ¤¦œ¤¦…„’Œ‹“™š¤µ¶·|„…|‚z‹’ŠŒ”•…‹’“Œ”Š~‹‹„‹{{ƒœ¤¦£œ¥ƒ}Šf]c[TTleksleztl{u{red“Œ”{tt‹„„‘…„™š¤rfkultƒƒ|ddc‹‹‹”“›ztlƒƒ|œ››ƒ||j]\„„Šƒ‚uƒƒ|cbVddcztlllkƒ}ƒkd\ƒ‚u{{tƒ||{zmµ¶·MRK*)(|‚ztlltts[TTlriredtslƒƒ|””‹ƒ}ƒ’ŒŒlldƒ||„„Š‹‹‹ƒ‚n‹„„²¬µƒƒ|‚|uŠƒ}œ››«²«‹„‹“““{zmlri™š¤’ŒŒztlbVUŒ‹“{tt|‚ztt{””‹uzttts””‹‹’Š‹„„|‚z”››ƒ||“Œ”tts‹‹‹…‹‹“Œ”š””“““mttUTS^^qlks{u{…‹‹™š¤…‹‹Œ”•{{ƒŒ”•{||‹’Šlddztldc\œ››ult„Š„…‹‹ŠŠ}‹„„‹…’ƒ||ƒ}ƒ{{ƒ”“›…‹‹“““£››Š}ƒ\UZ{{ƒƒ||ƒ}ƒµ¶·¦§¨Œ‹“™š¤‹‹‹†~‘|„…Œ‹“{u{uzt…‹‹{{ƒ|„…‹‹‹ult‹‹‹„„Š„„Šœ¤¦mtt™š¤…‹‹œ¤¦…‹’…‹’Œ”•ƒ„„¦§¨„„Й𤔔‹“““edk‹‹‹“““Œ”•{tt…‹‹¦§¨™š¤llkŒ‹“‹’Šult|„…ult“““Œ”•“““‹‹‹›¢›œ››¨©´|‚zƒƒ|{||£››‹‹„tzl‹’Šsle{||„„Š|„……‹‹”𔋋„]bZŒ”•ult{||{zmƒ||{{ƒ|‚zŒ”•›¢›{{t””‹„Š}{{t{{tƒƒ|£›››¢›ƒ„„{{tdc\tsl[TT‹‹„kk]f]cf]c{{ƒtt{„„Štt{lek|„…tt{fkkmtt]cdŒ”•}‡’…„’™š¤”š”’ŒŒ£œ¥‹…’|„…£²¬¶Ã™š¤™š¤‰Š¡{{ƒ”“›£œ¥™š¤™š¤””‹š””ultƒƒ|”“›ƒ}ƒ{||tsl{||llkedkŒ”•„„Š‹„‹¨©´ƒ}ƒƒ||“Œ”Œ‹“{u{“Œ”ldd“Œ”{tt“Œ”ƒ||slesleŒ‹“‹„„{{tj]\„Š}kd\ek]dc\ekdredVTLb[UVTL]bZSKJlksµ¶·VTL*)(ƒƒ|{u{{u{ztltts‚utsre‚|u””‹{{ƒ‹’Š™š¤b[U|‚zult‚ut”››|„…iq]{{t””‹‹‹„œ››{||™‹†b[U{zmŒ”•Œ”•{{t‹‹‹‹„‹|‚z{||{u{tt{tt{”››«²«”š”tslmttuzt|‚z…‹‹ƒ}ƒŒ‹“„„Štts¤¤uztlritsl]cdMRKllkmtttll‹’Š\[[Œ‹“|„…ztl{{ƒ{{t{tt‚|utsl{tt|‚zbVZ‹‹‹Š}ƒŠ}ƒ“““‹„‹›”›{ttmtt‹‹„‘Œ…lldSKJlddJHF’ŒŒ|‚zƒ}ƒ|„…ƒ}Šlri’…‹œ››mtt£œ¥‹„„mtt{{ƒ|„…ƒ}ƒ›”›‚wl†~‘¨©´¦§¨™š¤Œ”•œ››œ¤¦mtt|‚z”››œ¤¦…‹’tt{|„……‹’‹…’{||…‹‹ultu{{mttmttŒ—£…„’lks””‹¦§¨«²«¦§¨¦§¨œ››œ¤¦{||Œ”•”››…„’œ¤¦„„Š”“›lks…‹‹|„……‹’ddcf]c”“›µ¶·{{ƒ{u{¦§¨…‹‹ƒ„„Œ‹“lks””‹[TT\[[dc\|‚ztsl“Œ””“›«²«„Š„››”œ››|‚z‹‹„Šƒ}ƒ}ƒ{{ƒd\\llk’ŒŒ‹‹„tsl™š¤{{tƒ}ƒttsdc\ult[[TUUYlriuztMRKtllllkyl„ddc{{ƒ“Œ”£²ŒŒš”“›ult””‹{||ƒ}ƒ‹…’™š¤tt{¨©´„„Šƒ„„ƒ„„Œ”•„„Šztl„Š„”š”{||tsltt{u{{ddc”“›™š¤œ¤¦”“›”››‹’ЄЄ‹‹‹„Š„Œ”•“Œ”\[blldlddedkdc\‹’Š{{t‹„„lldj]\{ttSKJSKJ]bZlridc\d\\j]\j]\lddekdttsƒ„„²««UTS*)({tti\Vldd{ttŒ‹“‹„‹Šƒ}£››zllsre‹„„{{t{{tllkš””’ŒŒtsl›”›lrid\\yle’ŒŒ‹’Ц§¨ƒ||“Œ”‹‹„{u{lldyle‹‹‹ttsŠ}|{||„„Šd\\…‹‹‚|u‹‹„ƒƒ|{|||„…lrikd\…‹‹kd\„Š„œ¤¦”››“Œ”uztu{{uzt]cdUMR]cdddcd\\Œ‹“]bZult\UZd\\ƒ‚nsleu{{ƒ||{ttf]c{{tdc\ƒƒ|ƒ„„Šƒ}JHF{tt[TT‚|utslƒƒ|mwUMRtts“Œ”‹„„lksultlkstts{u{‹’Й𤓓“{{ƒš””£œ¥|„…|„…{||œ››“Œ”””‹Œ—£„Š„‹…’ŒŒš…‹’ƒ„„…‹‹{{t¡¡“““|„…lks{{ƒ{{ƒ…‹’¨©´{{ƒ”“›‰Š¡{{ƒ{{ƒ…„’{{ƒnv‚lksŒ”•»ÂÇŒ‹“…‹š”“›…‹‹››””š”œ››‹’Š„„Ѝ©´œ¤¦”››ult‹’Šu{{‹„„›”›‹„‹“Œ”¦§¨‚ut„„Š”“›‹’Š£œ¥™š¤{{ƒ”“›tts{{ƒ{||‹„„”›››”›¦§¨ŒŒš…‹’¦§¨“Œ”\UZŒ‹“”“›ult‹…’]cdult„„Š{ttult™š¤“Œ”llkŒ‹“|„…ultedk“Œ”…„’Œ‹“tts\[bf]cult¨©´{u{ŒŒš{{ƒŒ”•ƒ„„„„Šttsmtt|„…tt{„„ŠmttŒ”•{{ƒ›¢›Œ‹“œ¤¦‹’ŠŠƒ}Œ”•lld|‚z‹…’œ››“““dc\‚v{tts”š”|‚z„Š„š””d\\lks…‹‹|„…d\\red{{ƒ“““ƒ}Š\[[tslSKJƒ||tsl{ttultdkVSKJVTLVZTmtt\UZredtllztl\[[SKJ{{t²««JHF*)(dc\ultd\\i\Vƒ„„{tt››”‘Œ…ƒƒ|~’“…„’sre‹„„d\\‚v{„„Š’ŒŒƒ„„lldek]f]c‹„„…‹‹|‚zƒ||£››‹„„’…‹””‹zll‹‹„ƒ„„‹‹„tll‹’Š‹„„„Š„{tt‹‹„””‹ƒ„„tt{|‚z‹‹„|„…llk››”™š¤|„…ƒ||„Š}ek]|„…cbV„„Šlldmttd\\lldllkedk{{ƒŒ‹“llkultttsŠ~‹’…‹bVU››”[[T‹„‹ƒƒ|sreddcttsf]c‰v|ƒ||ƒ„„sleb[U‚|u‹‹‹ƒ„„tt{d\\\[bLKR™š¤”“›™š¤“Œ”{{ƒƒ„„“Œ”llku{{”››”“›{||Š}ƒrfkŠ}ƒ™š¤{{ƒ{u{zllœ¤¦Œ”•¦§¨Œ‹“u{{…‹‹™š¤™š¤ult™š¤…„’ult…„’™š¤{{ƒ‹…’{{ƒ›²›²œ§²”“›{{ƒ‹‹‹™š¤””‹”“›œ››“““tsl…‹‹”“›ƒ}ƒŒ‹“Œ”•|„…{||lldmtt…‹‹›¢›Ž¡›œ¤¦¦§¨lri›¢›Œ”•tts…‹‹‹‹„slemtt\[bultƒ}ƒ|‚z“““uzt‹‹‹›¢›…‹‹lld„Š„‹‹‹…‹‹ttslri“““œ››ƒ‚uƒ„„rfkƒ}ƒ“Œ”‹„„dc\JHFf]cƒ„„ultlldult{u{f]cƒ}Š…‹‹{||mttlldŒ”•œ¤¦{{ƒ”“›‹„‹ƒ}ƒ„„Š…‹‹™š¤›”›{u{”››ztl|‚z¤¤‹‹‹{{ttslsleƒ‚udc\„Š„ztlƒƒ|tzl“““slelksekd{{t¦§¨{||ultleksleUTSŒ‹“{||d\\slett{‰ƒvldd{ttsle‹’Š{{tUUYztlult|„…ƒ„„”š”sremttSKJcbV””‹F=C*)(d\\tts[TT‚v{{tt”“›{{tƒ‚u{zmultred{{tŠƒ}ldd‘Œ…“Œ”llk|‚z\[blld{{ƒ‹‹‹Œ‹“ƒ„„‹‹„‚|uƒ‚u””‹£››|„…µ¶·”“›„„Šult„Š„‹„‹|‚z“““››”‹‹„”š”f]c”››|‚z‹’Š„Š„Šƒ}ttsu{{]cd”š”JHFƒ}Š[[Tf]c\[[tt{ulttlllriŒ”•{{ƒƒ}ƒlekedkllk|‚z„Š„‚|u‚|udc\llkb[Ui\VUTSlddUMRkd\VTLrg]f]cf]c“Œ”‹„‹¦§¨‹„‹‚|u|„……„’„„Š…‹‹‰ƒv…„’ŒŒšƒ„„œ¤¦Œ‹“™š¤{{ƒ{||tll¦§¨Šƒ}‹„‹™š¤”“›Œ”•“““Œ”•ª³·ƒ„„ƒƒ|‹’Šuztlks{{ƒ{{ƒ™š¤Œ‹“‹’Š…‹’|„…}‡’{{ƒ^fs}|’~’““Œ”œ¤¦œ¤¦ƒ}Šƒ„„‹‹‹ƒ„„tllƒƒ|tt{‹‹„œ¤¦tsl››”lriƒ‚u‹„‹llkƒ}ƒlektt{¦§¨¨©´ƒ}ƒŒ‹““Œ”‹’Šlld“Œ”f]ctts{tt|„…uztj]\™š¤’ŒŒœ››‹‹„ƒƒ|„Š}tzl””‹ŠŠ}”››µ¶·ƒ‚ukjVš””ƒ||ztlšŒtll\[[„„Šddcult‹…’„„Šult‹„‹›”›{u{{{ƒtll‹’Šuzt‚|uœ››tll{{ƒ˜Ž£„„Š|„……‹’”››…‹‹{{ƒ“Œ”{u{Œ‹“u{{ƒ„„œ¤¦œ››{||]bZlriUTSd\\u{{‹„‹f]cŠ}ƒult{||™š¤d\\{ttsle‚|uztlƒ}ƒ‹„‹u{{Œ”•ƒƒ|’ŒŒ{||{u{ƒ||’…‹¦§¨„Š„¦§¨‹’Š{||ƒƒ|ƒƒ|Œ”•Œ”•‚|uƒ}ƒJHF[TTkd\¤¤VTL74,ulttsltts“Œ””š”“Œ”bVUƒƒ|‚wl[TTsle{tt{ttult‰ƒvlek‹„‹lldlriekdƒ||tllŒ”•|„…‚ut‚|uŠŠ}ƒƒ|’ŒŒ{||‹‹„|‚z‹„„„„Š””‹{tt{{t›”›¤¤‹‹„|‚zult…‹’„Š„‹’Štslultƒ}ƒ”“›{||”››ekdf]cUMRVZ[\[bƒ}ƒƒ||‹‹‹u{{Œ”•ek]”››”“›™š¤‹„„[TTlri{{ƒƒƒ|ddclridc\j]\Œ”•lriultlekŠ}ƒ””‹[TTƒ}ƒ„„Š…‹‹¨©´Šƒ}Œ”•”››™š¤£²…‹‹…‹‹¦§¨{{ƒŠ~‹|„…„Š„ŒŒštt{ƒ}ƒuzt“Œ”lriƒ}ƒ„„Š™š¤Œ”•”“›‹’Š|‚zu{{Œ‹“lriuzt{||“Œ”“““Œ”•lkstt{‹…’›”›™š¤¨©´™š¤¨©´¨©´{{ƒ™š¤Œ”•¨©´™š¤“““ƒ||lld|„…”››|‚zƒ|||‚z”››œ››¦§¨¦§¨››”¦§¨‘…„tts{tt“Œ”Œ‹“¨©´“““£œ¥…‹‹‹‹„lekŒ”•UTSttsŒ‹“‹…’„„Š‹‹‹ƒ„„“Œ”ƒ}ƒš””Š}|£››{zm¤¤¤¤››”œ››¦§¨‹‹„{{t‚v{tts„Š„““““““VTLlldlldSKJ‹„‹™š¤lekedk›¢›«²«œ§²uztttsƒ}ƒƒ}ƒƒ„„…„’™š¤£œ¥“Œ”™š¤‹„‹{u{”“›{ttult¨©´µ¶·Š~‹ttsƒ||mttf]cŒŒšƒ}Šƒ„„lld‹‹„‚v{”››‹…’ƒ}ƒtt{ztlrfkult›”›bVU™š¤u{{ƒƒ|ult…‹‹sle”“›‰ƒv‹„„{{ƒƒ„„‹‹„ƒ}ƒ{||„Š„‹‹‹’ŒŒcbV{{tedk{||„Š„¤¤JHF*)({{ƒlddttsztl“““ultcbVƒ||””‹rfk{zm’ŒŒ„Š}tll‹‹„j]\‘Œ…uztuztztflddd\\ƒƒ|tt{¦§¨™š¤ƒ‚uƒƒ|’ŒŒ{||„„Šlri{{t”“›œ››››”™š¤‹„„”“›ƒƒ|llklek…‹‹«²«£››{||ƒ||‹’Štts…‹‹|„…‘Œ…‹„‹|„…}‡’mttƒ}ƒd\\š””{||srett{Œ”•›¢››”›™š¤lekztltzlkd\“Œ”ƒƒ|kk]kd\{zmƒ}Š{ttu{{lrilld‹„„f]cztlŠ~‹{{tddc‹„„Œ”•„vŒŒ”•„Š„…‹‹mtt›”›rfkUTStsl{{ƒ|„…lld’ŒŒ‹…’…‹‹tslyl„ult™š¤{||…‹’mtt{||{{tleku{{›”›ƒ}ƒ‹„‹|„…Œ‹“‹’Š“Œ”œ¤¦œ››¨©´”“›„„Š{u{„Š„”“›Œ”•ƒ„„Œ”•lri‹’Šƒ„„œ¤¦‹’Š…‹‹uzt{u{··Ä“““¨©´„„Š’ŒŒŠ}ƒ’ŒŒ’ŒŒbVZ„„Šsle£››“Œ”‹’Šult””‹¦§¨›”›‘Œ…Š}ƒ¦§¨²¬µ›”›”“›¨©´¦§¨lek¢—‹’Š›¢›œ››››”›¢›“““rg]sleŠŠ}lri{zm“““tzl{{t””‹[[Tllduztƒ‚u™š¤Œ”•{{ƒmtt„„Š™š¤ƒ}Š]bZ…„’ult‹uŠ{u{‹„‹“Œ”£œ¥“Œ”ult‹…’tsl“Œ”lksVZT{{ƒŒ”•u{{‹„‹™š¤ƒ}ƒ{u{ƒ}ƒ„„Š‹…’‹…’{{ƒƒ}Šlldsle|‚z{{ttslkd\ultlksultƒ}ƒddcu{{bVZ…‹‹„Š„’ŒŒ[TTd\\{tt{tttygtts{{t‹‹„lektllkd\‚|ulkslldtsl£œ¥FD;*)(Œ”•‰|vtt{rg]ƒƒ|ƒ„„‚|u‹‹„tsltsltll{u{kd\|„…‰ƒvztl›”›lri‹’Š’ŒŒedk{{ƒ£››Œ‹“‚|uultz‚llld{{ƒŠ}ƒ›”›”››lldf]cƒ}Š{{tŒ”•tll“““›¢›Œ”•ttsœ¤¦”››¦§¨|„…\[[rfkƒ||uzt|‚z”“›Œ”•u{{‹„‹ŒŒšlri{{ƒ””‹‹’Š…‹‹{{ƒ‹„„|‚zœ››ƒ||ƒ}Š‹’ŠŒ”•{ttƒ}ƒrg]‹‹‹{{t|‚z„Š}ƒ}ƒ“““|‚zlriuztƒ}ƒlek‹…’‹„„lldllk”š”†~‘u{{…‹‹llkŒ‹“{u{Œ‹“ƒ||{||ttsœ››™š¤{||‚v‚tts‹„„{ttf]ctt{£››|„…‹„„”“›{{t”š”{{t›¢›ddcƒ}ƒu{{¸Á¹œ§²™š¤¦§¨¦§¨‹’Štts{{ƒ|„…mtt™š¤œ¤¦tt{Œ‹“u{{{{ƒ|„…”“›”››“Œ”ƒ||‹‹‹²¬µœ¤¦””‹{u{edk‹„„{{ƒ…„’”››“““u{{¦§¨”“›‹…’’ŒŒ£››¤¤£››¦§¨¨©´Œ‹““Œ”¨©´¦§¨”“›‹‹„redtllš””›¢›¦§¨Šƒ}£œ¥VTLztl„Š}¤¤ƒ‚u‹„„sleztlVTL{u{Œ‹“Š}ƒ“Œ”“Œ”‹„‹f]c™š¤£²£œ¥…„’|„…u{{mtttt{lksŒ”•“““œ¤¦™š¤™š¤œ¤¦››”ƒƒ||‚z„Š„|„…‹’Š‹‹„|„…u{{¨©´Œ‹““Œ”“~ˆbVUtslŠ~‹”››„„ŠJHFek]lks\[[¦§¨lrilri\UZbVUŒŒšƒ„„’…‹ult“““kd\zll[TTd\\uzt‚|usre’ŒŒd\\uztmw[[TSKJƒƒ|JHFd\\ult”“›JHF*)(‚|uztl”š”redƒ‚ulekrg]ztl¦§¨’…‹”𔋋„ult‹’ŠŠƒ}sre£››ult|‚z‘Œ…tts‹„‹fkk|‚zŠ}ƒ‹„„””‹£››’ŒŒ“Œ”sre…‹‹œ¤¦llk{u{›¢›“Œ”¤¤ƒ„„›¢›{||„Š„¨©´¦§¨¦§¨”››{u{lldu{{…‹š|„…uztultLKRVTL\UZlek“Œ””››”››uzt‹„„‹‹‹tts{u{…‹’™š¤œ¤¦[[T{{ƒlldultllkƒƒ|‚|u‹’Šztlƒ}ƒred„Š„ƒ„„‚v‚lddš””tsl{ttœ››¨©´uzt…‹‹lldlksƒ||Š~‹›”›‹„„lri[TTtslf]c„„Š‚uttsltll‚v{Š}ƒ”“›ƒ||ƒ||‹„‹lksƒ||‹‹‹|‚zult{{ƒ¦§¨Œ”•œ¤¦™š¤Œ”•¡¡œ¤¦œ¤¦|„…|„…Œ”•„„Ц§¨{{ƒ”“›„„Š“Œ”£œ¥™š¤™š¤‹„‹¨©´¦§¨{{ƒ¨©´›”›™š¤™š¤““““Œ”Š}ƒ²««{u{llk…‹‹’…‹··Ä‚v‚yfdƒ||‹‹‹‹„‹™š¤™š¤rfk“Œ”‹…’ƒ}ƒ‹’Š›”›™š¤ƒ„„‹‹‹Œ‹“{||ƒ„„ztluztlri‹’Š|„…lrillktt{|„…‹’Š{{ƒ]cd]cdœ¤¦mttfkkfkk{{ƒŒ—£¬¶Ã™š¤|„…}‡’™š¤…‹’…„’”“›|„…Œ”•{{ƒ‹…’mtt{||„„Š‹‹‹¸Á¹lld””‹Œ”•lri‹‹„kk]ƒ„„ƒ„„lldŒ‹“…‹‹‹„‹…‹’ddc|‚zlld‹„‹ƒ||„„Šddcldd{{ƒ{{ƒJHFUUYu{{lddJHFf]clddƒ||ttsllkŒ‹“lri‚v{ddclldj]\dc\Š}ƒ„„Šƒ}ƒlriƒƒ|¦§¨JHFJHFuztlld{ttztlšŒllkjV[|‚z|‚zkd\“Œ””š”Œ”•uzttsl””‹‘…„„„Š„Š}|‚z“““ztlŠƒ}tsltts{tt„Š„¦§¨‹„„œ¤¦”››{||“Œ”Œ‹“ult|‚zlek£››µ¶·ª³·›¢›…‹’¦§¨Œ”•‹‹‹£œ¥œ¤¦‹‹‹”››uzt]bZMRKlld]bZ|„…tt{‹„‹…‹‹‹‹„™š¤{{tllk…‹‹‹’Šƒ||œ››u{{…‹‹„Š„ƒƒ|Œ‹“|‚zbVUtsl‹’Šlldfkk|„…‹„„tslsred\\fkklddŠ}|{{tƒ}Ц§¨{||…„’‹’Štts]bZ{u{¦§¨†~‘¤¤ƒƒ|ƒ||{u{tts{||f]c‚|u“Œ”|„…ttsœ¤¦””‹ŒŒšŠ~‹ldduztu{{…‹‹…‹’ƒ„„|„……‹‹Œ—£Œ”•}‡’|„…|„…mtt|„…ƒ„„‰Š¡Œ”•‹…’œ››™š¤{{ƒ|„…Œ”•™š¤|„…£œ¥‹…’“Œ”ttstt{²¬µ””‹¨©´“Œ”…‹‹™š¤uzt{ttƒ„„‚ut¦§¨Š~‹“Œ”ƒ}ƒ‘Œ…Š~‹f]cmw’…‹ƒ}ƒš”””“›‹„‹ª³·‹„‹llklek“““œ››tts{{ƒlrilri’ŒŒŒ‹“…‹‹…‹’™š¤edkultJHFlks{{ƒ…‹š{{ƒlksedk|‚z’ˆ|‚zŒ—£Œ”•lks””‹|‚zuzt‹‹‹„Š„¦§¨¦§¨‹„‹Œ‹“›¢›Š}|””‹Šƒ}ƒƒ|ƒ‚u””‹VTL””‹‰|vŠŠ}slerr]tzl|‚zƒƒ|[TTƒƒ|lriŠŠ}‹’Šƒƒ|tslUTS”“›d\\|„…ekd‹…’uztyl„[[TŠƒ}“““‹„‹Š~‹””‹VZT””‹lek‚v‚lldultztlf]c{ttF=Ckk]rg]²««UTS*)(slej]\…‹‹Š}|‚|ulddŠŠ}ŠŠ}‹’Š›”›”“›””‹“““ttsrg]sle‚|utt{VTLsleztlŠ}ƒ„„Š‹„„zll›”›”š”””‹¤¤ƒƒ|œ¤¦“Œ”¦§¨Š}ƒ‹„‹u{{{{ƒ“Œ”¤¤’…‹Œ”•ttsŒ‹“‹’Ц§¨“Œ”¦§¨£œ¥™š¤|‚z‹‹‹lriUTSJHF[TT{{ƒ{{ƒƒ„„œ››ŠŠ}œ¤¦ƒƒ|uzt{{t{||fkkŒ”•œ¤¦tslmttsre{ttu{{Šƒ}b[Uƒ„„…‹‹ƒ}ƒ{||””‹tzlkd\74,{u{ztlŠƒ}ztl™š¤ƒƒ|ƒƒ|uztmtt{u{™š¤‹…’f]clriŒ”•‹„„d\\„„ŠŒ‹“ƒ„„lddttsultult›²Œ‹“ƒ}Š“““ƒ„„[TTlks{{ƒŒ”•‹‹‹…„’|‚z|„…fkk‹’Š|„…‹’Š|„…¦§¨““““Œ”{{ƒ“Œ”‹‹‹‹…’”“›ttsu{{›¢›””‹]cdtts{u{ƒ||\[[ƒ}ƒ”“›“Œ”ƒƒ|kd\{zm‹‹‹Œ‹“ttsšŒŒ”•ekdttsf]ctlldc\tzlJHF{||lkstll’…‹¦§¨’…‹£œ¥‹…’”“›{{ƒ”“›¦§¨lkszlld\\dc\‚v{red‰v|{u{f]cedku{{ª³·””‹ƒ„„“~ˆllkekduzt›¢›|‚z‹’Š›¢›‹’ŠŒ”•ttsmtt‹’Š‹‹‹ƒ}Š£››“““›¢›{||tll„Š„kk]{||tll›¢›‹‹„llklri|‚zVTLek]„Š„””‹dc\‹’Š|‚z””‹ƒƒ|dc\{{t{||lksmttultœ¤¦mtt{{ƒƒ}ƒ{{ƒ…„’Œ”•‹‹„””‹™š¤ƒƒ|[TTsresle{||lld]bZrr]JHFttsJHF{zm‚|u””‹JHF:97tsllrilldƒƒ|Šƒ}‹„„ƒƒ|‘Œ…‹’Š””‹Œ‹“‹’Šƒ„„‹’ŠŠƒ}Šƒ}‘Œ…’ŒŒƒ‚uƒ‚ukd\Œ”•‚v{™š¤œ¤¦Œ‹“””‹››”ƒƒ|”“›¦§¨“Œ”Œ”•tt{ƒ}ƒ{u{”“›Œ‹“›”›u{{“Œ”lksƒ||lriš””œ¤¦’ŒŒƒ„„|„…|„…{||llkmttf]c{{ƒ{||“Œ”‹‹„{{t|‚zœ››ƒ„„Œ”•”š”uzt„Š„lek„„Šdc\tt{Œ‹“kk]lekƒ||d\\|‚z|‚z{||ƒ||ƒ||‹‹„kd\VTL{||tll£œ¥sre¨©´¦§¨|„…„Š„ƒ||”š”’…‹UMR†~‘’ŒŒœ››ƒ}ƒ‹„„{ttš””œ››‹’Šƒ||kk]ƒ}ƒ{{ƒ›”›¦§¨‹„‹‹’Š{u{Œ”•{{ƒ|„…{tt‹’Š|‚zƒƒ|„„Š“““Œ‹“„Š„{||{||{{ƒ…‹‹™š¤ƒ„„{||„Š„…‹‹„„Šœ¤¦„Š}ttsuztUTSUTSSKJSKJƒƒ|‹„‹“Œ”…‹’Œ‹“Š}ƒ‚ut£œ¥ultš””sle„Š„lksddcd\\lekƒ||uztddctslƒ}ƒ¦§¨{u{…‹‹\[bƒ}ƒ””‹„„Š„„Š{{ƒf]c]cdJHFultllkŒ”•‹‹‹tslƒ||””‹lddD;9lldbVUuztekd|‚z{ttek]|‚z›¢›Œ”•‹’Š‹‹„|‚z|‚z””‹‹’Š›¢›‹’Š“““‹’Šœ¤¦Œ”•|‚z|‚z‹‹„ƒ„„ƒƒ|‘Œ…ƒƒ|yle‘…„ekd’ŒŒ‘ˆ}ƒ||ƒ||[[TbVU‹’Š‹„„ƒ„„‹‹‹”“›{||‹’Šœ››Œ‹“ƒ||{{t‹…’|„…™š¤dc\…‹‹\[[mtt›”›lld[[TSKJVTLƒ„„„Š}tts‹„„|„…\[b{{tj]\””‹JHF*)({tt|‚z‹‹„‚|uŠŠ}Šƒ}‚|u{zmdc\‹‹„leklld|„…‘…„{{t››”slellk””‹””‹ƒ||‹‹„’ŒŒuzt{||Š}ƒz‚lƒ||ƒ||llkš””{u{|‚z†~‘“Œ””š”{{ƒ‚v{¦§¨Œ‹“mttlekŒ”•ƒ‚u™š¤Œ”•¦§¨œ››‹‹„llk{{ƒldd|„…{{ƒekdœ§²{ttƒ„„”“›|‚z…‹‹ƒ„„‹’Šƒƒ|tts“Œ”ldd{u{|‚z‹…’‚|u|‚z›”›tllztldc\‹’Šœ¤¦‹„„””‹››”b[U[[TddcVZTtlldc\ekdldduztlriƒ||{ttlek‹„„ƒ}ƒ„Š„u{{ekd’ŒŒ{||™š¤¤¤ƒ}ƒzll{{ƒ‹„‹ult¦§¨¦§¨£œ¥’ŒŒ‹‹„›”›mtt{{ƒ¦§¨{{ƒƒ„„{{ƒŒ‹“‹‹‹”››™š¤mttek]lriƒƒ|ƒ„„|‚zœ¤¦…„’|‚z‹‹‹”š”{{t„Š„‹‹„lldultttsUUYŒ‹“dc\“““›”›„„Š‹„„£››‰v|£››··Ä’ŒŒŠ}|‚v{s_qred”“›ƒ}ƒVTL‹„„]cd’ŒŒ¦§¨›¢›tzl‹‹„tzlmtt‹’Š{||‹‹‹f]c[[T|„…lksedk‹„‹\[[ƒ}ƒ‹„‹tt{‚|u{{ƒƒ}ƒb[U{{ƒd\\tt{|„…™š¤mtt{{ƒ”››{{ƒ…‹’™š¤¦§¨£²‹‹‹ŒŒš‹’Š“““Š}ƒšŒ‹„„ƒƒ|œ¤¦”››ƒ||‹‹‹redslej]\ultbVU£œ¥r]Z‹„„cbVkd\sle‹„„lddkd\{tt“Œ”tll‹…’\UZ„Š„VZ[dc\edkŒ”•uzt[[TŒ‹“[TT\UZƒ„„lld[[Tzll‹…’””‹kd\š””‹„„›”›ŒŒšVTLj]\œ¤¦>EC:97ultŒ”•|‚z{{t“““zll ztl”š”‘Œ…VTLƒƒ|„Š}Š}|šŒ£››‹‹„„Š„š””Š}|red”“›{tt”“›{tttll”𔓓“tts‹uŠult™š¤‹…’…„’“Œ”ƒƒ|™š¤¦§¨ƒƒ|ultdc\{u{“““¦§¨’ŒŒŠ}ƒ„Š„‚v‚…‹’edk„„Š{{ƒ{|||„…LKRtslmtt‹‹‹u{{‹‹„ttsd\\ttsuztldduztj]\ƒƒ|tt{llklddkk]tt{‚|uldd|„…›¢›™š¤{zm„Š„™š¤„Š„„„Š|‚zlrid\\‹„„ƒ||ekdlekœ¤¦|‚z|‚z{u{{zm[TT|‚zttsUTS‚|u{{t‹’Š’ŒŒ›”›ƒ||Œ”•œ¤¦™š¤˜Ž£{{ƒ“““{tt“Œ”fkklks{{ƒŒ”•‹…’ŒŒšª³·‹‹‹…‹‹Œ”•Œ‹“|„…”››]cd…‹’tt{fkktt{|„…|„…”››mttulttts”“›™š¤…‹’‹„‹“Œ”“Œ”£œ¥f]c|‚z¦§¨|‚z”››{u{“Œ”‹…’{u{‹’Šult’ŒŒ’…‹“Œ”kd\SKJkd\tllŒ‹“Œ”•’ŒŒ…‹’ƒ}Š{{t{{t„Š}‚uttslSKJJHFb[Uƒƒ|tsl‰ƒvlddƒƒ|]bZ”“›dc\mtt|„…ttsVZTult…‹’|„…{{ƒ‹…’ŒŒšƒ}ƒ{u{‹„‹ƒ}ƒ’ŒŒ··Ä‹…’£œ¥ƒ||bVU“““››”Š~‹ult|‚zŠŠ}dc\ldd|‚ztslUTSSKJ””‹‹‹„lld[TTslej]\\[[MRKŒ”•[[T{{tƒ„„„Š„lksllk{||œ››{||Œ”•mttlrimttddc[TTj]\„Š„Šƒ}kk]lddtsl‹‹„‹‹„£››u{{{u{\[bVZ[ƒ}ƒƒƒ|JHF*)(tll|‚z‚|u””‹‹’Šyle‚utkd\sleƒ||j]\{{t“““‰ƒv¤¤›¢›””‹ddcŠƒ}kk]ztl’…‹’ŒŒ‹„‹ƒ||ƒ}ƒtts‹’ŠŠ}|ƒ„„{tt…‹‹„„Štt{Œ‹“£œ¥™š¤”“›|‚z”š”””‹„„Štts{tttslƒ„„{{t{u{tsllriŒŒš‹uŠVTL\[b[[Tedk‚|u¦§¨ƒ„„|‚zlektt{{{ƒlddttsƒ||leklddlldtllŠƒ}‘Œ……‹‹››”tllƒ||„Š„tsl\[[{||ult{{tMSS|‚z|‚zu{{ƒƒ|„„ЄЄlddu{{|„…”“›{ttƒƒ|sleSKJfkkVTL{ttztltzl‚|uŠƒ}“Œ”{{t„„Š{{ƒ‹‹‹{zmtll‚v{“Œ”ult›”›{{ƒƒ„„”“›ƒ„„¦§¨”››|‚znv‚ultmtt„Š„…‹’£œ¥œ››“““œ¤¦“““”“›ult‹‹‹|‚z…‹‹ª³·²¬µ£œ¥”“›œ››™š¤œ››¦§¨¦§¨¦§¨‘Œ…ttstt{Œ”•ƒƒ|{{tkd\›”›„„Š”“›dc\”“›{{ƒ‹‹„kd\ultŠƒ}‹„„‹’Š{tt’ŒŒŠƒ}šŒ‘…„“Œ”‹‹„kd\iq]|‚zUTSƒƒ|””‹{tt‹’Šllk‹‹‹[TTedklksu{{„„Š]bZVZ[lri]cdlek‹„‹|„…lekllk„„Šllkkk]‹‹„‹‹‹{ttœ¤¦{{tllkƒ||ƒ‚u””‹››”‹‹„‚|ulksllkb[Udc\VTLjcVcbV]bZlddVTLƒ}ƒ”“›dc\\[[uzt{{tlksttslddmtt|‚z™š¤]cd“““‹„„‹‹„lld{u{‹’Š[[TVTL{{tlrillk{{tƒ‚uddc[[TedkmttUMR‹‹„>EC74,ƒ|||‚z„Š„‘Œ…tsl‚|utllkd\{zmldd|‚z]bZ‹‹„‚|uŠƒ}Šƒ}¤¤œ››tt{{zmœ¤¦ƒƒ|ztl{u{lks‹„„”››|‚zŠ}|“Œ”ƒ}ƒ£œ¥‹’Šu{{”“›’…‹ƒ||‹„‹œ››Œ”•Œ”•{ttf]c[[Tsre{|||‚ztsl‹‹„ldd„„Š“Œ”]cdtt{””‹{{ƒlks|„…™š¤œ››lksfkkƒ||ƒ„„tllSKJlddSKJ[[TlekŠƒ}‹‹„ƒ„„‹‹‹ult‹‹„ekdlld\[[ƒƒ|‹„„‚|uMSS\[b\[[lld„Š„Œ”•Œ”•d\\edk„Š„”š”š””f]cœ››kd\|‚z„Š„ultƒ|||‚z¤¤ult‹‹‹ƒ„„’ŒŒ“Œ”ultŠ}|ƒ„„edkf]c{{ƒœ¤¦…‹’›”›„„Šlksƒ„„|„…{{ƒmttmtt|„…{u{…‹‹›¢›œ¤¦Œ‹“|„…tsl{{ƒ{{ƒŒ‹“¨©´™š¤Œ‹“£œ¥¦§¨£œ¥¦§¨µ¶·»ÂǦ§¨Šƒ}sre‹’Š‚ut“Œ”sreŠŠ}”š”{{t{u{‹‹‹¦§¨Œ”•Œ‹“’ŒŒ‹„„{tt›”››”›¦§¨…‹‹|‚z¦§¨š””‰‰w‰ƒv{{tƒ‚ukd\‚|ulldtslŒ”•›¢›{{tœ¤¦…‹‹tt{lek…„’lks‹„‹“Œ”™š¤ultŒ‹“›¢›£œ¥‹…’ƒ}ƒu{{ulttts{ttŠ~‹ultllkƒ||ƒƒ|£œ¥llkœ¤¦Œ”•u{{™š¤ttsƒƒ|‹„„‘Œ…kd\‹„„ƒ||ult|‚zllk’…‹kd\ƒ‚usre„Š}VZTŒ”•ekd„Š„lksJHFUMRlri|„…]cd…„’›¢›‹„‹ƒ„„bVZ|‚zlldUTS‚|ulldƒƒ|ƒƒ|dc\sleVTLJHFJHFJHFztlJHF3+*{u{››”ƒ‚u]bZtsl‚|u{tt‚ut{{tjcVb[Ukd\ttssle£›››¢›ƒ||{u{’…‹{u{’ŒŒrfk‚ut“““fkkƒ}ƒƒ„„llkœ››ult‹„„{||Œ”•ƒ}ƒ›”››”›„„Š’…‹‹’Š|‚z„„Šf]c{u{‹‹‹‹’Š‹„‹zll\[[tt{”››…‹’lekdc\\[bf]cult{{tllk„Š„‹‹„llkƒ„„lddƒ}ƒ‹„‹‹„„ƒ‚u‹„‹f]c‚v{‚|u‹„„“““ultVTL›¢›“““uztttsslef]cƒ||ddc\[[|‚z„Š}œ››u{{Œ”•ldd…‹’…‹‹„Š„ƒ||Œ—£››”ª³·|„…tllrfktts™š¤””‹lek{||{||ƒ„„‹…’tzlƒ„„{{t¦§¨“““|„…{u{|„…Šƒ}lriedkllkƒ}Š{{ƒ¦§¨|„…|„…ƒ„„“““…‹‹Œ”•|‚z””‹‹’Š›¢›‹’Š|„……‹‹„Š„…‹‹”››”“›{{ƒ¦§¨”“›™š¤ƒ||š””bVU¦§¨ª³·redtll£œ¥‹’Š’ŒŒ‹„„ÃÄÆ¨©´¦§¨Œ”•‹„‹“““’ŒŒ‘Œ…‚|uš””dc\ŠŠ}‚|u””‹””‹‚v‚›¢›‰‘~]bZuztkd\lek‰‘~\UZ‹‹„Œ”•ª³·›”›””‹|„…bVZultf]cf]cƒ}Šƒ}ƒƒ}Š‹’Š™š¤fkk{{ƒ{{ƒmttUTStzl‹„‹Œ‹“Š}ƒ‹„‹›”›tllultult”𔣛›‹…’{{tultdc\Œ‹“u{{uztekd[[Tlridc\|‚z„Š„lrisleddctzldc\VZ[lriUTS\[[ddcVZT|„…‹„„fkkƒ}ƒbVU™š¤tt{ƒƒ|tsl‹„„lld{zmlriƒ‚ulldf]c{ttUTS|‚z›¢›JHF*)(lksuztuzt””‹”››zllƒ‚uƒ‚u{tt{tt£››uzt””‹šŒŠƒ}””‹’ŒŒ{u{ƒƒ|bVU‚|uŠƒ}tllƒ}ƒ{||ª³·‹„‹Œ”•¦§¨uzt‹‹„›¢›”“›œ¤¦{u{£œ¥lek‚v‚Œ‹“tts{||’}™‚v{{u{{||{{t{u{SKJlld{{t|„…{u{””‹„„Š…‹šult{u{lld{||{||{tt„Š„ƒ}ƒj]\Š}ƒs_qzllƒ}ƒ‹„„‹„‹tsl‚|ud\\zllcbVtslŒ”•mtt„Š„tsl\[[tll\UZ{zmuzt›¢›”š”u{{ª³·u{{|„…„„Š{{tƒ}ƒ“Œ”œ››š””¦§¨ttslekŠƒ}uzt{{tult‘ˆ}{tt{{ƒŠ~‹‹‹„‹’Š””‹ƒ„„š””ttstt{{{ƒuzt…‹‹”“›‹‹‹™š¤™š¤…„’tt{lddƒ„„™š¤|‚zu{{Œ”•ª³·‹‹„|‚z„Š„|„…”𔛢›tslƒ„„…‹‹tt{tt{ddcddcSKJ{tttll“Œ”™š¤”“›‚v{…‹‹ƒ}ƒ‹„„£œ¥¦§¨£œ¥“Œ”¨©´“Œ”¨©´¦§¨µ¶·ƒ||™š¤ztl“Œ”””‹mw‹‹„{||uztfkkMRKlrilrillk”››ddc…‹‹ŠŠ}{||edk{{ƒf]cleku{{”››u{{mtt{{ƒtslŒ”•ƒƒ|‹’Šmtt”››™š¤„„Š|‚z{||Œ”•™š¤”“›¦§¨œ››tslƒƒ|dc\Œ”•{u{edkƒƒ|JHF„Š„VTLVTLŒ”•iq]VTLu{{]bZ„Š„lekllkuzt\UZ‹„‹ttsJHF]bZ‚v‚JHF]cd]bZSKJ‹„„›”›‚utƒ}ƒŒ‹“ƒ‚ub[UlldcbVzll|„…Šƒ}|„…{{t|‚zmttmttšŒJHF*)(ldd”š”{zm‰ƒvƒ‚u{zmŠŠ}ƒƒ|{{t‚ut‰|vŒ‹“””‹¤¤‚ut‹‹‹‚v{{||tts‘Œ…‚|u’ŒŒ¦§¨™š¤{tttts““““Œ”{zm“Œ”“Œ”ƒ}ƒ‹’ŠŒ‹“{u{tll‘…„tt{ztl|„…{||ƒ}Š‚v‚{||llktlllldlddlri‹’Š˜Ž£Œ‹“ƒ}ƒ{{ƒf]cultƒ||ƒ}ƒŒ”•mtt’ŒŒ‹‹„f]cƒ||ultrfkulttll“Œ”Š~‹ŠŠ}{tt{||{ttddctzluzt‹’ŠŒ”•‹‹‹£››š””ttsuztƒƒ|‹’Šƒƒ|edkttsŒ”•›¢›{||Œ”•œ››ŒŒš²¬µ””‹¦§¨{{ƒ›”›{{tmtt””‹ƒ||’ŒŒ{tt”“›¦§¨¦§¨Šƒ}””‹Œ”•ƒƒ|ttsƒ}ƒd\\lekttstt{‹‹‹|„…„„Šƒ}Š›”›‹„„“Œ”ƒ}ƒ™š¤£œ¥‹„‹’ŒŒƒ„„”“›Œ”•tts{tt¤¤™š¤”››“““ekdŒ‹“Š}|b[Uzll„„Š{tt¦§¨œ››œ¤¦Œ”•ƒ}ƒlksult{u{“Œ”†~‘™š¤™š¤²¬µƒ}ƒ™š¤tll“““Œ‹“¨©´‚v{£œ¥’ŒŒ“Œ”‚v{tll£››‹’Š{{ƒ|‚z|‚z„Š„Œ”•‹‹„””‹‹‹„lld„„Š…„’f]cƒ}Š„„Š”“›{{ƒ…‹‹]cduzt™š¤ª³·›¢›œ¤¦”››¦§¨„Š„‹’Šƒ}ƒ£››{{ƒœ¤¦…‹’„Š„””‹‹’Š‘ˆ}“Œ”‚v{[[Tuzt{||{{tVTLcbVllk|„…tzl[[TuztUTSuzt\UZVZ[‹„‹Œ”•ekdtll\[[uztUMRlri[[Tttsƒ}ƒ’ŒŒ£œ¥|‚zƒ„„‘Œ…kk]ekd{zmƒ„„‹’Šƒƒ||‚ztzl[[Tedk‚v{:973+*|‚ztts‹‹„lld{zm‘ˆ}ƒ||ztl”š”„Š„lddœ¤¦””‹¤¤‚|utslƒ||‹„„Œ‹“‹‹„‹‹„¦§¨‹„‹”“›Œ”•’…‹™š¤››”‹‹„¦§¨£œ¥…‹’¦§¨™š¤“Œ”{tt”›››”›ŒŒšµ¶·™š¤··Ä…‹’‹‹‹{{t“““‹‹‹{u{ƒ||lrif]c{{ƒ\UZ\[b™š¤f]c{{ƒŒ‹“‹‹‹…‹‹™š¤…‹‹Š}ƒ“Œ”ƒ||[TTƒ}ƒ\UZ{u{sle’‘~””‹”“›“Œ”‚ut|‚zƒƒ|‹’Š‹’ŠlriuztSKJ{||ult“Œ”œ››‹„„lksMSS|„…„„ŠŒ”•{{ƒ”𔋋‹ƒ}ƒ‹‹„|‚zlks¦§¨’ŒŒ{||‹„‹ƒ||‹„‹„Š}‹„‹µ¶·œ›››”›ƒƒ|‹„„›”›uztƒ}Š{ttttsŒ”•‹„„„Š„„„ŠŒ‹“Œ‹“ƒ||ultƒ}ƒ„vŒ¦§¨ƒ„„uzt””‹’…‹ƒ„„ª³·tts…‹‹Œ‹““Œ”lddŒ”•lddtsl›¢›‹…’£››¦§¨™š¤µ¶·lksŒ‹“Š}ƒ“““ultlks™š¤ult‹‹‹™š¤„„ŠlddlddŠ~‹‹„‹ƒ||™š¤Š}ƒ…‹’Œ”•”››”“›ultœ¤¦tllŠƒ}“““””‹¤¤™š¤|‚zlridc\“““|‚zekd„Š„lri|„…tslŒ”•f]c™š¤ƒ||{{tŒ”•ƒ„„ƒ„„{{ƒ…‹‹uzt“Œ”„„е¶·¦§¨|‚zƒ„„ƒƒ|lldllduztkk]“““]bZ””‹{tt„„Šllk[[T|„…mttddc‹’Šƒ„„‹’ŠVTL{{ƒ”››ƒ}ƒŒ‹“f]cUTSlkslkslri{||Œ”•lksttsult››”ultlks‹„„£››””‹ŠŠ}ƒƒ|‹‹„{{tdc\]bZ|‚z[[T[[T¦§¨LKR*)({{ƒtll””‹œ››{zm|‚z‘Œ…{{t””‹””‹£››™…””‹‘}zŠ}|””‹{tttt{Œ‹“uzt“Œ”£››ƒ}ƒ“Œ”{||ƒ}ƒŒ‹“Š}|””‹“Œ”œ››Œ‹“ddcƒ„„“““”“›’ŒŒ…‹‹{u{Œ”•™š¤{{ƒ¨©´Œ”•{||ttslek‹„„u{{ttslek\UZlddVZ[£œ¥ƒ}ƒlkstt{{||tll’ŒŒttsrfkŠ}|‰v|lddrg]‚v{„„Š“““„„Š‘Œ…Œ”•‚utldd‹’Šlldekdtzlekd„Š„tlllldŠ~‹{{ƒŒ‹““““}‡’\[[f]cŒŒš|‚z{||’ŒŒllk‹‹„llkƒ„„”››‹‹‹{tt’ŒŒšŒ²««››”“““£œ¥‹…’‹‹„|„…š””lldƒ„„tts{u{‹„‹‹„„{{ƒ“Œ”{{ƒ™š¤…‹‹Œ”•ƒ„„ddc¨©´ttsult™š¤ult{{ƒ¦§¨””‹Œ”•|‚z‹‹„{{ƒ™š¤Š}ƒd\\„„Š{tt‚v{ƒ}Štt{tll”“›œ¤¦…‹‹“Œ”›”›™š¤“Œ”f]c‚ut{{ƒ“Œ”\UZ‹„‹rfk™š¤ultƒƒ|ƒ||“““‘Œ…uzt¦§¨llkŠ}ƒ‹„‹›”›‹„‹ƒ„„sle{u{”“›‹’Šœ››d\\]bZtslŒ”•lrillkmtt{ttmtt‹„‹d\\ƒ|||„…Œ”•”››™š¤…‹‹„„Š…„’“Œ”“Œ”¨©´‚v{…‹‹ultŒ‹“|„…‹’Štsltzl{||ƒƒ|lriuztlks“Œ”””‹ztlƒƒ|‘Œ…|‚z{{t{{t[TTlldekdƒ}ƒd\\{u{d\\[TTJHFVZTuzt{||ekdf]c{{ƒlekƒ||‹„‹…‹‹lrizllztl“““tzl|‚z{{t„Š„]bZ‹’Š]cdu{{²²¬:97*)(kk][TTƒ‚uƒƒ|uzt‘Œ…Šƒ}””‹²²¬””‹‘ˆ}Šƒ}””‹sleŠ}|””‹¦§¨›”›™š¤œ¤¦‘Œ…“Œ”“Œ”ultƒ„„¦§¨¦§¨ƒ„„Š}|››”²««™š¤‹‹‹ƒ„„“Œ”£œ¥œ››“““œ››””‹„„Š“Œ””››£››{||‹‹„‹’ŠŒ‹“edk|‚zŠƒ}{{ƒd\\]cd‹’Š|‚zŒ‹“ƒ}Š”››£››™š¤ƒ}ƒ›”›Š~‹ylemttkd\ddcf]c{u{sreŠ}ƒttskd\“Œ”‹’Šzlldc\llktslttsd\\|„…ultu{{tts‹’Šlrilksddc”“›lksddcƒ||lksŠƒ}¦§¨Šƒ}|„…””‹|‚z{{ƒ…‹‹Œ‹“››”{tt‹‹‹Œ‹“‹„„rfk{zmtsl{{tŒ”•“““‹„‹””‹œ››‚v‚{{ƒ¨©´™š¤ƒ}ƒ‹„‹ttsƒƒ|ƒ„„…‹‹”“›‹„‹{{t¦§¨ƒƒ|™š¤ttsŒ”•Œ‹“„„Š£œ¥”𔦧¨ƒƒ|‹„„{{t“Œ”‘Œ…™š¤‰v|‹‹„‹‹„¦§¨Š}ƒƒ}ŠŒ‹“’}™„„Š„„Š”“›ƒ}ƒ‹…š\[b£²ƒ}ƒddc”š”{{ttllf]cƒ‚ulritsl›”›Š}|{zmƒ||ƒ}ƒ„Š}]cd„„Šu{{u{{[TT{{ƒmtt‚v{”“›|„…ztl…‹‹{{ƒtll{u{¦§¨œ¤¦…‹’…‹‹{{ƒ|‚z‹‹‹™š¤…‹’”“›”“›Œ‹“š””|‚z‹’Š|‚z””‹lrikk]|‚z”š”Šƒ}tzl¤¤“““tllƒ„„llk“Œ”“Œ”{ttŒ‹“ƒƒ|\[[kk]ƒ||tllVZT‹‹‹|„…u{{tt{|‚z‹„‹]bZƒ}ƒ[TTtt{lri{||ultlld|‚zllkekd[TT{||mtttzltll{||²««F=C7-2‚ut‹‹‹„Š„ztlƒ||‹„‹{zmsrekd\{{t¤¤sle›¢›ult””‹‹‹„‘…„‹„‹ƒ„„z‚l’ŒŒ‚utš””{u{‹„‹Šƒ}ƒ}ƒmtt£››Šƒ}™š¤{u{‹’ŠŒ‹“‹…’Œ”•“Œ”“Œ”™š¤uztŒ‹“›”›…‹’‹’Š’ŒŒ|„…„Š„lksmttŒŒš{ttu{{{{tuztŒ”•dc\tt{ult{||ƒ„„›¢›…„’ƒ||tll‹„„[TT{{tddc‚ut{||„Š„\[[Œ‹“{||Œ‹“‹‹„ekdlldƒƒ|{{t{||tts\[blksƒƒ|™š¤‹‹„lrilks}‡’Œ”•™š¤‹‹„›”›llklddllk„„Šllkf]c\[[“Œ”””‹›”›‘Œ…œ››tts‹„‹Œ‹“‚|u’ŒŒƒ„„lldu{{£››™š¤œ¤¦…‹‹”“››”›edk‹…’“Œ”™š¤Š}ƒƒ„„„„Š‹…š‹…’””‹Š}ƒ‘Œ…‚ut‹„‹‘ˆ}‚|u‹’Š{||Š}|tts‹’Šsreƒ„„Šƒ}Š}ƒ£œ¥£››Œ‹“‹’Š„Š}™š¤›”›“Œ”‹u…œ››“Œ”Š}ƒ{{ƒ“Œ”“Œ”‹‹‹„„Šf]c{u{‹„„zllldd‹’Š£››ztl{ttttslksedkFD;kd\””‹z‚l[TTŒ”•“Œ”™š¤}‡’UMR\UZ…‹’|„…„„Šlks…‹šedk…‹‹UTS…„’Œ‹“™š¤u{{u{{™š¤|‚zyl„¦§¨{{tŠƒ}‹‹‹{{tllkd\\ƒ||{{ƒ|„…ult{||]bZ{{t”››””‹lddVTL¦§¨„Š„{||”“›ƒ||“““{{t|„…mttf]cuztultlks‹„‹llktt{{u{edkrfktllƒ}ƒlri{{ƒ{tt‚|u„Š}ztl[[TztlŠ~‹|„…{{tlldlld²««JHF*)(tsld\\|‚z’ŒŒƒ„„ztl‚wl[[TŠŠ}‚v{’ŒŒu{{‘Œ…’ŒŒƒ}ƒ‹‹„‘…„{ttƒ}ƒ„Š„‹’Š“~ˆzll‹‹‹£››„Š}‰‘~„„Š‹‹„„Š„“Œ”™š¤ttstts{u{‹‹‹|‚z¦§¨Œ”•‹’Š™š¤{||™š¤ƒ||tll‹’Šlritt{\[b|„…ƒ}Šœ¤¦ekdldd|„…ƒƒ|‹„„ŒŒšllk{{t|‚z|‚ztslƒ}ƒ‹„‹{{ƒult…‹‹{{tcbV{ttŠ}ƒ“Œ”ƒ||cbV‚|u{||”𔛢›‹’Š„„ŠVTL\UZŒ‹“Œ”•Œ”•ƒƒ|œ¤¦{{ƒŒ‹“ƒ„„”𔋒Г““|„…ƒ||‚|uyle|„…{tt„Š„ƒƒ|ƒ„„ƒ„„‘…„”“›tllŒ‹“llktts|‚ztts‹‹„„„Š”“›ƒ||Š~‹Œ”•„Š„|„…f]c{{ƒŒ‹““Œ”Š~‹ƒƒ|¨©´lld{u{{{ƒ›”›“Œ”lri{{ƒ’…‹Œ”•‘…„£œ¥‹„‹{{ƒŒ”•›”›™š¤‹‹‹ztl‹„„¦§¨‹‹„ƒ„„””‹“““Šƒ}‹„‹tlltsl‹‹‹ƒ}Šf]c{u{tts{||‹‹„Œ‹“[[T¢“d\\zllj]\‹„‹‚v‚“Œ”‘Œ…››”SKJ‚v{sre\[[œ››””‹Šƒ}|„……‹‹{{ƒmtt„„Šf]cŠ}ƒttsƒ}ƒtzlVZTƒ}Š\[[ultdc\lri|„…{{tu{{œ¤¦œ¤¦””‹…‹‹‹‹‹‹„„””‹ƒ„„ultƒ}ƒddc”“›Š}|VZTVTLuztmttJHF|‚z|‚z”››lld›¢›„Š}›¢›‹‹‹lld‹‹‹ƒ}ƒtts|„…ultf]cddc[TTtslf]c”“›‹„‹{{trfkŒ‹“>EC{{tVTLlldllk{ttfkktsl|‚z”š”]bZ›¢›£››:97:97Š}ƒƒ||››”tll‚|u¦§¨{{t|„…ztl{{t¦§¨‚|uŠƒ}“Œ”ƒ‚uŠƒ}¦§¨|„…ult””‹dc\sle“Œ”‹„‹‹…’“Œ”‘…„rfkƒƒ|‚v{“Œ”ƒ„„¦§¨{{t‹„‹‹‹‹“““¨©´ƒ„„|„…{||‚v‚tt{¦§¨{{t]cd…‹’tt{uzt…„’{ttœ¤¦ddclri]bZrfk“Œ”|„…{{tŒ‹“|„…u{{ultlriredu{{ƒƒ|r]g{{tƒ}ƒlddƒ||‹„„lddredred›¢›¦§¨œ¤¦„Š„›¢›mttUMRu{{{tt{||srett{ƒ}ƒŒ”•{{ƒª³·””‹£œ¥›¢›ƒ||””‹rfk{||{||ttslri…‹‹‹‹„œ››”“›{||¦§¨‹‹‹ŠŠ}‹‹‹“““›¢›‹„„”“›Œ”•{tt…‹‹‹‹‹”“›Š~‹f]c‚v‚ƒƒ|œ¤¦\[[‚v‚…‹‹Œ”•tt{„„Š“Œ”llk“Œ”‚|u|‚zœ››„„Š‹‹„|„…–¢‹‹…’”››ƒ||lld”š”tt{ƒ„„‹‹„ztfŠƒ}¨©´’…‹”“›„Š„‹’Š{||dc\f]c‹„‹ƒ}ƒ””‹Š}|””‹Šƒ}kd\‹’ŠlekVZTlrisleredzlltllztlsreVTL{{t‹‹„£››‹…š‹„‹‹‹‹‚v‚{{ƒlks|‚z’ŒŒ„Š„uztsle…‹‹\[b]cdƒ}ƒŠ~‹ƒ„„uztmtt”››Œ”•Œ”•ttsmttddc{|||‚z{||sleJHFƒƒ|\[[‹’Š[TTdc\„Š„„Š}lri”“›|‚z\[[›¢›ƒ„„]cd‹’ЄЄrg]š””ekdtslƒ||ddcuzttt{ƒƒ|Œ‹“„„Šlld‰|vdc\u{{SKJdc\tslVTLlld[TTsreƒ||lriaWMSKJ|‚z£››D;9*)(ƒ„„“Œ”Šƒ}tslƒ‚u’ŒŒ››”‘Œ…’ŒŒ””‹“Œ”Šƒ}£››¦§¨£››{{t¦§¨ƒƒ|‹’Š“““lek‹’ŠaWMª³·‹„‹›”›…‹‹‚ut‹’Š£››Œ”•|„…””‹ŠŠ}£››Œ‹“œ››²¬µµ¶·Œ”•›”›ƒ}ƒŒ”•ƒƒ|[[T’ŒŒ[[T]bZmttd\\ƒ„„{zm’…‹„Š„tsl„„ŠŒ‹“{{t’ŒŒƒ||„Š„ƒ}ƒš””lriztlŠƒ}{ttldd„Š}{u{Œ‹“”“›‹„„‹„‹Š}ƒult…‹‹|„…„Š„|‚z‹‹„‹’Š|‚z””‹„Š„ekd””‹u{{f]cztlƒ„„…‹š”››¦§¨ttsƒ„„„Š}ztfddc‹„„{{tsre‹„‹„Š„ƒ||{tt{||„„ŠŒ”•”𔦧¨…‹‹›¢›””‹‹‹‹lksult™š¤Œ‹“ƒ„„tt{llk{{ƒsle{{ƒŒ‹“‹‹‹|„…¦§¨Œ‹“…‹‹{{t‹„‹ultŠ}ƒ‰ƒvœ¤¦„„Š’ŒŒ…‹‹llk„„ŠtllcbVŒ‹“’…‹|‚zƒƒ|ztltt{‹„„¦§¨{||mwsreƒ„„‹’Šsleult{tt…‹‹‹„„ŠŠ}ƒ„„ƒ‚uzll‚utylelritll£œ¥‹„‹””‹tlltzlkd\b[UddcŠƒ}lek™š¤›”›edk›”›‚utƒ||„Š„|„…u{{‹’Š|‚zllk{{ƒƒƒ|Œ”•tslŒ”•››”‹‹„™š¤u{{ƒ}ƒlldƒ}ƒUTS””‹|‚z[[Tultuzt¦§¨tt{mtt{{t{{tlld]bZbVUultultUMRŠ}ƒ{||‘Œ…‹’Šb[Uztlf]c{{ƒ…‹‹ultult””‹|„…{||{{ƒ{{ƒkd\„„Štt{fkkf]cd\\‹‹‹‚utzll{{tlrilridc\\[[ekduztš””:97*)(tzlsre‹‹„ƒ}ƒ{tttts””‹¤¤£››“““’ŒŒ‘…„“Œ”²««ƒƒ|‘Œ…ƒ„„{ttttsƒƒ||‚z«²«Œ”•{tt¨©´£œ¥¤¤…‹‹‘Œ…ƒ||¦§¨“““›”›¦§¨›”›™š¤‹‹‹¤¤œ››‹’ŠddclddŒ‹“|„…]bZ\[bƒ||tt{‹’Š‚v‚ƒ}ƒb[U‹‹„|‚z‹’ŠŒ‹“ƒƒ|‹‹‹‹„„{||u{{ldd›”›‹‹‹{u{ŠŠ}kd\zllkd\lek”“›‚v{kd\edkŠƒ}{{ƒ“““|„…£››tts„„ЄЄ[[T{{ƒ‹’Šmttdc\]cdSKJlek…‹‹lkskk]‹‹„{||“““tsllldllkslelld[[T{ttƒ}ƒ£œ¥‹„‹››”’ŒŒ|„…£œ¥””‹ddc|‚zlddƒ}ƒŒ”•‚v{¦§¨‹‹‹Œ‹“’ŒŒult“Œ”œ¤¦ŒŒš“Œ”uztttsŒ”•ldd…„’mwƒ„„{tt“Œ”“““‹‹‹“Œ”’ŒŒultŒ‹“”“›”“›‚v{ƒ„„{||™š¤”››ƒƒ|‹„‹tllš””Œ‹“œ››tsl{{tŒ”•””‹{||\UZ{{ƒ‹‹„µ¶·‹‹‹œ¤¦ƒƒ|{tt‹‹„”𔋄‹£œ¥’ŒŒ‘Œ…SKJttsjcVldd]bZƒƒ|‹„‹ƒ„„™š¤Š}|lekf]c‹„‹dc\“““„Š„‹’Šttsœ››„Š„“““¨©´„„Š{{ƒŠƒ}lri…‹‹{{ƒƒ}ƒyl„edkbVZj]\›”›[[T‚|uekdd\\{{ƒ{ttddcttsf]c[[Tek]sleult“““lksFD;zllztlƒ||‹„‹tt{UMRfkkultu{{‚|uJHFƒ„„red“Œ”ƒ}ƒŠƒ}{{ƒ{||\UZztl{||ƒƒ||‚z”š”]bZkk]dc\\[[UTS]bZ¦§¨:97*)({{t{ttlddred’ŒŒƒ}ƒ¤¤{zm„Š}²²¬š…Ž‹’Šztfztl¦§¨ƒƒ|“Œ”„Š„£œ¥µ¶·“““¦§¨¦§¨“Œ”…‹‹”𔦧¨£œ¥›¢›ƒ}ƒ¨©´’ŒŒ‹„„””‹{||””‹‹‹‹„Š„{ttƒ||{||››”ddc{{ƒ‹‹„ƒ||lek”“›Œ”•”“›tlld\\lld‹’Šœ¤¦ƒ}ƒ“Œ”‹„‹sredc\Œ”•“Œ”„Š„u{{{||sleSKJ‹„‹ƒƒ|tlltllzll‹„„r]g“Œ”mtt„„Š“““¤¤Œ”•{||ƒ„„tslƒ}Šœ¤¦|‚z{{tuztd\\ƒ||”››ddc‹’Š–¢‹ƒƒ|ztllritts‹‹‹ztlƒ„„|‚zƒƒ|ƒ||{u{‚ut’ŒŒ‹„„„Š„{{ƒ‹’Šlld‹„‹{{tƒ}ƒ““““Œ”Š}|lek“Œ””“›ultƒ}ƒ™š¤“Œ”tt{tts”š””››œ››{{ƒUTSlksttslriœ››‹‹‹“Œ”tts{u{ƒ||›¢›ƒ}ƒ‹„‹„„Š‚|uek]™š¤‚|u²««{||”“›tsl“““Œ”•{{t””‹ƒ||{||tts|‚z‘Œ…“““ƒ„„š””{{t£œ¥‹‹„”“›\UZ£››ddcztl‹’Šdc\VTLVTLek]tllŒ”•ª³·{ttyfltt{\[[ƒ}Š[TTtt{leku{{VTL]cduzt…‹‹„„Š„„Šu{{lksd\\|‚z››”f]c¦§¨lri{u{j]\edkttsllk]bZllkƒ„„{{ƒ\[[SKJek]tll‰|v””‹VZT“Œ”[TT{||dc\ldd[[T‚v‚lksf]cƒ}ƒttsf]cJHF]cd{{ƒlek“Œ”‹‹„tt{Œ”•fkkƒ}ƒ‚v{|‚zsle\[b‰‘~lrisre]bZ[[TFD;ƒ||“Œ”:97:97rfkkd\‹‹„{tt£œ¥””‹‹’Š›¢›{{t£››ƒƒ|””‹›¢›‹„„²¬µ‹’Š™š¤£œ¥š””‹‹„¤¤”“›²¬µ“““œ››™š¤””‹”š”››”|„…µ¶·‹’Ц§¨¦§¨œ¤¦›”›œ››ƒ„„š””‹‹‹‹„‹¦§¨|‚zultƒ}ƒ‹‹‹”𔤤¦§¨{{ƒlektts{{tllkŒ”•{u{‹‹‹‹‹„…‹‹¤¤™š¤‹‹‹{{ƒ”“›‹„‹{ttb[UbVZtslƒƒ|ult£››ztf”››‚v{œ››{u{llkztl„Š„ƒ„„UTS‹‹„{{ƒsre™š¤ƒƒ|mtt‹„„ƒ||”š”…‹‹mttŠƒ}‹„„‹„„ek]Šƒ}{{ƒ’ŒŒ\[[lrisle{u{ƒ}ƒrfkš””ƒ}ƒ‹’Š£œ¥‹‹„lri‹„‹ƒƒ||„…|„…™š¤””‹““““Œ”ƒ}Й𤋋‹“““tslultmtt…‹‹„Š„ƒ||…‹‹llk‚|uƒ}ƒ{u{‹„‹Š}ƒ”“›ttsllkŠƒ}¦§¨{||š””dc\{||ult|‚z{{ttslultš””ƒ||£›››¢›uzt‹‹„›¢›Œ”•„„Š£œ¥¬¶Ã“Œ”£œ¥›”›‹’⬵ƒƒ|{||{||‹‹„Œ‹“‘Œ…lld‹’ЉƒvŠƒ}‹‹‹ŠŠ}Œ”•ƒ„„ultbVUf]clddƒ}ƒedk[[Tlriult›”›”››™š¤‹„„ultlri”“›ek]{{tdkVmttƒ}Šztlult’ŒŒ„„Štt{llkUMRLKRƒ}ƒ“Œ”{tttts{{ƒ\[[ttsttsŠ}|kk]llk|„…ƒ||£œ¥uztlek™š¤Š}ƒ{{ƒf]cJHF‹‹‹{||VTLlriƒ}ƒ|„…Œ”•mttllk\[b{u{ultllkttssre{{trg]|‚zuztMRK\[[dc\¦§¨:97*)(dc\ztl’ŒŒ‹‹„„Š}””‹‹‹„ƒ||››”¤¤{u{ƒ‚uŠ}|’ŒŒ¨©´œ¤¦{||¦§¨”››‹’Š«²«µ¶·œ¤¦œ¤¦”“›“Œ”œ››„„Ц§¨„„Šƒ}ƒ™š¤“““”››‹‹‹‹’Š‹‹‹ƒ‚u‹’Ц§¨£œ¥²¬µ”››uzt‹‹‹²««{{tœ¤¦‹’ŠŒ”•{{ƒ{u{SKJ[TT|‚z“Œ”kd\‹‹„„Š„‹„„u{{‘Œ…UTSƒ||j]\{zmlddƒ}ƒrfk{{ƒtll’ŒŒ{tt‹„‹{tt“Œ””››™š¤£››{||„Š„JHFtsl‚v{{{tu{{”››„Š„uzt‹„„ttsŒ”•|‚z””‹lldd\\“““¤¤‹‹‹‚v{|‚z„Š}‚|ullkf]cultult‚|u”š”{tt|‚z{||Œ”•œ¤¦”››Œ”•”“›„vŒ|„…yl„“““Œ”•’ŒŒ””‹ult{u{|„…{u{{||ztl‹…’‹‹„ult[TT{tt’ŒŒ‹„‹{{ƒ‹„‹[TT‹‹‹‹„‹‹‹‹tlltsl{u{tlltslred‘ˆ}’ŒŒ›”››”›{||Œ‹“¦§¨”š”ttsœ¤¦¨©´…‹‹‹‹‹“““›”›“Œ”{tt‹„„|„…uzt{u{ƒ||¨©´››”‹’Š‹…’ƒƒ|‹‹‹|‚z“““‹‹‹“““ƒ„„“Œ”Œ‹“{tt{{ƒ[TT]bZb[UlriŒ‹“uztdc\{tt{{tredult|‚z{||{{t{zm{{t{{t“““‹’ŠVTLŒ”•‹…š\UZtts‹„‹d\\ƒ„„œ››ƒ}ƒddcƒ||\UZek]SKJ{{ttt{UMRŒ‹“{{t‹„‹‹„‹„„Šd\\VZTUMRlri{ttddc…‹‹ƒ||„Š}‹…’d\\tsltts[TT|„…„Š„Š}|u{{z‚llriŠƒ}ddcUTS[TTlektslFD;,55‹‹‹››”Šƒ}yleŠƒ}‹‹„’ŒŒ‚ut””‹ƒ||‹‹„Š}ƒ{{ƒƒƒ|ƒ}ƒ‹‹„„„Š…‹‹›¢›¤¤¤¤‹’ŠŠ~‹¤¤‹…’‘Œ…˜Ž£ƒƒ|‹„‹sre›”›|‚zœ››ƒ„„‚|ulri|„…‹‹„“Œ”tll‹„‹™š¤…‹’u{{|‚z‹„‹‹‹‹…‹’ŠŠ}ult‰|v{||dc\£œ¥fkkleklks’ŒŒ†~‘£››ƒƒ|œ››Œ”•{||””‹j]\tllŠ~‹{u{‚ut‚ut“Œ”tts{u{ƒ}ƒ„„Š{||”“›‹‹„uztuztllklld\UZ„Š„Œ”•VTL{{ƒ|‚z|„…›¢›œ¤¦lrikk]‹„„‹„„{{t™š¤ƒ}ƒtllrr]””‹{{ttt{lddf]c’…‹‚v{‹‹‹¦§¨lri™š¤‹‹‹”››¦§¨Œ”•Œ‹“Œ‹“¦§¨£²ƒƒ|”“›Š~‹”››{{ƒ…„’|„…]bZŠ}ƒŠ~‹“““fkkŠ}|llkb[U‘…„{u{£œ¥ƒ||d\\‹’Šƒ||’…‹tzldc\cbV{{ƒdc\””‹‘Œ…j]\ddc‹…’Š}ƒœ››Œ”•œ§²|‚z”“›u{{tslŠŠ}¦§¨‹„‹{||…‹‹™š¤‹’ŠleklekŠƒ}‹„„zll|‚z‹„‹‰ƒv²²¬…‹’sle…‹‹“Œ”ƒ}ƒ‚v{VZ[ultultbVZ‘…„ƒ}Šƒƒ|tll…‹‹SKJVZ[uztUUYUTS|„…‹‹„ddctslllkŒ‹“™š¤‹„‹‹’Ц§¨‹‹„{{ƒƒ}ŠŒ‹“{tt‹„‹lekŒ‹““Œ”u{{lri{{ƒ{{tztltll[TT™š¤{{ƒ{tt‚utƒ}ƒ‹„‹ddcUUYllkœ››lri‹„„tt{ztl‹„‹VTLƒƒ|{{tldd“Œ”tslmtt‹‹„ƒ„„lriztl‹’ŠtslUTSJHF’…‹:97*)(Œ‹“„Š}“““{||””‹Šut„Š}tll¦§¨{{t‹‹„››””š”””‹“““œ¤¦¦§¨ztlµ¶·‹‹„µ¶·””‹Œ‹“”š”ult“““’ŒŒuzt™š¤‹‹‹£œ¥ƒ„„{{t‹‹‹›¢›|„…‹‹‹{||‚|uƒƒ|ƒ}ƒ|‚zŒ”•lksƒ„„{tt‹‹‹…‹‹Œ‹“…‹’ƒƒ|tslœ¤¦{ttŒ”•›”›¦§¨“Œ”‹„„ƒƒ|ƒƒ|‹’Š‚v{””‹ddc‚utJHFƒ}ƒtts„„ŠŠƒ}bVU{u{{{t{u{‹„‹{{ƒ…„’slerfk{{ƒ|„…{{tult\[[]cd[[TmttlriVTLlri|„…œ››ztlƒ||lld””‹ƒƒ|{ttd\\{{ƒ””‹Šƒ}{{ƒtllŠ~‹’…‹“Œ”™š¤ƒ||›”›„Š}‹‹‹’ŒŒ£œ¥ƒ„„‹‹„™š¤ƒ}ƒ…‹’‹„„œ¤¦lri{tt{||ƒ„„llkzll|„…sle‹’Šllk{u{‹„„sletll‚|uƒ||Šƒ}lkstzl“Œ”ƒ||”“›„Š„ƒ‚uŒ‹“lld’ŒŒ””‹‰|v“~ˆ‹„‹™š¤™š¤“““ƒ„„{tt{u{\[[„Š}œ››“““{||uzt[[Trfk‹‹„d\\{u{š…ŽŒ‹“¦§¨œ››ƒ„„“““tsl|‚z‚|uƒ„„ult{u{UUY\[[ldd{{t{u{‚utult{{tƒ}ƒ…‹‹Œ”•ult‹’Šj]\lek„„Štt{ztllriddcŒ”•‹„„{ttb[ULKRVZ[lks…‹šf]cttslddult‹’Šƒ||{u{ult‚ut{{tbVU{||VZT\[[Œ‹“{{t’ŒŒtll¦§¨‹‹„VZ[mtt{ttmtt{{tf]cSKJ{u{ƒƒ|„„Š\UZztldc\SKJ‚v{tsl{{tuztuzt|„…\[[VZTUTS¤¤:97*)(ƒ||kd\›¢›{{t››”¤¤‹‹‹›”›ztl‘Œ…¤¤™‹†ƒ||sretts£››‹‹‹¦§¨”š”’ŒŒtslœ¤¦ª³·µ¶·¦§¨™š¤‹‹‹”𔋄‹”“›”“›””‹¦§¨ª³·¦§¨¦§¨tt{Šƒ}|‚z”“›{u{£œ¥UTSztl|‚z{||…‹‹ƒ„„‹’Šttsƒ„„{||œ¤¦ekd‹„„“““™š¤bVZekdƒ‚u›”›‚|uVTL\UZ{||“Œ”f]cŒŒšult{u{‹‹„“Œ”Š}ƒ|„…lek‚v{{u{›”›leklksf]clldUMR{{ƒcbV…‹‹””‹‹„‹ddcSKJuztddc‚|u‹‹„“Œ”sleœ››{u{››”Š}ƒƒ„„„Š„kd\ult‹„‹Œ”•Š}ƒ”“››¢›™š¤“Œ”¦§¨¦§¨œ¤¦„„Š«²«£››™š¤‹„„ƒ„„“““ƒ}ƒ‹’Š‹„‹“Œ”£œ¥Œ”•{{t{{ƒ‹„‹¨©´{ttdc\‹‹„…„’zllztl‚utƒƒ||‚z››”‹„‹‚v{{tt„Š„tslŒ‹“ƒƒ|‘…„kd\ƒ}ƒ’ŒŒj]\Š~‹£››‹’Š‘Œ…œ››”“›…‹‹œ¤¦‹’Š”“›{{ƒ{tttts[TT”š”mttu{{kk]lekƒ‚u””‹ƒ„„–¢‹‘…„…‹‹{ttuztlekedklrimttd\\\[[ƒ||{{ƒult‚wl{u{Œ”•Œ”•‹’ŠUTSedkd\\ƒƒ|UUYtllf]ctts‹„‹ŠŠ}|‚zƒ||UTS\[[llkœ¤¦UMRrededk{{ƒ‹‹„ƒƒ|lek|„…sreƒ||‚utddclrimtttt{{u{ƒƒ|””‹lri\[b\[b[[Tlri{||lldf]c‹…’™š¤¨©´mtt›”›tll„Š„lekdc\ƒ‚u‹‹‹ƒ‚uttsmtt‚v{[[Tekd£œ¥:97*)(ztlƒ‚u›¢›tsl››”‹’Š‹‹‹”››„Š}£›››¢›””‹”“›ƒ||¸Á¹¨©´£››{tt£››ƒƒ|‹‹„„„Š“““™š¤““““Œ”Œ”•¨©´Œ‹“”“›ƒƒ|{{ƒ›¢›ŠŠ}tsl”››ƒ}ƒ‹‹‹‹„„“Œ”{tt|‚zUTS]cdlritllŒŒš‹„‹|„…lkslldtsl…„’mttŒ”•Œ‹“”“›Œ”•ƒƒ|‚|uult””‹‚wltslrfkƒ}ƒj]\\[[uztleksresre{||{u{‹‹‹£››’…‹“““ƒ||‹‹‹“Œ”{||d\\ƒ}ƒ{tttt{|‚z‚|ulks”“›”››“““››”Šƒ}››”²¬µ›¢››”›‚|u‹…’lld„Š„Šƒ}ª³·¨©´“Œ”š””‹„‹|‚z™š¤’…‹|„…Œ‹“ƒ„„tllu{{’…‹””‹ƒ||ƒƒ|¦§¨œ››u{{”“›”“›…‹‹„„Šƒƒ|sleƒ}ƒ£œ¥{u{‹‹„Šƒ}œ››ldd””‹Œ‹“›”›œ››››”™š¤…‹‹“““¦§¨‹‹„£œ¥›¢›‚v{‚|u“Œ”‹„„‹„‹mwtll{{tŠƒ}Šƒ}ttsfkklri{{t’ŒŒ“Œ”{||‹’Š‹’Š|‚z‹„„ƒ„„tts{u{b[U{||i\V‰ƒv¤¤llkŠƒ}‹‹‹tt{‹‹‹lriSKJb[U]bZ{u{llk{tt‹„‹dc\uztfkk„Š„ddc{u{ƒ||””‹Šƒ}tzl{zmtsl{ttztllldllktt{„„Šƒ||lri{u{slef]c|„…{{t›”›MRK…„’sretzlsretslUUYUTSŠ~‹ttsldd¦§¨{||{u{\[b[TTf]ctslcbVtlltt{ƒ„„b[UUUY{{ƒkd\ultJHFleklld{ttfkkƒ}ƒUTSJHFVTL|‚zŠƒ}JHF*)(„Š}‹‹„‹’Š‚ut„Š„›”›|‚z“““¦§¨‘…„¤¤ƒ||‘ˆ}‹‹‹£››”“›””‹‹’Š››”{ttµ¶·£››Š}ƒ{||‚v{œ¤¦”“›¨©´Œ”•‹‹‹ƒ||›¢›uzt|‚zttsŒ”•|„…lri‚|u”𔋋‹edk]cd]cdf]ctsl{u{|‚z{{ƒtt{ult‹’Šœ¤¦‹’Š‹’ŠŒ‹“‹„„‹„„”“›››”’ŒŒƒƒ|„Š„bVUlriŒ‹“f]cJHFbVZlekƒƒ|ult‚v‚sleƒ„„zll‹„„“““‹„„tt{ƒ}Šfkk„Š„j]\ƒ}ƒ‹„‹{ttultŒ”•‹‹„{zm{||ƒƒ|‹„„ƒƒ|¦§¨ƒ„„Š}|’…‹Š~‹ƒ‚n|‚z””‹™š¤‹„„…‹‹tll’ŒŒ””‹{u{‹„„…‹‹“Œ”‹‹„Œ‹“{{t|‚zœ››Œ‹“ddctll„Š„¨©´“Œ”Œ”•œ››’…‹”š”ztl{{ƒ|‚z’ŒŒ‹’Š‹‹„ƒƒ|Š}ƒ‹…’Œ”•Š}ƒŒ‹“Šƒ}¤¤’…‹’ŒŒ‹„‹Šƒ}{||‹„‹ƒƒ|ƒ||ƒƒ|ƒ||Š~‹ult…‹‹‹‹‹zll‹‹‹„Š„{||llkkd\lek£››Š}ƒsle‹„‹ƒ„„{tt”𔋒Ћ„„‚|ullkllkzll””‹Š~‹[[Ttlltt{[TT\[[ddcSKJ‚utredu{{tt{‹„„|‚z‹’Š|‚zlridc\tt{‹‹‹„Š„Œ”•””‹lrif]c{u{{||{u{Œ‹“lkslektllylezlltsl„„ŠmttsleultJHF{{ƒek]lld…‹‹zlllldekdztl‹’Š‹‹‹‹‹„|‚zŒ”•]cd|„…ekd’ŒŒœ¤¦UTSultJHFVTLkd\Œ‹“‚v{sleƒƒ|tt{tll{{tttsƒ}ƒlek{{tlks]bZ¤¤F=C*)(lld|‚z‹’Š‹‹„£››“Œ”£œ¥š””µ¶·š””””‹’ŒŒ¦§¨‘…„¦§¨|„…tsl””‹””‹’ŒŒ‰ƒv£››tllŒ‹“Š~‹rfk„„Š’ŒŒ{{ƒtts{||”“›ttstllƒ||ƒ„„”š”Œ‹“‹‹„sre‹„‹mttu{{fkk|„…uzt{ttuztmttƒ}ƒ{||‹„‹|„…|‚z‹’ŠŒ‹“{||uztƒ||‘…„š””tts“Œ”ƒ}ƒtt{f]cJHFfkk{||ddc{ttš””ƒ}ƒult‹„‹¨©´‘Œ…ult“Œ”|‚zddcsleƒ„„„„Šƒ„„…‹’Š}ƒ„„ŠlrillkŒ”•”››ƒƒ|£››’…‹£››‹’Š›”›sleƒ||tllƒƒ|‹’Š“Œ”{{ƒƒ||‹„‹šŒlrilks“““¦§¨“Œ”‚|u{||…‹’ƒ„„ƒ||{u{tll‹„‹|‚ztt{”𔍩´ƒ„„Œ‹“¦§¨š””Œ”•“Œ”œ››‚v‚””‹[[T‚|u𔔙𤋋‹™š¤›¢›’ŒŒ|„…ztl‚|u‚wl‹„‹‹’ŠzllsleuztŠut{u{yfdllklld‹‹‹¦§¨{||‹…’{u{cbVƒ}ƒƒ„„”››¤¤ƒ||Œ”•‹’Š‹‹‹””‹‹‹‹’ŒŒttszllb[U‹’ŠŠƒ}’ŒŒtts“Œ”rg]ult“Œ”UMRrfk[TT{||ttslldllkJHFedk{zm]bZredƒ||„Š„cbVlkslksŠ}|ultrfk…‹’ulttts|„…ultƒ„„¦§¨››”ŒŒš[TTztlVTL{{ƒƒƒ|ult[[T‹‹„{zmfkklrilekJHFdc\tsl‰‘~Œ”•lddlldlriƒƒ|{{t‹‹‹“Œ”ztlSKJƒ||mttiWUd\\lritzl„Š}ldd{||ƒ„„“Œ”tzl‹’Šfkk²««LKR*)(u{{”›››¢›£››ƒ||‹„„“Œ””“›²²¬¦§¨²««‹„„‘…„ƒƒ|‹‹„””‹›¢›””‹£››¤¤¦§¨“Œ”‚v{£››£œ¥‹„‹Œ‹“”››‹’Š‹„‹™š¤¦§¨””‹|‚z{|||‚z…‹‹ƒ}ƒ{||²««‹‹‹¨©´™š¤…‹‹››”‹‹„{||‹’Šlks„„ŠlddlrilriŒ”•„Š„{{ƒ‹„„ƒƒ|‚|uƒ||ztlŒ‹““““{||„„Š„„Š‚|uJHFƒƒ|rfk{tt“Œ”{{ƒkd\‹„‹lek’…‹š””lks”››f]cmtt‹‹‹bVUƒ„„ult[TTtts]bZdc\tsl”“›››”‹„„‚v{ztlttsekdƒ||‹„„”š”ƒ‚u‹‹„‹„‹ddc\UZsle‹„„‹‹„”š”{ttu{{‹’Štts„„Š…‹‹‘Œ…š””|‚z{tt²««|‚z{u{ƒ„„™š¤™š¤ttsœ››‹‹‹…‹‹ƒ||‹‹„™š¤‹„„\UZztl‚wlƒƒ|‹‹‹„„Ц§¨™š¤mw””‹ƒƒ|‚|urfkœ››‘Œ…š…Ž””‹Š}|“Œ”f]cult‹‹„slešŒƒ‚u{{ƒƒ„„””‹ƒ}Š{{ƒ£››¦§¨uzt\[[ƒ„„{||››”‹…’‚utƒ}ƒŠ}ƒzllztfVTL‹‹„”››lekddcŠ}ƒ‹„„lddultkd\mtt…„’š””ekd]bZƒ||SKJuzt\UZ„Š„ƒ„„dc\kk]{||zll‹‹‹‚v{Œ‹“‹…’£œ¥|„…tts{{t{{t““““Œ”UTSdc\tt{JHF]cdddcjcVlriyflu{{›¢›Œ‹“{{ƒ[[Tmtt|‚z™š¤lri“Œ”|‚zlks{{tmttVTLredcbV“Œ”lksdc\ttsƒ„„uzt‹’Šƒ||tsl{||ddcfkk]bZ‹’Š››”JHF*)(|„…‹’Š|‚z‚|u””‹Š}|‹‹‹“““š””²²¬›¢›Œ”•Š~‹Š}ƒ“““””‹››”“Œ”š””sre›”›²««›”›“Œ”¨©´£œ¥›”›£››¨©´¦§¨Œ‹“Œ”•„Š}„„Š„„Š…‹’|‚z|„…tslƒ„„ƒ||tt{™š¤œ¤¦¨©´‹’Š|„…u{{mttlekulttsl„Š„tts{||Œ‹“Œ‹“lldslelldultŒ‹“™š¤f]c‹’Šƒ}ƒfkktt{…‹‹f]c‹„‹{{tlritll|„…ldd‹’Šult“““…‹‹ultttslldƒ}ƒ{u{{zmtllultekd›”›ƒƒ|’ŒŒŒ‹“£œ¥‘Œ…{zmƒ„„‚|uultult‹‹„‹‹„£››|„…ttsddc‘Œ…’…‹{{tedkred¦§¨{{ƒƒ„„ƒ}ƒ…‹‹ttsƒ}ƒ¦§¨œ¤¦£œ¥‹‹„“Œ”|„…llkŒ‹“{{ƒ…‹‹£››ƒ}ƒ‹„„‹„„{||ult‹‹‹‹„„“Œ”ƒ„„››”‹„‹ª³·£²š””™š¤‚|u‚|usle„Š„¤¤Šƒ}‹„„sle£œ¥yfl[TT{||‘Œ…ddc{||”››„Š„lri“Œ”¤¤””‹’ŒŒ{tttslŒ‹“‹‹„œ››“““lks“Œ”£››i\V‚|u{u{{tttll{u{‰Š¡{{ƒ‹„‹rg]tllƒ}ƒ‚v{ttsred“““tslztltslVZT\[[ekdu{{ek]ultbVZf]clekƒƒ|ldduztƒ}ƒŒ‹“rfk‹„‹¤¤‹‹‹lksu{{ult|‚z|„…›¢›{||lld[TTf]clriƒƒ|{||]bZddcllduzt”››|„…lld‹’Šuztƒ}ƒbVUtlltlltll‹‹‹ƒ‚u‰ƒv|‚zfkktzltslllkllklek\[b|‚zVTLsle¤¤\[b:97]bZrr]œ››””‹œ››‚ut£œ¥²««¦§¨²²¬¦§¨¦§¨«²«¦§¨‹’е¶·“Œ”œ››«²«‘Œ…²¬µ¨©´„„Šƒ}Š“Œ”Œ”•‹„„œ¤¦Œ”•œ¤¦£œ¥“““ztlƒƒ|\[[{tt|„…kd\lld{{t’…‹ultu{{tt{ultu{{lksmttedk{{ƒƒ||{||„„Štll|‚zf]cƒ„„ƒ||kd\”š”tlllldlldƒ}ƒ“““llkƒ||{{ƒ|‚zultedkekd{u{ƒ||JHFtll”››„Š„UTSmttultuzt\UZŒ‹“Š}ƒ|‚zd\\ultŒ”•]bZ”š”d\\””‹tts{zm’ŒŒtts¤¤š””š””ƒƒ|””‹ƒ||[TT…‹‹ƒƒ|””‹’…‹ƒƒ|ƒ„„lldƒ|||‚z|‚z{{ƒ|‚zƒ||“““œ¤¦“Œ”™š¤“Œ”u{{dc\{u{‹„‹llkƒ}ƒƒ}ƒ™š¤ƒƒ|›”›¦§¨šŒƒ||‚v{›”›ƒ||ƒ||ƒ||lksƒ}ƒ””‹{tt‹„„’ŒŒ”𔋒БŒ…šŒ‚|uult‹‹‹ultleklek„„ŠŠƒ}””‹‹‹„‹‹„¦§¨Œ”•’ŒŒƒ||‚ut‹‹‹‚ut””‹fkk‹‹„ddcŠŠ}‚wlj]\{yfj]\f]c‚|uekdllk‚v{ultd\\i\V[TT‚v{‚v{tts‚ut™š¤ek]lddƒ||\[[ult{{ttllfkk|„…f]c‹„„‹„„”š”™š¤„Š„””‹uztldd{u{uztŠ}ƒŒ”•u{{””‹|„…UTS…‹‹„Š„‹„„ƒ„„ult{{t”𔄄Š]cd“““VZ[„Š}›¢›uztJHFMRK{{t|‚zSKJ\UZlld„„Šƒ}Š{{ƒllduztƒ„„„Š„llk“““tllƒƒ|JHFJHFVTLllk¦§¨\[[&&ek]{||Œ”•¤¤Š}|™š¤¦§¨²««£œ¥‹‹‹£››‹‹‹¦§¨›¢›¤¤””‹“““””‹‹’Šƒ||¦§¨¨©´›”›‹„‹¨©´{{ƒ››”“““’ŒŒ‹’Й𤓓“”š”Œ”•ldd„Š„ƒ„„|„…|‚zŠŠ}{||ƒ}ƒ|„…lriultlksmtt„Š„lriUMR{{ƒsle{{ƒŒ”•lriultŠ}ƒ››”bVZtslfkkƒ}ƒ‹‹‹{u{ddc{tt]cdUTS|„…mw’ŒŒ{||d\\ƒƒ|dc\“Œ”llk£œ¥{||lriƒ||{ttu{{ultlddŠŠ}{ttUTS…‹‹VTL…‹‹rfk„Š„{u{sle››”lritll››”ztllld”š”š””{||ƒ}ƒddc”››{ttƒƒ|tts‰v|b[U„„ŠŒ”•uzt‹‹„|„……‹‹”“›’ŒŒ“Œ”„„Š…‹‹…‹’“Œ”{||…„’œ››‹‹‹“““sle’ŒŒ{{tttsult¨©´™š¤tsl’ŒŒtllultred‚|ulddVTLcbVœ›››¢›Šƒ}ƒ||’…‹’…‹Œ”•ldd‹„‹ƒ||Š}ƒ‚v‚‹‹„Š}|ƒƒ|””‹‹‹„¦§¨¤¤››”ttsttsœ››ddctsl‹‹‹‘Œ…lek‹‹„””‹SKJd\\{{t\[[dc\ƒ}Š‹„‹ult”š”…‹’{||¦§¨llkƒ||‹’Šœ¤¦‚v{‹„„{u{mttlldƒ„„f]cbVZ‹„‹f]cŠ}ƒddcttslekŠ}ƒ\UZ‚v‚›”›‚|uultredUUY{zmmtt«²«|‚z›”›{{tultƒ||ƒ||„Š„~’“lrilriŒ”•™š¤tsltsl|‚z|‚zf]cu{{{tttllƒ„„£œ¥llklddekd|‚ztzlƒƒ|ztlƒ}ƒ\UZlek\[[VTLslemtt¤¤MRK%&‹‹‹tsl–¢‹››”lldƒ„„{tt’ŒŒ‹’Ц§¨¦§¨“““””‹šŒ¦§¨””‹µ¶·œ››””‹¤¤œ¤¦›”›¨©´”“›„„Ц§¨ƒ||ƒ„„Œ‹“ult‹’Š””‹¦§¨œ¤¦š””‹„„uztuzt|‚zƒƒ|›”›‹‹‹UTS|„…{{ƒ|„…[[T\[[]cdlekd\\{ttlek“Œ”lrif]cldd{{ƒŠƒ}sleƒ}ƒ’ŒŒ‹’Š‹„‹mttSKJllklldsleƒ„„{ttddc{ttj]\llk‹„„lritlluzt|„…‹‹‹lld™š¤ƒƒ|™š¤Šƒ}{ttbVU]cdVZTlld’ŒŒ‹‹„ult””‹””‹’ŒŒ£››slef]cdc\ztl‹„„ŒŒšŒ”•ƒ||œ››‹‹„”š”{||ƒ||‹’Šmtt››”…‹‹ƒ„„›”›Œ”•„Š„ƒ„„tsl”››œ¤¦mtt{{ƒtlltt{ƒƒ|tll{{ƒsleztl„„Ф¤{u{ƒ||›”›‚|ukk]‚v{dc\™š¤¦§¨‰v|f]cŒ‹“™š¤ŠŠ}‰|v””‹”“›’ŒŒŒ”•ƒ}ƒf]c‹…’“Œ”Š}ƒƒ||‚|u„„Š‹‹‹¦§¨kd\ƒ||kd\””‹ƒ}ƒ\[[ztlsre“““{tt{{t{||sre[[Tlddkk]””‹{||bVZ{{t{{tzll”š”f]c’ŒŒlek‹„„¦§¨¦§¨“““{tttsltt{ztl‹‹‹‹„„lek“Œ”ultŠ}ƒ{{tf]c’…‹‚|uddc›”›{{ƒj]\{u{f]c\[b™š¤Œ—£…‹‹|‚zlekƒƒ|mttlek„Š„ƒ„„œ¤¦]cdtts|‚zƒ}ƒ[[T{tt„Š„lddlld„Š„lldƒ}ƒ‹‹„ekd\[[dc\lri”››‹‹„ƒ„„u{{{u{ƒ}ƒllkmttf]clddddc››”MRK*)(VZTmttztl””‹™š¤™š¤””‹’ŒŒ””‹‚|uŠ}|‹’Š””‹””‹‹‹„¦§¨š””¦§¨›¢›Šƒ}‹…’¨©´›”›„„Š“““›¢›“““™š¤{{t‹’Š”››¦§¨¦§¨œ››£œ¥›¢›“““‹’Š|‚z“““ƒ„„lek‹’Š…‹‹llkƒ„„tsl|‚z…‹‹ƒ}Š[TTd\\{{ƒ{u{ƒ„„ƒ}Šf]cttstsl‹„„Œ‹“’ŒŒ‹‹„{tttslmttJHFlld‹„‹ƒ„„[[T{{ƒllkj]\VTLƒ||“Œ”“Œ”ldd|‚z{ttllkult¤¤’…‹|‚z‹„„{||ƒ„„MRKƒ‚utll””‹‹„„››”‰|vƒƒ|j]\‹„„ƒ}ƒlldsle‘Œ…ultttsƒ}ƒ””‹ƒƒ|œ¤¦”š”Šƒ}|‚zš””ƒ„„›”›‹‹‹ƒ„„Œ‹“…‹‹‹‹„ƒ}ƒƒ}ƒtt{“Œ”™š¤|‚z‹„‹‹‹„œ››ƒ}ƒ{ttƒ}ƒ‚ut‹‹‹rfkb[Utll“Œ”[[TlksbVZ“Œ”Š}|{tt‘Œ…”š”rg]””‹Šƒ}¤¤›¢›ŠŠ}ult‹„‹tt{tts‹„‹‹„‹‘ˆ}ŠŠ}£››‘…„lksrfkƒƒ|j]\{{tllkllk‹‹„‹‹‹ƒ}ƒ‚ut{u{lri„Š„Šƒ}ddckk]ƒƒ|{u{ttstll|„…lek‹‹‹b[U{tttts{zmuzt“Œ”‹„‹{tt“““uztztl”››lddƒ}Š{{ƒƒ}ƒ£œ¥¦§¨ƒ}ƒƒƒ|tsl[[Tƒ||ƒ}ƒtll“Œ”‹’Šyl„\UZ|„…œ§²„„Šƒ}ƒ[TT„„ŠVZTtlllri|„……„’‹’Štllztlrfkultd\\ult|‚zŒ”•ƒ‚u{tt{{t{{tlldŒ‹“{||]bZtzl‹‹‹‹’Š””‹{{ƒlekmttlldztl‹‹‹¦§¨dc\>EC‹’ЄЄ››”“““’ŒŒ“Œ”ttsœ››“““¤¤“““{u{Š}|‘Œ…£›››”›š””ƒ„„›¢›››”™š¤¦§¨“Œ”¦§¨Œ‹“ƒƒ|¦§¨¦§¨‹‹‹|‚z“Œ”{{ƒ|‚z‹’Š””‹‹„‹”››‹’Šuzt“Œ”ƒ}ƒSKJ|„…]bZVTLkd\lld]cd\[blek{u{{tt{{ƒ‹‹‹ekdlldult‘…„‘Œ…””‹{||Œ‹“›”›{tt{{t{ttSKJlld|„…™š¤‹‹„‹„‹„Š„£››lri‹„‹uzt|„…‹‹„‹‹‹{ttƒ||u{{u{{{{ƒ|„…“Œ”ulttt{lri›¢›‹„„››”‹‹‹²««‘Œ…”“›ƒƒ|zllttstts„Š„œ¤¦tt{…‹‹kk]‹‹‹¤¤£œ¥‹’Š‚utŒ”•Š}ƒ„Š„”››Œ”•”“›{u{…‹‹tllttsƒ}ƒ…‹‹™š¤™š¤„Š„tts„Š}œ¤¦‚v{‚|u…‹‹mtt“Œ”ldd[[Tlldsleztlult¨©´“Œ”’ŒŒ£œ¥llkƒƒ|lddš””ztlŒ‹“{{tœ››““““““mtt{tt{u{›”›‹‹„zll‚utš””„Š}››”{{tƒ||››”‘ˆ}ƒ||tsl››”{||‹‹‹sle‹‹‹“““[[T‹„„lldlriŒ”•{{ƒ‹‹‹{{ƒtt{{u{lks‹„„uzt{||sled\\SKJƒ„„[[Tuzt””‹{||ƒƒ|ƒ}ƒš”””“›{u{ƒ„„‹„„‹‹„‹’Š|„…’ŒŒ“Œ”tsl‹„‹|‚z{||ƒ|||„…lks]bZmttslemttedktsl¦§¨mttldd{{t”“›{||ultttsj]\„„Šllk‹‹‹lld{ttƒ}Šlek{{ƒŒ‹“tts‹‹„tll[[TmttŠ}ƒlek„Š„{||{{tlldlld²¬µ]cd-1+tsl‹„„››”ƒƒ|{||··Ä¤¤£››‹‹‹”𔦧¨ult²¬µ£œ¥ƒƒ|¤¤¦§¨¤¤ƒƒ|Œ”•š””Œ‹“¨©´’ŒŒª³·œ››µ¶·œ››š””¤¤”“›››””š”|‚z…‹’ƒ}ƒƒ}ƒ‹‹„œ¤¦ƒƒ|‹„„lddu{{uztllkŒ‹“”››tt{Œ—£‹‹‹lek{u{…‹š‹„‹‹‹‹ƒƒ|ztl››”ƒ‚u‹‹„{||{||ƒ}ƒ„Š}Šƒ}kd\‹„‹lld‹‹‹…‹‹„Š„{||u{{£››…‹’zll¦§¨lkstzlmtt‘…„‹„„š””tts“Œ”{||ldd{||…‹‹mtt|‚zƒƒ|œ››”“›ŠŠ}ŠŠ}ddcœ››‹‹„’…‹{zm|‚z“““{ttlriddcŠƒ}‹‹„Œ”•™š¤Šƒ}‹’Š›”›‹‹‹ƒ„„tt{{{ƒŒ‹“„„Š“Œ”{{ƒ¦§¨{{ƒ’ŒŒ‹„‹”š”tllttsfkktsl‹‹„…‹‹{||“““{ttƒ„„{u{d\\SKJu{{rfk‚v{™š¤Œ‹“‹‹„””‹zll{{tƒƒ|ƒƒ|{{tƒ‚u{||Œ‹“tts‹„„‹…’kd\tsl‹‹‹¦§¨ƒ||lek‚utƒƒ|ƒ„„‹‹‹””‹u{{ƒ„„ztl”š”””‹’ŒŒ‹’Š‹‹„sre{||]bZtsl{||tlluztuztsle{ttedkzll|‚ztsltllj]\zllslelld‹‹„Œ”•ƒƒ|’ŒŒ{ttƒ||tsldc\tsltt{lrikd\slered{u{lddddc‚|u\[bllk…‹‹mtt¦§¨SKJtsl„„Š…‹’lrib[Uedk{{ƒœ››ƒ„„ultedkƒ}ƒ|‚ztll”š”Šƒ}‹‹‹zll\UZllktt{ttslksmtttt{[[T„„Šultlri{{t„„Šlrisle\[b¦§¨LKR%&£››Œ”•£œ¥£œ¥™š¤£²£››¦§¨””‹„Š„‹‹‹ƒ}ƒ£››››”¦§¨››”¤¤{||ƒ„„‹’Šœ¤¦¤¤··Ä¦§¨¦§¨‹’Š£››…‹’ƒƒ|{{ƒ{tt„Š}{{ƒ{{tŒ”•”š”|„…Œ‹“Œ‹“‚|u››”tll…‹’|‚zVTLlddmttmtt…‹‹lks¦§¨ttsultŒ”•|‚z‹‹‹\[[¦§¨ztl‹‹‹d\\””‹tll‹‹„’ŒŒlld™š¤“““™š¤{{ƒtsl{{ƒsleŒ”•œ››™š¤“Œ”‹…’|„…lldƒ||{tt„„ŠUTSlek„Š„{zm{{ƒLKRekd„Š„‚|ukk]‹‹‹¤¤””‹Œ”•|‚zœ››{ttttsƒ‚u’ŒŒ‹„‹uztƒ}ƒƒ||””‹{{t{||‚|uƒƒ|šŒfkk””‹ƒ„„tts{||„„Š{||Œ‹“„Š„|‚z£››{||ttsu{{Œ”•lddlddd\\‘Œ…ttsŠ~‹™š¤[[T„Š„tsl‹„‹ƒ||’ŒŒŠ}ƒƒ}Š‹’ŠŠƒ}‚|u’ŒŒ{{t\[[¦§¨j]\lriSKJ£œ¥„„Š“““Šƒ}ƒ„„ƒ||Š}||‚ztzlƒ„„Šƒ}’ŒŒ‹‹„{ttŠƒ}lddƒƒ|{{tƒ„„”››tll{||¤¤lddrg]{u{”››lrilri\[[|„…„„Š‹„‹mtt{{t|‚z{{tVTLbVZztl“Œ”{{ttsldc\]bZllk‹„‹ƒƒ|ttsldd‹‹„™š¤{u{ƒƒ|tt{‹u…‹…’‚|u„„Š{||Œ”•[[TŒ”•œ§²{{ƒ\[b¦§¨Œ”•tt{‹’Šb[Umtt{{ƒ{ttrfk’…‹{u{UTSlritlltts”››ƒ}ƒult‹‹„{||ddclri‹„‹{||…‹’tsl|„…b[Utts‹„‹llk‹„‹[TT\[[¦§¨ek]FD;Œ”•””‹¦§¨œ¤¦ƒ}ƒ¨©´‹„„¦§¨µ¶·¦§¨¤¤’‘~£œ¥¦§¨¦§¨²²¬‹’Š“““ª³·œ¤¦™š¤‘…„œ¤¦Œ”•|„…‹‹„š””„Š„™š¤¨©´‹„‹”“›¦§¨““““Œ”››”{{t”“›‹„„ƒ||{tt’ŒŒ|„…lri{u{llklri“““\[[{{ƒ{||{u{dc\›”›‹’Š“Œ”””‹£››{tttslƒ„„zllƒ||{tt£œ¥Šƒ}ƒ}ƒ‹‹‹Œ”•‹„‹ƒ||‘…„sre‚utƒ„„›”›{||ddcƒ}Š…‹‹tts“Œ”›”›‹’Š„„Šƒ„„’ŒŒ‹„„Œ”•lrikk]š””llkllkš””‹„„lld{{t‘…„UMRttstslŒ”•ultŒ”•››”››”››”uzt„„Ф¤„Š}”š”{ttƒ„„ult‹‹‹”“›‹‹„lekekdlriddcu{{ƒ}ƒlldtt{uzttts{{t|„…ƒ}ƒldd‹„„ult›¢›Š~‹|‚zŠ}ƒSKJ{u{‚v{sre‹„„ƒƒ|ztlŠƒ}””‹ƒƒ|ƒƒ|ƒ||mttllk„„Š„Š}{tt‚v{ƒ„„Šƒ}ldd‹…’\[[’ŒŒ’ŒŒ¨©´””‹”𔋋„lldjcV‘ˆ}]bZkk]bVZ{ttƒ„„„Š}ƒ‚u{zm‹’ŠVTL‹‹„\[[|„…\[[f]clddekdƒƒ|sle{tt’ŒŒ‚utf]cVTLƒƒ|UTS“““œ¤¦‹‹‹’ŒŒ]bZztluztlri””‹dc\Œ”•’ŒŒƒ}ƒrfk\UZ“““|‚z„„ŠŒ”•|„…u{{{{ƒttsƒ}ƒ¦§¨¦§¨‹‹„u{{„Š„“Œ”Œ‹“¦§¨tt{u{{|‚zŠ}|lri”“›lddf]cVZT”“›{||UTS“Œ”ttsVTLtslŠ~‹‹„‹dc\ultu{{ultŒ‹“llk¨©´UTS)+2››”ƒ||ƒ„„ƒ„„𔔍©´¦§¨«²«›¢›™‹†››”‹„‹’ŒŒ””‹“““‹‹„™š¤››”ƒƒ|”›››”›”š”œ›››¢›“““™š¤”“›¦§¨Œ”•¨©´”››Œ‹““““”››””‹z‚l¦§¨œ››…„’{{tƒƒ|ƒƒ||‚z{{ƒ“““ƒ„„ddc{||lksƒ}Š‹…’ƒ„„“Œ”‹’Šuzt{{t„Š}œ››“Œ”‹„„{u{{u{‚utlddf]ctllztlƒ‚uVTLultƒƒ|d\\Œ‹“ultVTLƒ}ƒ{{ƒllkllk{tt‘…„£œ¥Œ”•‹‹„{u{u{{Œ”•‹‹‹‹‹‹‹‹„„Š„ztlŒ”•tts¦§¨š””“““‹’Škd\‹„‹JHFlriƒƒ|tll‹’Ц§¨›”›””‹¤¤Œ”•ƒƒ|ƒ||¦§¨œ››lldƒƒ|tll‹’Šsle“““Œ‹“|„…“““…‹’‹„‹ztl\[[””‹ƒ}Šš””{||Œ‹“‹‹„tt{ƒƒ|”𔋅’|„…zll{{tŒ‹“ƒ}ƒllkƒ„„‹„‹ƒ„„dc\‹‹„yleƒ‚u’ŒŒ‹„‹tllttsƒ}ƒ{tt„Š}uzt¤¤Šƒ}{tt{u{“Œ”ttsdc\{||””‹{{tllk‹‹„ztlztflddœ››lrillkddc‹’Šek]|‚zdc\|‚zdc\lddUTSf]clekred…‹‹¤¤[[T{{ƒ“Œ”‚|u{{t„Š}”››„Š„edkŠ}|’ŒŒ„Š„Œ‹“››”œ¤¦‹…šsre”››tt{{u{‹’Šlrimttuztddcekd”“›uzt””‹]bZ™š¤edk|‚ziq]lks{||sletll‚utultµ¶·{||uztu{{ƒ„„dc\tts‹„‹{{ƒŒ”•dc\‹…’tts\[[|‚zddc{ttuzt‹„‹ƒ}ƒ{u{”š”tll¦§¨\[bLKR|‚z…‹‹ª³·Œ‹“’ŒŒ“Œ”››”ƒ‚u–¢‹„Š}¦§¨‰ƒv’ŒŒ‹‹„¤¤|„…¦§¨››”ƒ||‹‹‹”››’ŒŒ£››‹’Ѝ©´£œ¥··Äœ¤¦‹…’¨©´¦§¨¦§¨„„Šª³·š””¤¤¤¤œ¤¦ƒ„„ƒ||š””ƒ||fkkƒ„„{{ƒ‹„‹{||””‹{{ƒ£œ¥“Œ”ƒ}ƒult{u{tslŒ‹“tt{””‹Š}ƒ››”‹„‹tslldd‘Œ…¦§¨’ŒŒdc\rg]llk{ttlldsle‚ut‘…„”››ultŠŠ}llk{||d\\“Œ”‚|u‹‹„›¢›™š¤Œ”•|„…{{ƒllkdc\]bZ‹„„ttslek‚|u‘Œ…ldd«²«Œ‹“{u{ƒ}ƒcbV”š”ƒ„„{||””‹’ŒŒ¤¤‹‹‹š””{ttƒ‚u¦§¨„Š„‹’Ѝ©´{ttŒ”•‹‹‹‹„„£œ¥”“›‹‹‹{||{{ƒ‹‹‹…‹‹ƒƒ|‹‹‹|‚z{u{…‹‹ttsult{||fkk\[[Œ‹“u{{‹‹„Œ”•{u{{ttƒƒ|“Œ”{tt{zm{tt‹‹„‚|u””‹ƒƒ|ldd\UZ‹’Š“Œ”‹’Š“““sle’ŒŒd\\kd\{tt{{tlldmtt]bZekdttsƒ„„šŒƒ}ƒbVZŠ}ƒ…‹‹llklldkd\SKJddc{u{ztlllktzlb[U{u{{tt{{tu{{lriƒ||r]g¦§¨ƒ||¦§¨”š”…‹‹ƒ‚u‹‹‹›”›cbV””‹‹„‹|‚z„„Š‹’Š›¢›œ¤¦‹„„ƒ}ƒ””‹„Š„‹’Š|„…|‚zekdœ§²|‚z|‚z‹‹‹mttuztƒ||d\\UMR›¢›‹’Šƒ||lksf]c››””››{{t›¢›]bZŒ”•‚|u“Œ”uztmtt[[Tttslri|‚zdc\JHFƒ}ƒtllƒ}ƒ[TT{ttultd\\¦§¨MSSLKRœ¤¦›”›”“›£œ¥‚v{ƒ||’…‹””‹¦§¨¦§¨¤¤²¬µ“Œ”¦§¨ƒƒ|“““tzlª³·‹’Ѝ©´‹’Š£œ¥Ÿ±¯¦§¨¦§¨”“›…‹‹¦§¨£œ¥””‹™š¤…‹‹ƒ„„“““‹‹‹™š¤””‹’ŒŒ…‹‹‹…’edk‘Œ…\[bŒ”•ƒ}е¶·lks™š¤œ¤¦„„Š‹„‹‹…’ƒ||œ¤¦ƒ||Œ‹“llkztl’ŒŒ|‚z„Š„{{t“Œ”ƒ||’…‹lld‚|u’ŒŒtsl{||…‹‹Šƒ}‹„„sleu{{’ŒŒ‹‹„|‚z\[[ttsƒ‚u“Œ”ƒ}ƒekd‹‹‹llkœ¤¦tt{ddctzltsljcVƒ||¤¤œ››‘Œ……„’‹‹„‘…„‹‹‹{||›¢›|‚z“““‹’Š‹„„zllŠ}|ƒƒ|{tt’…‹‹’ŠŒ‹“u{{“““‹‹‹zll’ŒŒƒ„„{{tŒ‹“„Š„‹„„”“›ƒ||{tt”“›ƒƒ|tt{tsltts›¢›tllŒ‹“tt{tt{\[[“““ultllkƒ}ƒlks¤¤„Š„‹u…{{tƒƒ|››”Œ‹““Œ”ƒ}ƒtts{u{ƒ||ttsœ››””‹”“›‘Œ…ƒ||Š}|{ttsle{tt[TTkd\tsl{u{ƒ„„{{tŒ‹“kd\””‹{u{‚v{JHFŠ}|ztllri‹‹„{ttultbVUdc\{u{lekŠƒ}ttstts‚utƒƒ|ƒƒ|{{ƒ‚ut«²«›¢›„Š„{||„„Š‹„„‹‹‹ztlƒ„„|‚z£œ¥‹’Ц§¨Œ”•sleƒ„„š””|„…tzlŒ—£…‹‹Œ”•|„…]bZ|„…]bZu{{\[buztJHF\[b{tt]bZyle\UZŒ‹“{||tllredVZTek]fkklddlekedk|„…ttsu{{]bZ]bZ|‚z‚v{ultƒ„„‹‹‹ƒƒ|ƒ||sle\[b¦§¨MRKUTS|„…cbVƒ„„£œ¥“~ˆ‹„„””‹Š}ƒ|‚zƒ‚n’ŒŒš””sle|„…{||“““¦§¨›¢›¦§¨¨©´£›››¢›«²«lld‹‹‹«²«œ¤¦”“›“““œ››Œ”•¡¡’ŒŒª³·”“›llk‹‹„lri‹’Š‚|u{||‚|u{{ƒŒ”•ult‹‹‹{{ƒƒ}Š{{ƒlkslldd\\‚utƒ}ƒƒ}ƒztl‹‹„‚ut‚v{‹‹„lek‚|ured’…‹{u{{u{{ttŠƒ}lddldddc\sle‘…„›”›‹„„ƒƒ|¦§¨|‚z\[[{||‹„„ult‹‹‹{u{\UZllkƒ„„f]cf]ctzlsreSKJƒƒ|tzl[TT‚ut‹…’sle‚|u“Œ”[[Tƒ‚u””‹”“›™š¤››”›”›¦§¨¦§¨{||‘…„tsltsltsluzttts’…‹ƒ}Šš””š””„„ŠŒ”•‚|uƒ}ƒ›”›uzt™š¤š””ƒ„„ldd‹’Š{{tlddŒ”•ƒƒ|ƒƒ|ztlƒ}ƒf]cuztultœ›››”›Œ‹“””‹‚|u|‚ztslœ¤¦ƒ„„ŠŠ}¦§¨ult“Œ”””‹”››ƒ„„”››’ŒŒ‘…„ƒ}ƒŠ}|ult{||d\\“Œ”Šƒ}ultƒƒ|{{tƒƒ|‚|u‘…„yle{||‚|usle{{t¤¤ƒƒ|ƒƒ|tsllldFD;uztllktzllld\[[lldƒ}Šdc\bVZSKJtzlztl‹’Šlriultztl“““kd\””‹¦§¨›”›ª³·{{tkk]ztlŒ”•tsl…‹‹uzt„Š„u{{mtt‚v{u{{{||lksddcllkMSSlldult‹…š„Š}{{tUMRf]clektll”š”{{tlld{||u{{„„Štll\[[dc\]cd]bZlri‹’Š‹„‹„„Š‚utultŠƒ}Š~‹UMRf]c£››JHF?;C„Š„„„Š“Œ”£››‹„‹ƒƒ|‹‹„’ŒŒŠŠ}””‹Šƒ}Œ”•¸Á¹¦§¨¦§¨›¢›”𔦧¨œ¤¦œ¤¦¦§¨‹„„œ¤¦‹’Š‹uŠƒ„„…‹‹“““¨©´¦§¨Œ”•…‹’Œ‹““Œ”ŠŠ}’ŒŒœ››|‚ztsl‹„‹£œ¥‹„„uztUUY¦§¨Š}ƒlksultlksmtt…‹’ƒƒ|ƒ||œ¤¦{u{ƒ}ƒ{{tƒ||“Œ”|‚z”››“““‹„‹‹„‹‹‹‹Šƒ}ldd†~‘{u{™š¤‹‹‹“Œ”””‹cbV{{tƒ‚uƒ‚u{zm‹„„j]\‹’Šƒ||¦§¨ttstts|‚ztllf]cƒ}ƒƒƒ|lrilriƒ‚ulri„Š„{tt{||zll‚ut‹„‹““““““ƒƒ|›”›™š¤’ŒŒ‘…„¦§¨ƒ||””‹ƒ|||‚z{u{{{ƒ”š”ult‹„„’ŒŒƒ„„tll„„Š‹’Š’ŒŒ{u{’ŒŒu{{“Œ”ƒ„„tsl{{t…‹‹ƒƒ|ƒ„„tllf]cƒ„„”“›“““{{ƒƒ||{tt{{ƒzll\[[ƒ||‹„„{||ƒ‚uu{{b[Usle‘…„jV[‚|u‹‹‹ƒ„„””‹ƒ„„ztlŠƒ}œ¤¦š””tts““““Œ”Œ”•‚v{ƒ}ƒj]\‰|v‘…„””‹¤¤‘…„{tt{tt‹‹‹[TT‚|u£œ¥Š}|ylett{sreƒ||tll‹‹‹‘Œ…lddiq]{u{‹…’|„…ƒ||kd\{{ttsl„„Šf]ctll{u{b[Ulksztl|„…™š¤uzt{{t‹„‹mtt{||\[b|„…lks…‹‹UTS“Œ”{||\[[|„…lkssle\[bllk\[bUMRttsuzt\[b{{ƒlekdc\tt{ƒ‚u‹‹„\[[{{tƒƒ|[[T”š”{{t|„…{{tultlddƒ}ƒtll™š¤”“›››”lddbVZldd¦§¨\UZJHFlks|„…‹„‹£œ¥™š¤‚|uŠƒ}”š”””‹””‹””‹«²«¤¤¤¤””‹œ¤¦¦§¨‹’Ѝ©´«²«µ¶·›¢›{{t””‹¨©´œ¤¦Œ”•”››Œ”•’ŒŒ‹‹‹Œ‹“™š¤¦§¨|‚zœ¤¦‚|u‹’ЄЄyleult¦§¨]cd{{tlekultŒ‹“edklksu{{|„…”š”dc\„„Šlek”“›{||¤¤‹„‹{{tlri{ttŒ‹“’ŒŒ¨©´ultlddUTS¦§¨ƒƒ|ƒ„„ƒ||”››sleddc\[[lriƒƒ|lek[[T{tttll‚|u„Š„ƒ„„|„…uztJHFlkscbV|‚zllk””‹|‚z„Š}””‹””‹Š}|kd\ƒ„„Œ”•|‚z‹‹„tll„Š}‹„‹›”›²««“Œ”¤¤tll„Š}Œ‹“š””‹’Š{{ƒ‹‹„ƒ||{tt“““’ŒŒƒƒ|“Œ”’…‹‹„‹ddcult“““‹„„””‹‹’Š„„Štll[TT“Œ”„Š„{u{ƒ„„ƒ}ƒœ››ƒ}ƒ²²¬’ŒŒ|‚z„Š„ƒ‚n„„Š”š”{||{{t‹‹„lddmwŠ}|‹‹‹|„…“Œ”ƒ„„Šƒ}ylebVZŠ}|œ››ekdƒ}ƒ{ttkd\zll{ttš””‹„„’ŒŒ‹„„‘…„››”’ŒŒ{u{ult“Œ”‘…„[TTƒ}ƒ[TT„Š„lri{u{{ttŠƒ}mtttt{‹‹‹ultllkztlUTS£››tll…‹‹›”›‹„„“Œ”{tt{tt[[Tllkš””\[[››”‹„„ttsLKR[TTtzl\[[SKJmtt|„…mttœ¤¦ddcu{{lekœ¤¦dc\ult’ŒŒ“““‹„„lks{u{ult[[Tœ›››¢›‹’Štzl{{tƒ}ƒfkkfkkƒƒ|{||uztƒ„„uzt{tt{{tŠ}ƒult£›››”›kd\tll£››JHF*)(”››“““‹„„‘…„‹‹„”“››”›””‹|‚zz‚l£››œ››œ››“““›¢›··Ä«²«ª³·¦§¨µ¶·«²«œ››²²¬Œ”•‹’Šœ¤¦£œ¥œ¤¦‹’Š”š”œ¤¦”“›Š}|¦§¨œ¤¦œ¤¦Š}ƒŒ”•‹‹„lldƒ}Šult„„Š””‹Œ‹““Œ”{u{„„Šllk|„…›¢›‘…„“““lri{tt“Œ”””‹‹„„š””””‹“Œ”ƒ||‚ut£››œ››””‹‹„‹ddc„Š„ƒ||„„Š’ŒŒ‹„‹{u{f]c[TTlldcbVŠ}ƒUTSšŒ‹„„’ŒŒƒ‚n[[Tlrikd\{{ƒlri{{t‹‹„lri{zm{tt›¢›ƒƒ|“““zll{{t‹‹‹‹‹‹“““Šƒ}|‚zƒ||ƒ„„‘…„¦§¨’ŒŒ{{t‹…’ƒƒ|œ¤¦Šƒ}””‹”“›‹„„‹„„fkk‚ut“““tslult‹‹‹œ››u{{ƒ}ƒ”š”‹’Šƒ}ƒddcŒ‹“tt{ƒ||lddlddƒ„„{{ƒd\\ult‹‹„‚v{{tt››”lri‚ut|‚z„Š}uztztlzllƒ||tlltts𔔦§¨‹’Šuzt‚|u›”››”›lddztl„„Šttsƒ||lek‚|uttsek]ƒ||Šƒ}“Œ”‘ˆ}£››š””ŠŠ}“““lekƒ||ztlsle‚wl‹„„dc\uztztl{ttuzt„Š„‹’Š„„Š“““‹‹„|‚z¤¤Œ‹“ƒ„„llkldd„„Š“““‹‹„œ››u{{ƒƒ|{{t]bZ{u{SKJUMRmttSKJ]cd]bZ|‚zŒ”•mtt‹’ŠŒ”•lri„„ŠMRKƒ}ƒf]clldJHFdc\UTSd\\mtt|„…tll‹„„‹‹„lriekdlriƒƒ|\[[tlltt{dc\lridc\{u{{{ƒlddlektllƒ}ƒd\\ldd¦§¨JHF$›¢›ƒƒ|”“›’ŒŒ”š”£œ¥™š¤‘Œ…””‹¦§¨””‹¦§¨¦§¨š””¦§¨œ¤¦ª³·¨©´¦§¨µ¶·‹’Šœ››£››‹’ŠŒ”•”››Œ‹“”››œ››lek‹’Й𤋋‹¦§¨ª³·…‹‹’ŒŒ„Š„tsl{{t£œ¥‹…’\UZUTSƒƒ|{ttlri|„…lri|„…z‚l’ŒŒ””‹„Š„„„Š‹‹‹tll“Œ”‹„„›”›‚utŒ‹“‰ƒv£››Œ”•””‹ƒ„„{||tts‹„‹sle¦§¨ƒ„„bVU‹’Šldd|‚zdc\ƒƒ|j]\dc\redzlluzt”š”ttsJHFlek{{ƒsretsl{||Œ”•œ››››”{zm{||Šƒ}sleultƒƒ|uztŠŠ}tts”››ƒ||ult¤¤œ››tzl{||‹’Š”š”„Š„”š””š”‹‹‹››”tt{ƒƒ|lri…‹‹‚v{{u{ƒ|||‚zmtt‹„„ult‹…’ek]š””{u{tts‹‹„“Œ”zll’ŒŒ“Œ”‚v{‹‹‹lekƒ‚utslcbV|‚zuztkd\ƒ„„„Š}zll’ŒŒ£œ¥Šƒ}tsl|‚z„Š„“““‚|u‚v{’ŒŒ‘…„red„„Š{{ƒ“““r]glrilld{u{{u{Š}|[[Tkd\‘ˆ}‚|u‹‹„|‚zj]\lddf]ckd\{u{Œ‹“Šƒ}[TT‹‹„dc\|„…‹‹‹ek][TTlld{{t{||¦§¨“““{u{ult¦§¨¦§¨›”›{||›¢›|„…mtt{{tUTSddc|‚zŒ‹“\[blri””‹‹’Šmtt™š¤uztŒŒšlriu{{leku{{lksŒ‹“mttlri{{ƒ{||{{t{{ƒ|„…zllddcttsuztllk„„Šuzt|‚zlekdc\ztl{u{ultƒ„„ƒ}ƒŠ}ƒ{tt“Œ”{||ttsult¦§¨VZT*)(”››“Œ”””‹‚|utsl’ŒŒ‚wlŠŠ}””‹¤¤µ¶·””‹£››››”£››ƒ„„””‹¦§¨£››¤¤»ÂǤ¤¤¤œ¤¦|‚z‹’Š··Äœ¤¦„„Šƒ||Œ”•œ¤¦…‹‹››””››tzl””‹œ¤¦“““|‚z“Œ”‹„‹|„…|‚z™š¤[TTVTL[TTlriu{{‚ut‚v{tllŒ”•”“›””‹’…‹ƒ||‚v{Šƒ}Š}ƒzll£››Š}ƒƒ„„lld{{tlld”“›lekyfd†~‘ƒ}ƒkd\tsl{tt’…‹””‹{{t{ttƒ||‰v|uztllklddŒ”•cbV{u{SKJlri|‚z‹‹‹tzldc\””‹‹‹„“Œ”‘Œ…‘…„{u{{zm‹’Š{tt„„Š””‹{ttŠƒ}tsltsl|‚z›”›|‚z””‹‹’Šƒ‚uŒ‹“tsl‚|uttsƒ||‹‹‹ŠŠ}ultult|„…ttsuzt{{tƒ}ƒ‚|utsl‹’Š{{ƒtlltts{{t™š¤²««‹„‹ult|‚zdc\tslƒ„„‚v{ƒ||{{t”š”œ¤¦‚|u£››“Œ”‹„„‚ut{{tuzttzl{zmŠ}|‚|u‚|u’ŒŒš””„Š„uztƒ||“Œ”‹„‹Š}ƒ|‚ztllztfb[Uekdttsj]\ƒ‚u|‚zllkŒ‹“{u{Š~‹{u{{||ƒ||[[T”š”ƒƒ|]cdUTS‚|uf]cbVU‘Œ…b[U{{tj]\Œ”•llk{||Š}ƒ‹‹‹‹‹„{tt[[T[[Td\\llk“Œ”|‚z{tt{{ƒ|„…Œ”•lksŒ”•ª³·œ¤¦{{ƒ‹’ŠMSSlriVTLbVUf]cUMR>B9ƒ||ª³·“Œ”|„…]cdtts]cd|„…ek]™š¤„Š„Šƒ}…‹‹{{t|‚z{tt’ŒŒb[U‹„‹{u{ult{tt’ŒŒr]Z‹„‹{ttœ››MRK*)(””‹²¬µ£œ¥””‹ultmw””‹Ä¿¤¤””‹›¢›£››²««””‹£œ¥¦§¨¦§¨£››£››¦§¨²²¬‚wl‹‹„””‹›¢›{||£œ¥œ¤¦‹„„¦§¨‹„‹{ttllk¦§¨“““Œ‹“ƒ‚u„Š„’ŒŒ|‚z¤¤‹‹‹…‹’FD;„Š„ultu{{u{{fkkUTS{ttzll‹„‹…‹‹ƒ}ƒ‹‹„š””d\\{u{lld‹„„Š}|ƒ||‹‹„ƒ}ƒuzt{ttkk]ƒ„„UMRrfk‚utttsSKJztlrfk””‹tsl\UZ“““‹’Š‘Œ…‚wlllkttsb[Uldd{||{||¦§¨kk]ƒ}ƒek]|„…””‹‹„„‹‹„š””ult“““‹‹‹lld”š”llk{ttƒ}ƒslesle{tttsl{u{”𔫲«¤¤”š”ƒ„„Šƒ}Š}|‚ut‹‹„“““ƒƒ|’ŒŒuztƒ„„u{{{{ƒ{{tƒ}ƒlri‹’Š“““ƒ||ttslriƒ„„”“›Œ‹“ult{tt{{tkk]{{tultttsllddc\{{t{zm{{tj]\zll‚v{‹„„{u{tllƒƒ|tzlb[U{{tŠ}|š””tllŠ}|œ¤¦ƒ}ƒult“Œ”£››Š}ƒlrilri“Œ”VTL{zm‚|u‚|u“““›¢›ultlddzll‘…„ztlf]ctts|‚z{tt{||uztlldtsl{||fkkek]tts{zmddctllš””VTLultuztbVUlriuztekdŒ”•””‹¦§¨Œ‹“f]c‹’Š…‹‹…‹’”››œ¤¦ttstt{u{{UUYJHF]bZƒ}Š{{ƒ[[Ttsl{{ƒŒ”•‹’ŠmttŒ”•‰ƒv{{tldduztttslriuztuzt{zmƒ„„llkf]ctllkd\ldd‚v{rfkztl‚v{leklek«²«JHF,55llklksƒ}ƒ””‹š””£››¤¤››”|‚z¤¤’‘~µ¶·²²¬²««š””¦§¨¤¤‚v{uzt„Š}¤¤£››¦§¨‹‹„|‚zœ››œ¤¦”“›{ttœ››ƒ||ztl‹‹„‰|v\[[lritlllld{{t{{tƒ„„Š~‹…„’tyguzttll‹‹„|‚zŠ}ƒ{||rg]‹‹‹kk]‹‹‹‹‹‹ƒ}ƒƒƒ|ult‹„‹ƒƒ|›”›‘Œ…“““œ››Œ‹“tsllekŠƒ}‚v{zll[[Tb[Uultrfkƒƒ|‚|u{u{„Š}£››”“›{{ƒŠ}|{u{…‹‹ƒ}ƒ‹‹„‹„„ƒ„„tt{jcVi\Vƒ‚uƒ||ƒƒ|›¢›¦§¨“““””‹‹‹‹{u{ƒƒ|sreztf{u{‚|u|‚z‘…„{zm|„…tsl‹‹‹‹’Š|‚z…‹‹›”›|‚z“Œ”ƒƒ|ƒ}ƒ”“›œ¤¦ƒƒ|tll{{tŒ”•Œ”•Š}ƒŒ”•Š~‹{u{‹’Š’…‹ƒ}ƒfkku{{tll’…‹ult{ttš””\[b{{tƒƒ|sleƒƒ|lektll|‚zƒ‚u{u{‚|u£››£œ¥‹‹‹ƒ}ƒ‹’Š”››{||tsltslrg]ƒƒ|sle’ŒŒ“““{{tƒƒ|“Œ”tsl’…‹››”kk]ult‹„„ƒƒ|ƒ||lld‹‹‹ƒ}ƒ‚ut{||bVUrg]kd\lek£››ƒ||tslƒ„„uzttts{u{z‚lmtt{zmztlj]\tts{{ƒ‘…„ŒŒšz‚lekdtll|„…„Š„„Š„yl„]bZ‹’Š‚|u{||‹’Š‹‹‹Œ‹“Œ‹“‹‹„¨©´fkk|„…\[b„„ŠUTSD;9lksmtt‚|u{{ƒlks”š”mtt{{ƒŠ}ƒ’ŒŒ“Œ”‹’Š‹‹‹{||tts‚uttsltt{|‚ztlllekredf]cf]cƒ}ƒ{ttŠƒ}tlltll¦§¨MRK*)(ƒ„„ƒ||¦§¨¦§¨£››²²¬¦§¨‰ƒv¦§¨µ¶·ÃÄÆ¤¤µ¶·“Œ”””‹”š”£œ¥¦§¨µ¶·››”””‹‹„„‹‹‹œ››“Œ”tts¦§¨™š¤²²¬””‹¤¤‹’Š”››Šƒ}ttsVTLtts”𔋋‹uzt{ttttsƒ„„]bZƒƒ|¦§¨uztllk„Š„{{tztlƒƒ|‹‹‹Œ”•uztd\\lddƒ||‚|uztlŠ}ƒ””‹‚utedk„Š„tts“Œ”lld’ŒŒldd™š¤Šƒ}„Š}‹‹„Šƒ}f]c‹‹‹{{tldd„„Š‹‹„™š¤‚uttts[TTSKJŒ‹“lriekdƒ‚uŠƒ}tts‰v|“Œ”²¬µ¤¤¤¤£››‹‹‹ƒ}ƒ™š¤ƒ‚ukk]‹„‹””‹ƒ||‹‹‹››”‹’Šztlultƒƒ|‹’Š””‹‹„„“Œ”ƒ}ƒŠƒ}{||ƒƒ|Œ”•{ttlrikk]{u{…‹‹¨©´ƒƒ|tll{||Œ”•‹‹„ƒ}ƒ{||u{{‹„„{{tult‚|uƒ}ƒ”š”””‹tsl””‹œ¤¦‚v{›”›{{trg]{{t‘Œ…ƒ||›”›‚ut“Œ”“Œ”››”{{t’ŒŒ’…‹d\\ttskk]’ŒŒ”“›‰‘~¦§¨ttsŒ”•œ››‰|vsre››”‚|u{{tdc\kk]ƒ||ƒƒ|d\\{u{slered{tt{tttll\[[{u{lld{||VTL{tt|„…ttslldztl’ŒŒŒ”•lks{||‹„‹lritts‹„‹Œ”•uzt™š¤lddtll|‚z”››llk{||ƒ„„‹’Š’ŒŒ‹’ŠVZT\UZlrislef]cu{{{{ƒ‹…štlldc\UTSlri‹’Šlks…‹‹ƒƒ|‹„‹{|||„…œ¤¦{|||‚zddctslƒ}ƒekd{tt[TTƒƒ|{tt{u{Šƒ}{tt››”Šƒ}dc\µ¶·JHF*)(„Š}“Œ”œ¤¦‘ˆ}””‹£œ¥‘Œ…£››””‹»ÂǦ§¨²²¬²««²««¦§¨¦§¨œ››¨©´›”›£››“““ƒƒ|ƒ||tzl™š¤…‹‹ƒ}ƒ‹’Ф¤¦§¨£œ¥ŠŠ}ƒ‚u¦§¨uztuzt“Œ”››”ƒ}ƒ‹‹‹tslttsŠƒ}ddc‹’Š|‚z„Š}|‚zlridc\ƒ||ttsuzt„Š„ƒ||ldd{u{d\\zll£››š””œ¤¦¦§¨¦§¨¦§¨ƒƒ|‹‹‹”š”{{ƒ²¬µ’ŒŒ£››‘Œ…‹‹„tllƒ}ƒtts…‹‹„Š„‹„‹yleš””tllƒƒ|mttVTL’ŒŒtt{”“›ƒƒ|kd\ƒ„„ƒ‚uVTL’ŒŒ‚|u‚wlš””tt{‚|ullkdc\tslult‹„„ƒ||‘Œ…‘Œ…‹‹‹jcVmw{zm¦§¨£œ¥‹…’™š¤‹’Š›”›{u{{||‹‹„“““{u{‹‹‹Œ”•Œ‹“{||‹‹‹ƒ„„{{t‹‹‹tslƒ|||„……‹‹{||‹„„›”›ƒ}ƒ‹„‹tts‹‹„|‚z{zm¤¤tll{u{ƒƒ|{{t›¢›{{t””‹ƒ||ƒ||{{t‹’Š|„…‚|uŠ}ƒyleƒ||red„Š„””‹ƒ||’ŒŒ‘Œ…””‹ƒ„„dc\uzt””‹‹’Šƒ||slekd\mtttzl\[[ultƒ||’…‹‘…„sle“Œ”ƒ||‹‹‹ƒ„„|‚z„„Š{{tb[UtllŒ”•„Š„lld…‹‹”“›ƒ||””‹„„Šœ››|„…ztlœ››„Š„Œ”•’…‹lddŒ”•tts„Š}|‚zmtt™š¤”“››¢›{tt{{ƒmtt””‹|„…Œ”•tt{ƒ}ƒred‚v{lksŒ”•ekdleklksztllek„„Šuzt„Š„dc\[[Tekdlekƒ}ƒlld{||[TTtlllddlek{tt‚ut„Š}Š}|]bZ··ÄJHFF=C‹„„Š~‹””‹²««²««£œ¥””‹ƒƒ|‰‘~¢—£››ƒƒ|šŒ‘…„‘Œ…š””²««››”²¬µ··Ä“Œ”œ››Œ”•›¢›llk“““‹‹‹{tt››”£››Š}ƒ‹„„¦§¨ŠŠ}‹‹‹„„Š…‹‹lritts‘Œ…‹‹„tsldc\ttsƒƒ|\[[[[Tkd\VTL[[Tr]g‹‹‹‹’Šek]“Œ”{ttlldllk‚ut”𔋄„ƒƒ|‹’Štts„Š„‹‹‹zlldc\{||“Œ”rfk¤¤”“›››”„„Štsl‹’Šƒƒ|‹’Š“““‹‹„ƒ||tllllktzlƒ||‚wlŒ‹“{||redsleSKJ{{tƒƒ|zllsletsl{zmlekf]c„Š„rg]„‰vttsŠ}ƒ{||š””””‹¦§¨‹‹„””‹sle|‚z””‹“Œ”“Œ”‹’Šƒ}Šu{{{tt¤¤‹„„‚utƒ}Štt{ƒ}ƒllkllkƒƒ|“Œ”lld‹‹‹{tt”“›”››‹‹„{ttult‹‹„‹„„f]c›¢›ƒƒ|ƒ‚u‹‹„ƒ„„‹„‹›”›‹„„¤¤ŠŠ}sre£œ¥{||‹‹„„Š„‚|u{tt‹„„llk{tt””‹JHFtts{zmrg]{{tŒ”•ƒ„„{{t‹„„¦§¨£››jcVdc\sre]cd{{t¤¤¦§¨“Œ”š””‚uttts‚utœ››Œ‹“‹’Š[TTddcsref]clldult‹’ЄЄ™š¤u{{›”›kk]“Œ””“›ª³·ztl„Š}‹’Šult“Œ”Œ‹“u{{š””„„Š‹‹„|„…‹’Š“““lri]bZlldfkkVZT]cdllk{ttŒ‹“‚|u‹„„VZ[mttŠƒ}‹…’llkŒ”•{ttmtt]bZedkdc\{||fkk{u{lddzll{{ƒtllultyfdred››”ldd‹’Šƒ||ƒƒ|¤¤JHF*)(tsl’ŒŒ”𔲲¬¢—š””””‹’‘~‚wl””‹¦§¨‘Œ…£››¤¤“Œ”²¬µ¨©´²¬µ“““œ¤¦¦§¨£œ¥«²«‹‹„“““™š¤‹‹‹„Š„¦§¨‘Œ…£œ¥¦§¨‰|v¤¤™š¤u{{‹‹‹››”Šƒ}¦§¨{||dc\uzt„Š„]bZ{||ƒƒ|‹’Štzllriƒ}ƒŒ”•‹‹„Œ‹“‚|u{tt{ttƒƒ|‘Œ…Šƒ}kd\r]gztl¦§¨tsl{||llkVTLtt{‹„„‹„„Šƒ}uzt’ŒŒ„Š„‹„„{||sre{{tƒ„„‹‹‹sle’ŒŒtslƒƒ|“““lddtt{{{ƒkd\sre‹„‹|‚z‹‹‹tllƒ||{zm„Š}f]cVTLztl‰|v’ŒŒŒ‹“sle„„Šœ¤¦ƒ‚u‹’Šƒƒ|£››‹’ŠŠŠ}“““Œ‹“”“›…‹‹’ŒŒmtttsl››”›”›‹„‹Œ”•ultd\\lks‹„‹“““ldd|‚z‹„„™š¤™š¤tts‹‹„‹„„Š}ƒtsl[TTƒƒ|{zmdc\ztl‹‹„‹„‹{tt‚|u¦§¨ŠŠ}””‹{{tult{ttlri„Š}”“›zllult‹‹‹tll‚|u””‹f]cultŠŠ}Œ”•sreŒ”•””‹«²«’…‹“““ƒƒ|lddredSKJtslcbVtllƒ||ƒ||sle£œ¥‹„‹VTLb[Uddc‹‹‹|„…tll‹„‹{{tllkuzt|‚zSKJlri{||‹„„£œ¥“““‹‹„¦§¨{tt›¢››”›‹„‹’ŒŒlriŒ”•{{ƒkd\¨©´Œ”•™š¤uzt„Š„ŠŠ}JHF|„…lriƒ}ƒf]c\UZ]bZult|„…ƒ}ƒƒ}ƒ’…‹lkslrimtt|‚zttsSKJlriuztedklksƒ||ƒƒ|tts‹‹‹ttsrfkd\\{u{Š}ƒ‹‹„Š}ƒ{||£››:97*)(œ¤¦’ŒŒŠƒ}²««²««²««š””¦§¨””‹‘ˆ}µ¶·²««“Œ”²««²¬µ²¬µ¦§¨™š¤‹‹‹¤¤ƒ}ƒ¦§¨“Œ”“““œ¤¦”“›Œ‹“››”¦§¨””‹£››“Œ”llk²²¬{{tuzt£œ¥ƒ„„tll£œ¥¦§¨Œ”•|„…‹’Š|‚ztzl‹’Š‹…’lri””‹ƒ„„”“›{zmŒ”•””‹{tt{ttƒƒ|Šutztltsl››”Šƒ}“““‘Œ…{||{zm{||„„Š{{ƒ{u{ƒƒ|uzt{{tVTLf]c|‚z‹‹‹{||ƒ„„d\\£››£››{zmdkV[[Tddc‹’Šƒ}Š‚|u[[Tƒ„„{{ƒ„„Š{ttsleƒƒ|ƒƒ|f]c{u{ƒ„„”››š””Š}ƒ’ŒŒ{ttŒ”•‘Œ…””‹£››¤¤¤¤‹‹‹’ŒŒ“Œ”ƒƒ|‹‹„œ››tsl“““‹„„‹‹‹tt{ult‹…’zllddc’ŒŒ{ttƒ||{{tu{{‹’Š”“›‚ut‚|u“Œ”Œ‹“tll{zm„Š„ƒ||ƒƒ|‚wl“““‚v{šŒyl„›”›””‹‘Œ…Š}ƒ{ttsleŠƒ}{{t{tt›”›ƒ„„{ttlddekd‹‹‹‚ut„Š}””‹””‹{{tµ¶·“““¦§¨’ŒŒ”››„Š„redkd\VTLsleldd{||‚|u{ttŠŠ}|‚z{tt‘…„ƒ„„lldlriztl››”‹„„{{tVZ[‹’Štts]bZ{||Š}ƒ‹„‹tllŠƒ}{zm{tt{||””‹‹‹‹‹„„‹„„ztlfkk“Œ”rg]Œ”•™š¤tt{mtttsl”“›ddc…‹‹MRKlkslriƒ}ƒtlltts{{ƒ“Œ”{{ƒŠ}|Œ”•{||ekduztttsedk””‹lrilksŒ‹“ƒƒ|lri[TT{{ƒ{u{ƒ||kd\{tttlltts{{t‹’Š””‹:97*)(£››¦§¨””‹’…‹£››ƒ||£››ŠŠ}‘ˆ}››”””‹£››²¬µ²¬µ²««£œ¥²¬µ™š¤£››”››ƒ||““““““µ¶·„„Д𔦧¨››”››”Š}ƒš””ƒ}ƒ”š”„Š}¦§¨ƒ}ƒ£››‹‹„Š}ƒ‚|u‹‹‹|‚z‹’Š[[Tkk]|‚z¦§¨“Œ”|‚z„Š}¨©´”š”{zm|„…›¢›£››‹„‹‚|uztl‹‹„‹„„””‹””‹Œ‹“ƒ‚u|‚z‹‹‹{||f]cttstll{{t‹’Škd\ƒ„„“Œ”’ŒŒtzl„„Šf]c\UZ‘Œ…{{t‚ut{tt|‚zekdƒ}ƒttsz‚lrg]‹…’’…‹ƒ‚uƒ||››”‹’Š””‹ƒ}ƒ‹„„‹„„{||‚utf]c‹„„{||lddkd\tll¦§¨sle‹’Š|‚zƒ||{||„„Šƒ„„{ttttsŠŠ}š””ƒ||„„Š‹‹‹£²’ŒŒŒ”•œ››ƒƒ|{u{|‚z|‚z]cdtts{{ƒ‹„„„„Šƒƒ|ƒ„„ƒ||tts’ŒŒ‹„„””‹‹’Štts”“›ult{||””‹ztl‚wl””‹zll„Š}{{t‹‹„œ¤¦£››ƒ„„\UZ””‹‹’Š{{t{{tš””››”ƒ‚n{||…‹‹‚wl“Œ”ldd‘Œ…{zm{u{mwzllbVUkd\lddslef]c[[Tredtlluzt{zm\[b‹„‹””‹j]\ƒ„„VTL|‚z{{tVTLlri{tt‘…„\UZek]…‹‹lld{{ƒ‹’Štt{ddclddUMRlld…„’ztl“““tt{ddcleklddf]c‚v{lksVZTf]ccbV{{ƒlldddc{{ƒult‚v‚‹‹‹lksfkk…‹‹|‚zuztœ¤¦lld\[[mtt{||ldd|‚ztt{ƒ}ƒllklddztf‹„„ttsƒƒ|lriVTL’ŒŒ:97*)(›”›¨©´«²«²««’…‹Š}|²²¬²¬µ‹‹„‘Œ…””‹¦§¨£œ¥²««²««£œ¥µ¶·¨©´‹‹‹Šƒ}„Š„‹‹„’…‹™š¤„Š„”››“Œ”››”ŠŠ}µ¶·›”›Š~‹‹’Ц§¨¨©´‹„‹‹„‹ŠŠ}””‹ƒ‚uƒ||dc\llkƒ||{{tiq]…„’|‚zuzt‹‹„tzlŒ‹“{{t‹‹‹‚|u‹„‹„Š}‘…„’…‹sleŠƒ}¤¤²²¬““““Œ”“““‹’Šttstlltsluzttzl”››d\\{ttlddrfkkd\{{tdc\{tt‚ut‹„„u{{tllrg]UTStll„Š„sleš””ult„„Šred‚|uš””‹’Š‹’Š{{tœ››|„…[[Trg]j]\tllldd{{ttsl{ttzll‚|u›¢›„Š„“Œ”‹‹‹ddclld‘Œ…“““’ŒŒƒ„„¦§¨{{ƒŒ‹“…„’{||{||””‹lekŒ”•‹’Š{{ƒlldultmtt{ttdc\„Š„‘Œ…{ttŠƒ}{ttuzt””‹œ¤¦£››‘…„‘Œ…{u{ƒ}ƒztl’ŒŒ””‹£››“““ŠŠ}“Œ”tsl„Š„ulttts|‚z„Š„ult‚utrg]{{t‚|uVTLSKJkd\|„…ƒ||{{tztlttsd\\ztltll””‹zllkd\f]clld[TT\UZultVTLsrelri]bZ{ttd\\:97{ttekdƒ‚ntt{ztljV[{u{VTL[[Tdc\‹‹‹ƒƒ|lek|„…”››{ttultŒ‹“lddŒ‹“{||lldŠ}|UMRbVUƒ}ƒmttFD;llkuztf]clri{{ƒult{tt[[TVZ[nv‚\[b]cd‹’Štsllkstsluztf]clddd\\lkstsllekƒ}ƒbVUzllƒ||tllƒƒ|ddcb[U‘Œ…:97*)(£››¦§¨‹‹„£››£œ¥¤¤»ÂÇœ¤¦–¢‹¤¤¤¤¤¤²««‘Œ…šŒ“““œ¤¦¦§¨”š”ƒ‚u{zmzllƒ}ƒ‹„‹ƒƒ|{||VZTœ›››¢›¨©´ŒŒš“““””‹£››‹‹‹ƒƒ|“Œ”‘Œ…sle‹‹„ult”š”tzl‚utƒƒ|u{{‹‹‹|„…]bZ[TT{{ƒƒ‚ukd\Œ”•””‹sletsl‘…„“““{zmŠŠ}”š”””‹‹‹„””‹„Š„{{tttsƒ}ƒœ››Œ”•{||ƒƒ|ddc{||SKJzllslesreUUY‹„‹‚|uƒƒ|UTS{ttVTLJHFƒƒ|{u{{{taWMmtttsl{u{Š}|œ››””‹‹‹‹…„’tzldc\uzt‚ut{||ƒ}ƒ“Œ”‘Œ…š””‹‹‹‹„‹{tt“““¦§¨ƒ}Šult‚ut„Š„ƒ}ƒ|„…‹„„™š¤””‹|„…lek”“›‹„‹Œ”•ƒ||’ŒŒ“““{{ƒllk‹‹„\[[uzttlllldlks‚|u’ŒŒ‹’Š””‹|‚z‹’Šƒ||“““”“›ƒ}ƒŠ}ƒƒƒ|‚|u””‹‹‹„tllƒ}ƒƒ‚u””‹ƒƒ||‚zƒ}ƒVTL‹‹„„‰vek]tll{zmaWMlldVTLkk]rg]\[[‹’Š‹‹‹‹„„{tttts{u{‚|u{{tultƒ||[TTultbVUSKJŠ}ƒdc\dc\‹„‹{||ldd[TTlrildddc\‚|u‹‹„ƒ||‚v{™š¤‹‹‹tzl{{t{{tƒ‚utllƒ„„{{t¦§¨{ttŒ‹“Šƒ}‚v{„Š„™š¤‹’Š‹„„Š~‹ƒ}ƒedkVZ[\UZVZTfkklldUUY{|||‚z]cdekd|„…|„…mttlekVZTlksuzt|„…u{{lek‹‹„ƒ„„f]clddultsleultƒ||ztl‹‹„{ttsre‹„„JHF74,ƒ}ƒ£››””‹£››£››£››››”››”››”£››‘ˆ}™‹†››”‘Œ…²««š””›”›‹’Š‹‹‹””‹””‹‹‹„ƒ||”››ƒ„„¦§¨„„е¶·¦§¨‚v{œ¤¦{{ƒ™š¤””‹¨©´{{t¨©´‹‹‹tsl¦§¨ƒ||‹‹„™š¤ƒƒ|{tttslddcMRKuztsre\UZ‹’Š‹„„‹’Šƒ||‹„„ƒƒ|‘…„‘…„Š}ƒ””‹‘Œ…ztl”“›ƒ‚uƒ„„lldVTLƒ||{u{ƒ}Š‹‹„lddf]c{{ƒrfkŠ~‹rr]››”ƒ}ƒ‚v{ƒ||Šƒ}ƒ||£››tzl‹’Š‹‹‹’ŒŒ”“›‹„„…‹‹…‹‹“Œ”””‹’ŒŒ|‚z{||“Œ”lksƒƒ|{{ƒ‚|uƒ„„ƒ||”“›‘}z‘Œ…š””ƒƒ|””‹{{tƒƒ|“Œ”tt{›”›‹‹„‚ut“““{tt’ŒŒ¦§¨›”›{{ƒ…„’|‚z…‹‹“Œ”’ŒŒ‹„‹|‚zƒ||‹‹„tt{mttƒƒ|””‹Œ‹“‚|u‹‹„{{tztlƒƒ|””‹‹’Šƒƒ|“Œ”lekƒ}ƒlri”š”rg]|‚z{ttddc‹„„‚wl|‚z”“›œ¤¦{ttŠŠ}dc\‚|uŠŠ}‚wlcbVkd\ztld\\tzl{{t‹‹„lldkd\tllllk››”£œ¥‹„„{ttsred\\””‹llklekŠ}ƒredkd\SKJekd\[[dc\\[[UTSsre\[b{{ƒdc\rfkult›¢›„Š„›¢›Œ”•””‹ultƒ}ƒllkƒ}ƒUMR\[[lldddc{||{u{ƒƒ|{{t{ttulttll›”›ƒ}Š|„…£œ¥|‚z|„…tt{ƒ}ƒ™š¤„Š„MRK{{ƒmtt{||tsl{||mtt|„…ttsƒ}ƒŒ‹“{{ƒUMRSKJred‹„„‹‹‹ƒƒ|lddd\\ttsƒ‚u””‹>B9:97‹„„Š}|‘ˆ}‘ˆ}Š}|£œ¥¤¤‚|u–¢‹£››²²¬£œ¥‹’Š£››£››“““œ¤¦ƒ„„‹‹‹”𔋒ВŒŒ””‹”š”””‹¦§¨£œ¥£œ¥”“›””‹ƒ||“““ƒ‚u””‹“““sre¦§¨‚|u{||Šƒ}tlllri‹‹„‘…„lritslult„„Šmtt|‚z„„Š‚|u‹„‹tsltslrfkƒ„„””‹{tt„Š}‹„‹ƒƒ|„Š}¦§¨kd\[[T|‚zkk]””‹„„ŠŠŠ}‹‹„redUMRbVUrfkƒ||VTL‹‹‹ldd{tt‹„‹‹„„‚ut‚|u‚ut[[TVTLb[Uztl£››f]clks‹„„‚utŠƒ}“““|‚z„„Šred‚|ulri””‹tsllekƒ„„Œ‹“zll”“›‹’Š‹„„ƒƒ||‚z{ttƒ}ƒ…‹‹‹„„ƒ||Œ‹“‹„„‹„„‹’Š™š¤|„…Œ”•›¢›ekd“““Š}|tts|„…”š”|„…tslŠ~‹Œ‹“œ¤¦{u{sle{{ƒyle’ŒŒƒ„„‚utŠ}|f]ctts‹„‹‹„‹lri››”‹„„–¢‹š””‹‹„‹‹„‹„„›¢›UTSd\\lldtsltzl””‹llk¢—{yfsle‚wltsltllƒƒ|ƒ„„lek‚|u‹uŠiWUslettsƒ„„sleƒ„„lekƒ||ult‹…’ult|„…VTLztlkk]Š}ƒ{||]bZƒ‚ulddtt{tts{zmbVUƒ}ƒf]c„„Šœ››|„…””‹Œ”•ttstslƒ„„{u{‹’Š„„ŠŠ}ƒlektll|‚zaWM£››lks{{ƒ{||‹…’¦§¨Œ‹“š””…‹‹ƒ}ƒfkk|„…\[[VZ[ult\[bttsekdf]c“““{{ƒ{||‹„‹„Š„ƒ„„srett{j]\‚|uj]\lddlddddc‹‹‹lri””‹JHF-1+“Œ”™‹†sle£››››”‘…„‰ƒv‚|u¢—‘ˆ}¤¤¤¤””‹{zm¨©´²¬µ£œ¥””‹¦§¨ƒƒ|””‹ztf„Š}{tt”›››¢›„Š„£››‹’Šš””¨©´“Œ”””‹Œ‹“[TT“~ˆ“Œ”‹’Š‹„„‚|utll[[Tr]Zrfkult{||œ¤¦„„Šllk”𔦧¨ƒ||UMR“Œ”ƒ}ƒŠƒ}ŠŠ}tllbVZ›”›{zm„Š}šŒtsl‹‹„kk]uzttslš””UTSmw¤¤\UZ{{ƒSKJ’ŒŒkd\ztfdc\‹‹‹{u{‚|u‚utƒ||Šƒ}“Œ”lld{tt|‚zŠ}|’ŒŒzll{{tƒ||’ŒŒ‘…„‘Œ…ekd\UZ{{ƒrg]{zmjcVlldultƒ||œ››››”ƒƒ|‹‹„‹‹‹„Š„lri“““›”›‹‹‹£œ¥‹„‹ƒ||{zmu{{tsltt{llkmttUUY…‹‹“Œ”redu{{llk|‚z…‹‹“““uzt›”›‹’Š“Œ”{||Š}|dc\ƒ}ƒ’…‹£››ƒ||lksf]credult””‹{{tsle¦§¨{ttœ¤¦“““’ŒŒrr]tt{‹…’ƒ„„‘Œ…ƒƒ|””‹ƒ||ƒƒ|{zm{{t‘Œ…‚wltllztlƒƒ|j]\VTLƒƒ|Šƒ}‰ƒvd\\ult‹‹„‹‹„ƒ„„tllultf]cuztlri{||[[Tztlf]c‹„‹‚utek]ekduzt{{ƒztltllult„„Ц§¨ƒƒ|lri””‹›¢›tt{ztl”“›lek{{t|‚z‹„„”››{tt“““Šƒ}“Œ”{{ƒŒ‹“”“›{{ƒ\[[|„…“Œ”ƒƒ|lks…‹’|„……‹‹u{{{{ƒVZTllkztlult{{t{{ƒƒ„„{{ƒttsƒƒ|tslƒ}ƒlddbVUbVU‹„„tts{{tuzttsl‰ƒvMRK*)(‚wl‘…„{tt£››››”””‹¤¤š””¢—’ŒŒ‹‹‹Šƒ}µ¶·¦§¨¦§¨²««²««“““œ››‘Œ…””‹””‹Šƒ}Œ”•‹‹„ƒ„„‹„„ƒ||ƒ||{{ƒ””‹››”“Œ”¦§¨ƒ}ƒ£œ¥ƒƒ|‹’Šlj¦§¨“Œ”sle‚utyflƒ||…‹’‹„‹{{ƒ„Š„¦§¨…‹‹‹„‹ŠŠ}Šƒ}‹„„Šƒ}|„…Š}ƒ‹‹‹²««››”¤¤ultuztztl\[[‚v‚””‹“Œ”””‹¦§¨„Š„‹„„lldddc{tt‚utƒ}Šttsƒ„„b[U£››lkstts£››bVUUMRj]\zllztfiWUƒ}ƒd\\Š}|‚utult››”ƒƒ|ƒ„„ldd‹’ŠtslSKJlddredƒ||ƒ„„œ››””‹i\VŠƒ}|‚z‹‹‹‚v{‹‹‹ƒ„„ƒ}ƒ“Œ”œ¤¦‹„„“““ƒ„„ƒ„„lldedktslƒ„„‚|uzllddclksztl‹…’›¢›‹’Šƒƒ|Šƒ}{u{“Œ”llk„Š„¦§¨kd\“~ˆllktslttsƒ}ƒd\\{{tlld‘Œ…llkƒ||‹‹‹ƒ||‚v{‚|u¦§¨”𔣛›£››{{ƒ‹„‹¤¤‹’Šƒƒ|‹‹‹sre””‹œ¤¦kd\‹’Š{u{¦§¨”“›lekƒ||uzt‹’Š{{tddcttsfkk‚v{ƒ}ƒƒ„„UTS{{tƒ||‘Œ…Š~‹”“›…‹‹„Š„‹‹„uzt{||‘ˆ}kd\“Œ”kd\›”›rg]lritzl“““„Š„uztŒ‹“›”›”“›z‚l””‹›¢›tts”“›‹„„{tttllŒ”•|„…{{ƒƒ||f]cddc‚utŒ‹“ƒ„„…‹’|„…lrif]cŒ”•ƒ}ƒ„„Šddcuztu{{tts[TTllk“Œ”{tt{u{bVU’ŒŒlek{ttldd””‹‹‹„{{t¦§¨JHF*)(zll‚wl‹„„’ŒŒ’ŒŒÃ¼¿¤¤””‹Ä¿’ŒŒ‚wlŠ}|‘…„¦§¨£››‹„‹£››¦§¨””‹””‹‹‹„‘Œ…Šƒ}‹‹‹››”‹’ЄЄ“Œ”œ››¦§¨¨©´£œ¥¨©´¦§¨‹…’ƒ}ƒ›”›““““Œ”””‹‘…„i\Vtslzll””‹llkƒ||tllekdlri‹’Šƒ}ƒœ››”››“Œ”ƒ‚u‹„„‹„„‹„„«²«¦§¨{{tslelldlrilldaWM[[Tj]\›”›ŠŠ}|‚zƒ„„dc\ult“Œ”‚utSKJ\[[VTLtllztl‚v{‹‹‹lekUMR{||\UZzllƒ‚usledc\{{ƒ{u{‚ut{tt‚|uƒ„„llkd\\ƒƒ|{ttŠƒ}{tt‹„„ƒ||’ŒŒƒƒ|‘…„””‹‹„„””‹tts‹„„‹„‹ƒ„„fkk‚v{ƒ„„›”›tll‹„‹leklks„„Š|‚z|„…ƒ||’ŒŒult{{ƒult{||ƒ„„Œ”•{ttlldƒ}ŠlddUTStsl‹„„Šƒ}ƒ}ƒ{ttztff]cUTSd\\lriƒƒ|tsllldVTL[[Tsre{u{lldtslddc{ttŠƒ}slekd\llkƒ‚u‹’Š””‹„Š}{ttœ¤¦{{t“““ƒ}ƒtsl„Š}‰|vkk]‹‹‹llkuztultƒ}ƒultldd“Œ”{ttttstts{zmtslƒ||’ŒŒœ¤¦ƒ„„ƒƒ|lkstzllks‹‹‹lekdc\‚utsleVTLlekƒƒ|{||b[U{u{ƒ}ƒ|„…‹’Šsle{||tll{{ƒƒƒ|‰|vtll{{ƒ†~‘“““tslldd{tt‹‹‹{{ƒ\[[mtt|„…lks“Œ”„Š„›”›™š¤„„Š|‚z{{ƒ\[[‹„‹…‹‹‘Œ…“Œ”š””slered{u{‹‹„ƒ„„„Š„„Š„ƒƒ|£››:97*)(’ŒŒšŒšŒš””£››¤¤‹‹„¼À¯¤¤²²¬œ››£››²««£››²¬µ¨©´²²¬µ¶·›¢›””‹š””Š}ƒŠŠ}“““¦§¨¦§¨ƒ}ƒ£››£››£œ¥Š}ƒ£››‹„‹””‹ult{ttƒ}ƒ{{tzll‹‹„›”›‘ˆ}slezllUTSVTLtsltts{||‹‹„‹’Šœ››{u{ƒ„„¦§¨‘Œ…Œ”•{tt¦§¨¦§¨„Š}””‹‚uttsl{||‚|u‚|uUTSredrfkuztdc\VTLƒ}ƒ{tt£œ¥””‹VTLƒ}ƒd\\›”›uztyfd‚|udc\Šutƒ||Š}|f]c{ttƒƒ|ttsUTS’ŒŒƒ‚u{||kd\Œ‹“ƒƒ|ƒ„„‹„„sleŠƒ}‹‹‹{tt‹„‹œ››Šƒ}šŒ’ŒŒƒ||‹‹„‹’Šƒ||’ŒŒ…‹‹Šƒ}ƒ}ƒlektsldc\{zmtt{{{ƒtt{ƒƒ|{{ƒƒ||“““™š¤bVZƒ„„”››{||‹‹‹{tttts”“›d\\[TT[[T‹„„‹‹„ulttllŠ~‹tll{u{ƒ||Šƒ}VTLƒƒ|››”ztl…‹‹{||aWMbVUVTLSKJcbVlek[[TaWMMRKrg]››”{||””‹ŠŠ}‹„„d\\‚v{Šƒ}‹„„{tt{{tVTLƒ‚u„Š„¦§¨b[U{tt\UZ{{tUTSkd\{||ult{{ttslb[Uult‹„‹{{t™š¤|„…{{tbVUŠƒ}lek\UZ‹„‹zll›¢›£œ¥ƒƒ|tll]bZ‹„‹‹‹‹{{tŒ”•š””Œ‹“ƒ„„Œ‹“””‹ƒ„„¦§¨„„Š{u{tts|‚zƒ}ƒttsf]c{{ƒ\[[\[b]cd]cd\[b…‹‹{u{{{ƒ{{ƒuzt|„…tslu{{‹‹‹{{ƒ’ŒŒ“Œ”‚utztlkd\ztllld‹‹„‹‹„[[T¦§¨D;9:97””‹£››‚wl™…‹„„””‹¦§¨””‹¤¤“““¦§¨¤¤²««£››²««£››¦§¨¦§¨””‹””‹™‹†’ŒŒ„„Šƒƒ|””‹¦§¨Œ”•£œ¥²««¨©´£››¦§¨£››’ŒŒ‚utult{tt‹’Š£››‘ˆ}›”›‚|u››”››”Œ”•lld‚|ubVZuzt„Š}{yfŠƒ}lri£››ƒ}ƒŠƒ}ƒ„„ttsƒ‚uš””ƒƒ|‘Œ…ƒƒ|ztl¦§¨‹‹„‚|usre“Œ”lddkk]kd\[[T[[T{tt‚|ub[Uredƒ}ƒult‚v{|„…Š}|ƒ||Œ”•f]cr]Zult’ŒŒcbVjcV{||‹‹„ultred‹‹‹{{tlldrfklrillk|‚z‹„„‹‹‹“Œ”rfkƒ„„„Š}Š}|¦§¨ƒ||ƒƒ|„Š}tll‹‹‹u{{’ŒŒ‹„„edkœ››|‚zlld|„…‚utddcmtt…‹‹ƒ||Š~‹jV[edkzll“Œ”lri…‹‹‹’Šu{{tt{‹‹„sleuzt¤¤‚|uultš””{u{‹‹‹’ŒŒrg]¤¤mtt|‚zƒ‚u{tt[TTbVUb[U[TT3+*kd\kd\ek]cbVlld‘ˆ}ztl‹„„‘ˆ}{ttƒƒ|‚utŒ‹“tsl””‹“Œ”VTLtsl‚|u|‚zŒ”•{tt‚v{“““\[[‹„‹dc\b[Uddcb[Ub[U””‹lld\[[{u{£››lldultllddc\tsllekllkŠ~‹sleuztlritsl””‹u{{ultlddƒ„„„‰vŠƒ}Š}|Š}|Œ”•››”£œ¥{u{‹„‹f]cllk›¢›ƒ}ƒlddlekmttmttdc\tt{mttedktll“Œ”|„…ƒ}ƒlri\[[{{tuztŒ‹“‚utslezll‹„„’ŒŒkd\red{ttdc\uztlldµ¶·UMR:97‘ˆ}ljljŠƒ}Šƒ}sle‹„„‘ˆ}›¢›‘Œ…””‹£››£››²¬µµ¶·šŒ¦§¨¦§¨””‹””‹›¢›d\\|‚ztsltzl‹‹‹”“›““““““‹„„£œ¥£››””‹‚|u‰v|””‹¦§¨ƒƒ|”š”‘Œ…„„Šztl‹‹„tts‚v{“““””‹{{ƒ”“›ƒ„„uzt{{ƒlld{tt²¬µ””‹dc\{{t²««“Œ”””‹ƒƒ|”š”››”lldrfk{||ƒ||Š}|ƒ„„‚|ulldlldbVU{tt‚v{yleek]{ttddcƒ||]bZtsl‹‹„‹„‹“Œ”{zmldd‚utdc\aWMddcttsredš””tll››”{{tzll{{tldd‚ut‘Œ…‹‹„£››b[U„Š}ƒ„„‹‹„‹‹‹uzt‘ˆ}„Š„{ttsle\[[ƒ||llktts‹„„{||‹’Šlri…„’ƒ„„fkk|„…rg]ult‚|ullk{||llkƒ„„|„…‹‹‹|‚ztll„Š„kd\llk¤¤””‹£œ¥’ŒŒuzt‘…„Œ”•f]c{{ttsl‹’Šsle|‚ztllultVTLj]\{ttrfk‚|u“““‹’Šb[U‰ƒv“““šŒVTL‚|ulld{{t‹„„dc\‹‹‹ƒƒ|uzttslsledkV‹‹„ƒ‚uƒƒ|llk{tt‚v{tsl’ŒŒrg]lldVTLlri‚v‚tts¦§¨””‹‹‹„llkb[Ullkttsrfk{u{›”›£››llk‹‹„”››|‚zƒƒ|{{ƒd\\ldd”š”‚|u’ŒŒ‘…„”“›lriƒ‚u‹‹‹ultf]cldd|„…tt{ddctt{{{ƒedklri\[bu{{ultd\\lksek]lkslri\[[{ttƒ„„ƒ}ƒ‹„‹Š}|tlllddi\Vlri‚wlj]\ƒƒ|ƒƒ|tzl¤¤VTLJHF‚wl‰ƒv“~ˆŠ}|‘…„””‹µ¶·£œ¥š””¦§¨²²¬²««›”›£œ¥Â¾Æ²««²««²¬µ‘…„‹„„””‹tts„Š}›¢›‹‹„›¢›‹‹‹¦§¨¦§¨£œ¥¦§¨£››””‹œ¤¦¢—Šƒ}’ŒŒ›¢›››”‹„„ttsldd‘Œ…„Š„tll{{ƒ‚ut“““ult…‹‹„Š„‹„„lrilekƒ‚u£››{{tƒ||’ŒŒš””””‹ttslriultttsŠƒ}£œ¥””‹’ŒŒ‹„„ƒ‚u›¢›kk]SKJ“““j]\‘Œ…ldd„„Š[TTƒ}ƒ|‚ztt{ƒ||zllbVUVTLbVZ{tt{tt“““{{t]bZyleš””“Œ”ƒ||„„Šd\\|„…{{t‹‹‹‚|u‘Œ…Š}ƒ””‹‹’Š‹„„sletsl‹„„„Š„tll””‹tll|„…ztllek{u{{tt{{tœ¤¦Œ‹“ttsttsu{{ult›”›ttstllulttt{ddc…‹‹llkulttlltt{ƒƒ|””‹ulttsl[TTtllœ››tslƒ||›”›š””‹‹„ultztlkd\‚|ullk‘Œ…‘Œ…kk]”››‘…„UMR„Š„„Š}”š”srezll‚|uyleŠ}ƒSKJllk{ttsreVTLƒ‚uuzt{{t£››ztl”š”ƒ„„„Š„‹‹‹\[[{tt{ttŠ}|j]\{ttƒƒ|sletllzllƒ}ƒ‹„„„Š}LKRuzt‚utŒ‹“ljedk‚v{‚|uttslridc\””‹‚|u”“›{tt‚|utsl‹’Š”“›¦§¨‹„‹tslŠ~‹lksttsf]cztl]cd[TTtzl{||mtt{{ƒu{{‹’ŠUUY]cdkd\uztƒƒ|””‹lriUTS{||d\\{tt{u{‹„„yleyleyleJHFkd\red{{t{{tŠƒ}¤¤JHF*)( ””‹£››‚wl’ŒŒ“““¦§¨›¢›¢—²««Ã¼¿²¬µ²««£œ¥£œ¥Ã¼¿²¬µ””‹ƒ||“Œ””š”””‹¦§¨¤¤””‹›¢›“Œ”””‹›¢›ƒƒ|Œ”•Š}|¤¤ult“Œ”š””””‹‹‹„œ››ƒƒ|rfk””‹²««‹„„jcV{{t“Œ”‹‹‹ldd””‹”š”ƒ„„{||ƒ„„|‚z’ŒŒƒ„„ult‹‹‹j]\””‹lldldd{{tcbV{tt„„ЄЄ‚wl‹„„””‹{{tcbVSKJš””‚|ukd\j]\lld’ŒŒ{ttœ››tllƒ}ƒ™…kd\tsl‚ut¤¤tyg””‹|‚zdc\‚uttllƒ}ƒšŒtll{{t‹’Šœ¤¦ƒ„„’ŒŒŠƒ}f]csle‹„„uztŠƒ}ƒƒ|ƒƒ|rg]b[U{u{{u{lld{tt{tttts{||ƒƒ|„Š„„Š„ƒ}Š‹‹‹ƒƒ|“““ldd›”›{u{u{{””‹“““„Š„Œ”•tlllekŒ”•œ››””‹{{ƒ„Š„”“›{tt‘…„ƒƒ|š””‚v{Š}|ƒ||ztl{{tsleVTL[[Tzll””‹ŠŠ}¦§¨£œ¥‘}z“Œ”›¢›¦§¨ƒƒ|’ŒŒŠ}|’ŒŒredtsldc\‹‹„]bZldd¤¤ƒ„„{||”››ek]mtt“““|„…rfkzllultƒ}ƒ“Œ”‹„„kd\tslcbV„Š}edktll’ŒŒš””{ttuzt{{ƒd\\VTLbVUlrib[Uldddc\dc\„Š}ŠŠ}¨©´¨©´‚|uztl””‹“Œ”¤¤”“›ƒ„„{tt{{tf]ctsl{tt|‚zmttVTLdc\|„…{{ƒ{{ƒœ¤¦tt{ekdddcƒ„„{{t{||ƒƒ|d\\uztlldtlltllƒ||tllztlllkr]Zƒ}ƒŠ}ƒŠƒ}kk]{{t²²¬FD;74,¤¤“~ˆ’‘~‘ˆ}£››¦§¨š””£››£››¤¤£››¤¤¦§¨²¬µš””››”›”›œ››¦§¨£œ¥‹’Š£œ¥‹‹‹œ¤¦µ¶·””‹ƒ||‹‹„‚|u‹„„“““œ››{{t‹‹„›”›tsl‘ˆ}sre‹’Š‹‹„tts“Œ”‘ˆ}Œ‹“bVUddc™š¤Š}ƒlek„„Š‘Œ…‹‹‹|„…ƒ||””‹‚|u„„Šƒ„„››”™š¤””‹“Œ”‹„„{{ttsl£››ƒ}ƒ|‚z‚|u‹…’¢“‹‹‹[[Tj]\\[[tts‚|uƒƒ|¦§¨mtt“Œ”ult‹’ŠbVUŠƒ}VTLcbV[TTŠƒ}rfkekd\[[uzt‹‹‹j]\MRKultrg]sle{{t‹’Šƒ„„{tt{||’ŒŒtllƒ||tts‹„„ƒ||‹‹„|‚zj]\yle“Œ”“““‹„‹ƒ||Œ”•“““ƒ„„|‚z¨©´™š¤|„…llk”›››”›“““|‚z{u{””‹¦§¨d\\“““ƒƒ|ult{||ƒ„„|‚z…‹‹„Š„ƒ}ƒŠ}|‹‹„[TTƒ||‹‹„››”ƒ„„ztl{zmrg]d\\ekdztl‚wltslƒ}ƒŒ‹“ƒ||’ŒŒ‹‹„™‹†Šƒ}‚ut‹„‹™‹†Šƒ}”“›‚utdc\£››kk]¤¤„Š}””‹{{tƒ||ƒƒ|ultlekkk]{ttsleŠ}|yleƒ||[[Tek]tzltllultult‚utb[UŒ‹“lri\[[bVZ‚wld\\””‹sleultƒ„„ztl‹’Š’ŒŒ™š¤{u{ƒ}ƒ{zm‚uttll‘ˆ}¦§¨”“›™š¤„Š„ƒ„„‚|uƒƒ|tsl{{tMRK‹‹‹ƒ„„‹‹„{||{||lri{||””‹lddekd“Œ”d\\f]cddc‹‹„{tt‘…„‘ˆ}{ttcbV‹‹‹‚|u{{tšŒ‚|u‚|u‹’Ц§¨VTL-1+””‹‹„„‘ˆ}’…‹£œ¥¦§¨›¢›£››œ››Šƒ}¢—£››£››²««£œ¥²««””‹£œ¥¦§¨¢—‹„‹ƒ„„uzt{{t››”µ¶·Œ”•‘ˆ}“Œ”Œ‹“”››“Œ”¦§¨„Š}‹‹‹‘Œ…llkdc\ƒ‚uztfsre’ŒŒrg]Œ‹“lddttsultƒ‚urfkŠ}ƒ{{t{ttƒ„„‘Œ…‹„„››”{||‹„„ƒ‚u¨©´š””{{ƒšŒ‹‹„tzllddultsleŠƒ}‹„‹Š}ƒttsVTLrfkf]c‚v{ƒƒ|lri“Œ”{||{||lld‚|u’ŒŒztlkd\ƒ„„ztl‚|u[TTdc\‚|utsltllbVZƒ||Š}|tslsre|‚z¦§¨ƒƒ|cbVkk]{||{tt›¢›{||tslƒ„„‹‹„¤¤‚|u“““ŒŒštts{||{ttuzt\[[ŒŒš›¢›‹’Šƒƒ|Œ”•lks™š¤£œ¥“Œ”ztl“Œ”“““‚|uekd‹„„{ttƒ||f]cŠ}ƒdc\{||lldmttrfkldd{ttŠ}ƒ‹‹„ƒƒ|zllŠ}|ztltllƒ||‹„„{{t{tt{{tƒƒ|“““‚|uš””kd\kk]™š¤™š¤tsl‰v|red””‹ƒ}ƒ‚|u””‹tll¦§¨ztlddclri|‚zŒŒš{||uztŠƒ}{ttzll“““‹‹„ztlddcllduzt{{ttll{ttŠ}|zllultldd{u{lldr]g{{ƒsleztl{{ƒuzt£››tsl‚|uœ¤¦™š¤{||‰|vƒƒ|¨©´²««{u{”“›“Œ”{u{{u{rfklri|‚zult‹’Š››”Œ”•“““ttsƒ}ƒVZ[ƒ„„‹„‹|‚zlritts{|||‚z]bZtslsleš””ztlŠ}|‰|vdc\llkŠ}|‚ut››”{tt|‚z¦§¨[[T*)(tll‚wl‘…„ƒ}ƒ’ŒŒ››”“Œ”›”›¦§¨£››£››£››“Œ”ü¿²««¦§¨£œ¥£››£œ¥”››£››Š}ƒŠŠ}š””‹’ŠŒ‹“Š}ƒª³·’…‹‹„„””‹ƒƒ|””‹ƒ„„{ttŠ}ƒztf„Š„””‹¤¤{zm“““ƒ‚uultb[UlldVTLrg]ultzlltsltllult£››””‹slef]cƒ}ƒ|‚z‹„„””‹œ››llkƒ„„‘…„{{t£œ¥ztlbVUŠ}ƒtll\UZJHF[TTtllllk[TTldd{u{f]c{tt{||sleulti\VVTLVTLkd\ztlekdcbVcbVƒ„„Œ‹“ttstlllddtll’ŒŒ‚ut‹’Š‹’ŠŠƒ}lddŠƒ}ƒ}ƒ‹„‹tts””‹š””šŒ‘Œ…ultƒ||{ttƒƒ|f]c{{t{{ƒŠƒ}{{ƒ|‚znv‚{u{‹‹‹‹’Š…„’›”›”“›„„ŠŒ‹“››”„Š„…‹‹ƒ||ult¨©´Œ”•{u{‹‹„ƒƒ|„Š}tts‹„‹ƒƒ|rg]{ttƒƒ|jcVSKJjcV{{tf]c£››{zmtslƒ„„tzltll\UZzllƒ||‘Œ…ŠŠ}ult‚v{‚|ušŒŠ}|‹‹„“““ƒ||ƒ}ƒ{||zllf]cdc\tsl{{ƒ‚|uƒƒ|[[T‹‹„Š}ƒ’…‹…‹‹{||Š}|ek]‰‘~|„…slef]cmttzlltllbVZSKJ{||ƒ||{{ƒ“Œ”{{t‹„„{||„Š„”𔛢›‹„„\UZ‚v{{tt¨©´””‹‹„„””‹lek‚utztlƒ„„„„Š{ttŠƒ}VTLŠƒ}‹’ЄЄ‘…„{{t„„Šu{{ultult{ttŒ‹“„Š„“Œ”„Š„‹’Šuzt|‚zƒ}ƒ‘…„{ttb[U‚|utllyle{tt‚ut‰ƒvŠŠ}sre¦§¨D;9*)(Š}|š””“Œ”‰|v¦§¨ŠŠ}²¬µ¤¤²²¬£››””‹¤¤›”›¦§¨šŒšŒ“~ˆ£››œ››…‹‹sre‹‹„Šƒ}‘…„¦§¨›¢›šŒ”š”Š}ƒƒ||ƒƒ|‹‹„‹„„ƒ}ƒ”“›„Š„‹‹‹ƒƒ|z‚ltslŠƒ}‹„„””‹tt{‚v{‹‹„Šƒ}VTLultult‘Œ…‹„„”››“““›”›‹„„tt{“““ƒƒ|›¢›‹’Šf]c‹‹„{||‹‹„kd\ƒ}ƒsrebVUbVUult{u{\[[sleultlldƒ||b[U”“›“““Œ‹“ƒ„„tslbVUSKJFD;]bZSKJsrekd\[[Tlddd\\‹„„ztltzlƒ„„”š”ttskk]sle‚ut‚|u{tt™š¤”››œ››“Œ”‘…„¦§¨‚v‚ƒ„„£››‹„‹‹„‹ztl‹„‹Œ”•™š¤ƒ|||‚z|‚zlksf]ctt{fkklksUMRŒ”•‹‹„Š}ƒ”››tslœ››œ¤¦£››“Œ”{{ƒ‹‹‹”“›lldŒ”•›”›lekƒ‚uƒ||ƒ||lldsletslb[Uztfldd{tt‘Œ…Œ”•{{t{{tlldultcbV‚ut‚|u‚|ušŒ£››ultŠ}ƒj]\{tttts‰|vrg]tll{ttd\\„Š„uzt””‹{{tuztrg]bVZlddlddtts‚|u’…‹ƒ}ƒMRK|„…tslƒ„„rfk‚v{UMRbVZƒ„„‹‹„ƒ}ŠŠ}ƒƒƒ|{{ƒtll{tt„Š}œ››sre‹„„tts‹‹‹Œ‹““““Šƒ}f]cŠutŠ}|{{t𔔙𤓓“dc\‹‹‹dc\ƒ}ƒƒ||ƒƒ|ƒƒ|„„Šddcf]cf]c‹‹‹{||“Œ”‘Œ…{{ƒŒ”•‚utƒ„„ŠŠ}‹‹‹zlltllredj]\‚|utslj]\redƒ||‹‹„ztl›¢›JHF*)(™š¤’‘~²««‚ut‹„‹£››²²¬£››””‹””‹£››Ã¼¿””‹“““ü¿””‹²««›”›‹‹‹”“››¢›£››¦§¨š””””‹¤¤tslšŒ‹‹„“““ƒ||ztl‘Œ…uztš””Œ‹“””‹“““ztl‚utkd\rfk””‹ldd‹‹‹‹„‹’ŒŒ‹‹‹’ŒŒ£››‚utJHFuzt{||””‹£››‹„„›”›””‹{||uztŒ‹“”››tzl£œ¥{{t{{ƒlrizllrg]{||lddlrijcVtts‚v{””‹ultf]cSKJ”“›tll{||Š}|{{t{tt[[TUTSVTLj]\llklddlkstts‚v‚š””Š}ƒƒ„„{||r]Zekdddc‹‹„””‹ƒ„„ƒƒ|‹„‹ƒ||ztl’…‹{||ƒ||Š}ƒj]\{tt™š¤llkuzt{{ƒ’ŒŒ„„Š|„…u{{{||{{ƒlksedk{u{”š”ƒ„„ŒŒštsl|‚z|‚ztts“Œ”¦§¨“Œ”lks{{tkd\lksttsedk{tt{u{{{tultllddc\redred‚ut{tt””‹tts¦§¨ƒ||ttstllkd\yfd””‹zll£››‚|uŒ‹“ultdc\d\\””‹‹„„‹„„{tt{u{Š}ƒ„Š„ldd{{ttts‹„‹”››‰v|lddllk{ttŠ}ƒ‹‹„‚|usre{||tsllddlek‚|uUMRultbVZtts[[T{u{ƒ||tslƒƒ|tllƒ„„“Œ”‹‹„’ŒŒ‹„„ultƒ„„ƒ||š””ultbVU™š¤{{t‹„‹Œ”•d\\[TT|„…tzlšŒ”š”fkkŠƒ}sre™š¤Œ‹“{||““““““lri‚|uldd…‹‹{||‹‹‹{||ƒ||Š}|{u{‚wl{zmtlld\\‚ut‚wl‰v|rg]rg]¤¤FD;74,””‹‘}z£››j]\’ŒŒ¤¤Ã¼¿£œ¥²««™‹†²¬µ‹„„£œ¥œ››””‹£››šŒ|‚z‹„„””‹‰ƒvŠƒ}””‹¤¤¦§¨µ¶·››”’ŒŒƒ||{{tsle””‹››”š””’ŒŒllk‹‹„{{t›¢›ƒƒ|ƒƒ|{tt‹‹„tt{{tttts{zmztlƒ||£œ¥tllƒ||‹„„”“›œ››‹’Šƒ}ƒƒ||‹‹‹’ŒŒ|‚zlddtts[[T‹‹‹{{tƒ„„tzlkd\{tt{u{[TTd\\[TT‹„‹ƒ}Š{tt{{tŒ‹“ddc™š¤ƒ„„[TTd\\ekdrg]kk]bVZllkldd[TTtzllritllš””‹‹„“Œ”[[Td\\b[U{{t{tt›¢›{{t‹‹„‹„‹ttsŠ}|Š}ƒƒ}ƒ‹„„ƒƒ|‹„„{u{‹’Šƒ||“Œ”ƒ„„u{{{{tƒ„„llkƒ„„tt{{{ƒ…‹‹|„…“Œ””››„Š„ƒ}ƒtts„Š„„Š}ƒƒ|ƒ„„‚v‚””‹tt{Š}|{u{tll{u{{u{ƒ}ƒƒ||›”›››”llkdc\red‘}zf]cƒ}ƒ’ŒŒ{||‹’Š‚ut{{tUTS‚|utllsre‹‹‹‘Œ…ylettsŠƒ}‘Œ…ƒƒ|yfd{{tƒ||sleyflƒ}ƒŒ‹“{{tŒ”•‚ut‹‹„ƒ}ƒ{{ƒƒ||‚v{{u{Šƒ}“Œ”‚v{„Š„‹‹‹VTL‚v‚{{ƒ””‹edktllf]c‹‹„[[T‹„‹››”slelddllk””‹››”{zm‹„„“Œ”””‹u{{¦§¨””‹ultztlrg]{zm{{t|„…„„Štll{{t|„…²««…‹‹]bZ‹‹‹…‹‹tt{”“›|‚zlek|„…Œ”•ŠŠ}ddclekd\\kd\llkddc{tt‹„„Š}|uztldd\UZf]cŠ}|‘Œ…‰ƒv‹„„””‹>B93+*ƒ||‘…„£››£››”“›µ¶·Ã¼¿š””””‹‘ˆ}¤¤¦§¨£››”“›²««š””ª³·Š}||‚z¤¤›¢›£››¦§¨‹‹„”“›””‹¦§¨¦§¨œ¤¦tt{ƒ‚u‹„„‰‘~’ŒŒ‘…„’ŒŒ‘Œ…‹‹‹››”””‹lld{ttkd\tts‘…„{ttlldj]\tll’ŒŒ£››ƒ„„‚v{f]c‹„„tsl{tt‹„„ƒ„„{ttrg]ddctllƒƒ|šŒ”“›ƒ„„”š”Š}|’ŒŒ›”›llkiWU]bZtlluztœ¤¦tsl{{t{||ultlekdc\Š}|JHF{||ƒƒ|ttsƒ„„rfktllJHF{||‹‹‹‚v{srellkddckd\b[Utslslekk]d\\{||ƒƒ|lekyleztl’…‹Šƒ}ddctts›”›„Š}Œ”•‹‹‹‹„„u{{uzt|‚zƒ„„Œ”•‹„‹œ¤¦…„’…‹’™š¤uztddc\[[|‚zƒƒ|„Š„‹„„ƒ}ƒ\[bf]clks“Œ”lddƒ||ƒ}ƒœ¤¦ƒ}ŠŒ‹“…‹‹œ¤¦“Œ”‘Œ…„Š}œ››ƒƒ|j]\‹‹‹lld””‹i\V{{tzllkd\ldd„Š}ƒƒ|i\Vƒ||llktlllld{||llkŠ}|b[UbVU‚utbVZ‹„‹{ttsre‹’Šttszllƒ}ƒult‹„‹ƒ||{ttŠŠ}lek{{tƒ}ƒ[[Tddcttstlledktll{{ƒƒƒ|¦§¨Œ‹“Š}ƒsrecbV{{tsre™š¤u{{kk]‘Œ…ƒ„„Œ”•£››£œ¥tll‰|vzll‚|uƒ||ƒ||ult{ttƒƒ|‹‹‹‹’ЄЄ‹’е¶·{||{||Œ‹“Œ”•“““ƒ‚n{u{Šƒ}ultƒƒ|tsld\\rfk„Š„Š}|{zm‹„„tll{zmŠ}|zllyleztlkd\kd\””‹:97*)(ƒ„„‹„„Šƒ}¦§¨¤¤²¬µ£››£œ¥š””²¬µ ¦§¨¦§¨£œ¥£››’…‹šŒ›¢›ƒ‚uƒƒ|””‹››”””‹£››«²«¦§¨£››ƒ„„’ŒŒ‹‹„ƒ||’ŒŒztf{u{yfd‚ut”𔄄Ћ‹„£››{zm‹„„ƒ‚ulddšŒ‹‹‹tsl‚v{ƒ}ƒœ››Šƒ}…‹‹Š}ƒ’ŒŒllksle{{ƒ…‹‹„Š„ƒƒ|ƒ‚uldd„Š„ŠŠ}››”Œ”•‹‹„tzl‚|uddcƒ„„lriƒƒ|FD;d\\u{{]bZllkd\\rfklddlddsrezllSKJŠ}ƒtsl|‚zsleVTLtsldc\ƒƒ|lddsleVTLzll‹‹„lld’…‹››”rg]sre‹‹‹ldd‹„„ultd\\{u{ƒ||‹„„{ttŒ‹“‚|uztlƒ||‹„‹‹„‹mttllk|„…{{ƒœ¤¦|„……‹’ƒ}ƒŒ”•Œ‹“ƒ||œ¤¦ddcŒ‹“lriuzt‹‹„{ttlkslekUUY‹„‹ƒ}Šƒ||‹„‹‹„„kk]ldddc\‹’Šƒ}ƒ‹„„š””‘Œ…š””’…‹tllsrekd\bVZultlld‚v{bVZbVZœ››lddlriŠ~‹kd\‚v‚Šƒ}{{ƒƒƒ|Š}|f]c›”›lddultœ››ldd{||llkd\\kk]‹„„{u{‹‹„‚v{ƒ||ƒ||ƒƒ|{||tsl{u{‹‹‹VTL{zmbVUddctts„„Š™š¤lriztltllUTSš”””“›””‹››”ulttsl…‹‹š…ަ§¨Œ‹“‰|vttsrg]ƒ||tsl‚v‚ƒ||›¢›kd\[[T„„Š‹’Ц§¨£››£››œ¤¦Œ”•“Œ”‹‹‹{{ƒ’ŒŒtllƒ„„ƒ„„ƒƒ|lekƒ||{tt‰|v‚utztfzllsle‹„„ƒ||kd\‚wl‹‹„¤¤:97*)(ldd‹„‹Šutš””œ›››”›š””£››‘ˆ}¢“‘ˆ}£››™š¤¦§¨£››µ¶·£››¦§¨{{tƒ‚u¦§¨””‹‘Œ…‚ut¤¤”š”œ››‚|uƒ||ƒ}Ф¤””‹š””tts‚wl‚v{{{t“““‚|u‹‹„›¢›“Œ”‚|u‹„„’ŒŒ„Є𔔔”‹“Œ”Š}|sle{||f]crfk“““{{tƒ||ƒ}ƒ«²«‹‹‹zll‘Œ…{||‹’Ц§¨›¢›Œ”•d\\rg]redldd…‹‹ztlllkf]cŠ}ƒrfk[[Ttll‘ˆ}tt{j]\VTLkk]lldslettslridc\ƒ||tll„Š}dc\‹„‹tyg|„…ztllddj]\mtt{zm‚ut””‹{{t‹’Šš””ƒ||f]c‚v{tlllddd\\’ŒŒ‹„„ƒ}ƒŒ‹“ƒ„„›”›ƒ„„ƒ}ƒ„Š„ekdŒŒš|„……‹‹{{ƒtt{“““„„Š|‚z{u{””‹‹’Š‹‹‹„Š„tlllek{||Š~‹{{ƒ“Œ”‹„‹™š¤{{tllkleksle›¢›””‹|‚z‹„„sle‚|u{ttllklriredkk]VZTzllredbVZ[[T{{t{ttƒ}ƒultddc{ttƒƒ|””‹Šutredrfk‘…„{u{ƒ„„{{ƒ{||ŠŠ}lriztl]bZ\[[‚ut‘Œ…“Œ”VTLƒƒ|lld“Œ”lriddctsl{zm[[Tf]c„„Štsl{ttƒ}ƒš””””‹‹„„‚v{“Œ”„„Š£››‘…„lek{||bVZ‹„‹‘Œ…™š¤Šƒ}{u{ztl‹„„{{tš””kd\‹‹„uztuzt|‚zƒƒ|š””{{ƒ“Œ”|„…|‚z…‹‹œ››tt{‚ut{||{{t{zm‹„‹lldlldd\\sletll‚|u‘…„zllldd‘…„Š}|yleƒƒ|Šƒ}>B9&&‹‹‹£œ¥“Œ”‹‹‹›”››”›››”£œ¥¢“¦§¨Š~‹{tt“Œ”¦§¨£œ¥²««£›››¢›ŠŠ}‘Œ…š””ƒ‚u£››œ¤¦«²«{{tœ››ƒƒ|ƒ||¦§¨‚ut¤¤””‹’ŒŒrr]redtsl{u{tsl£œ¥ŠŠ}ztl¤¤Œ”•’ŒŒ‹’ŠŠ}|’ŒŒ{{tŠƒ}{{t{||‹‹„zllš””sle“““‹„„Œ”•ƒƒ|tllŠƒ}‹‹‹Šƒ}ultƒ„„{tttllsle’ŒŒultllksretts‹‹‹„„Škd\\[[tllf]c‹„‹sreztl‹„„d\\tts”𔋄‹””‹tllŠƒ}{{tVTLUTS[[Tlldztlkd\b[U{||ŠŠ}kk]ekduztƒ||kd\lddlkszllƒ||“““{ttkd\‘Œ…‹’Šu{{“Œ”{{ƒ””‹ddcek]lks|„…”››…‹’mtt‹„‹Œ‹“|„…edkƒ}ƒ‹‹‹|„…ƒƒ|‹‹‹š””{u{„„Š““““Œ”ƒ}ƒ£œ¥ddc{||‘Œ…ƒ||“Œ”””‹“~ˆcbVkk]tllkd\“Œ”f]clrib[U‹‹‹ƒ||”››j]\ztf{||{u{{zmƒ||ldd{ttƒƒ|‹‹‹ƒ‚ud\\Š}ƒƒ||rfkŠƒ}‚|utslttsœ››‹’Š{||tslkk]ƒ}ƒ‚ut‹‹„{ttredsrej]\‹‹„ttsUTS”š”tts’ŒŒ{u{{||£œ¥“Œ”‹„„¤¤{tt›”›’ŒŒ””‹Š~‹ultŠ}|uzttts™š¤zll{||‚|u“~ˆ{zmztlƒƒ|£œ¥zll””‹srelriƒ}ƒ‹„„Œ”•¨©´¦§¨|‚zekd“““‹’Šekdslellkldd‚|u‚|uƒƒ|tzl“Œ”‚|u{zmƒƒ|‘Œ…{tt‘ˆ}‰|vredkk]i\V””‹D;9*)(››”œ¤¦””‹{{t“““œ››¦§¨“Œ”‰|v£œ¥””‹‘…„£››£œ¥£œ¥“Œ”£››|„…‹‹„ƒƒ|¦§¨š””Šƒ}ƒ„„ƒ‚u››”‹„„œ››‚|u‹„‹‚utztl‘ˆ}‹‹„„Š}yleb[U[[Tzllf]czllŠ~‹{ttult‹‹„””‹š””tsl{u{kd\{tt|‚zš””kd\”“›‹„„š””ƒ||Œ”•£œ¥zllƒƒ|›”›‹‹‹‹‹‹ƒ„„ultlldzll‰|vŠ}|sledkV‚v{dc\Œ”•dc\{ttƒ||ƒ}ƒ“““lridc\kk]mttSKJ‹’Š{{trfk“““FD;sre{{ttll{{t|„…[TTb[UsleŠƒ}b[U{{tsreƒ||tll{||‹’ŠtllŠ}ƒŠ~‹‚v{‹„‹ƒ||𔔔𔋋„“““tt{lldultuztmtt{{ƒ{{ƒ{{ƒlrilksŒ”•‹’Š|‚zŒ‹“{u{‹’Šuztultƒ||ƒ}ƒœ¤¦ttsldd‹„„lks”“›{u{‹‹„Œ‹“{{t‹„„‰ƒvu{{{u{ƒƒ|Š}ƒ’…‹Œ”•‹’Šyle{||tsl{{ƒztlkd\d\\f]cuztŠƒ}tzl{||””‹›¢›œ¤¦””‹bVUrg]ƒ}ƒ‹‹„‰|v{tttslkd\ŠŠ}‹‹‹ƒƒ|ƒ||“Œ”{u{{ttrg]kd\[[Tlldtsl]bZult””‹››”{tt{{ƒ‹’Šsle›”›ztlztfš””ƒ„„š””””‹‹„„ztl‚utƒ}ƒ…‹‹ƒ||²²¬”“›‚|u“Œ”ztlsle“““Š}ƒ‹‹„lekœ››|‚z‚wlŠŠ}tll‹‹‹„Š}ek]{||™š¤„Š„{||‹‹„ƒ„„tsl‘Œ…ƒ||{||{ttƒ||JHFŠƒ}i\V‹„„ŠutztlŠ}|‹„„‚wlred²²¬FD;*)(„‰v““““““£››£››¦§¨£››£››šŒ‘…„²¬µ£››¤¤››”²««²¬µ²¬µ¦§¨ƒƒ|‘ˆ}‚ut¢—’ŒŒ’ŒŒ‹‹‹“~ˆ‚v‚”𔣛›‹„„ldd£››››”“Œ”‹‹„{ttƒ‚ubVUš””{||tsltll{{t{||‹‹„„Š„‹‹„‹’ŠŒ‹“ult››”uztttsƒ‚u’ŒŒŠ}|{tt’ŒŒƒ„„{||‹‹„‚|u’ŒŒ„Š}”š”””‹lri‹‹‹Š}ƒsleldd›”›Šƒ}FD;{||ult|‚zƒ}ƒlri{ttttsllkekdu{{lldb[Ulri‚utUTStygtll„Š„sreuztŠƒ}„Š„ztlsre[TTaWM|‚zztl‹‹„rfklldƒ||ŠŠ}tllƒ}ƒ£››‹„‹tllš””ƒ|||‚zƒ„„‹„‹lks„„Šlrilek]cd|„…”“›|„……‹’lkstt{Œ”•Œ”•Œ‹“ƒ}ƒfkkllk{ttultlek“Œ”„„Šƒ„„sle£››{{ƒ“Œ”›”›£œ¥{{t{{t|‚z„Š}{u{‘Œ…ultrfktsltt{rg]lld‹‹‹‚utUTSzllyleslekk]{{t{||lddƒ„„ƒ„„““““““’ŒŒ‚utlekf]c{u{{u{r]gƒ||ƒ||{||ƒƒ|Šƒ}‹…’tllredtzlsleVTL|‚z{{ttllŒ”•‹‹„‹‹„ƒ„„ttsllk{tt‚v{œ››ƒ||””‹‹„„¦§¨‹„„£››£››¦§¨ƒ„„]bZ{{ƒ„‰v™š¤¤¤™š¤£››ulttslƒ||Šƒ}tsl{{t‹‹„Šƒ}ŠŠ}mttmtt“Œ”£››“““u{{‹’Š›”›””‹{{t‹‹‹lddlldtzlllk{ttj]\‹„„lddsleƒ||‚|uztlsletslrg]¦§¨JHF*)(’‘~{{t‘ˆ}²¬µ£œ¥²««¦§¨“““£››šŒ£››£œ¥¤¤‘…„²¬µ£››šŒ‹‹‹ŠŠ}‘Œ…‹‹„‚|uzll›”›››”£››Šƒ}‘Œ…‹‹„{{t™š¤‹‹„Šƒ}ƒ„„‰|v’…‹|‚zŠƒ}‹„„’ŒŒ„Š„{||srelri‹’Š‹’Š””‹„Š}„Š}ƒ}ƒ‚|u…‹‹‹‹„’ŒŒ‹‹„|‚z{{ƒŠƒ}{{t™š¤yfl””‹Šƒ}sle„„Š””‹llkŒ‹“””‹r]ZbVZ“““““““Œ”“““ƒ„„ƒ„„Œ”•llkred{ttddc[[Tlld‹‹„Šƒ}lldlldƒ||tzltll[[Tddc{||rg]dc\b[Usreslesleƒ‚nsreŠŠ}{{ttllƒƒ|lritzl””‹²¬µ‹„„zlltllƒ}ƒŒ”•tts{{ƒult„„Š]cd|‚z{{ƒ|„…Œ”•|„…u{{Œ”•…‹‹|„…mttlriultuzt{{ƒultf]clks\[bmtt›”›’ŒŒultŒŒš‹‹‹ƒ„„lddztldc\kk]‹‹‹{tt‚utƒ}ƒ‹„‹llkddcƒƒ|””‹Œ‹“sre{tt‚utzllztl{{ƒ{u{kd\d\\ƒ„„¦§¨‚ut{u{¤¤š””‚utred{tt{||ztltllkk]\[[¤¤lriŠƒ}ultŠƒ}uzt‚wl|‚zmttŒ”•Š}ƒtt{’…‹””‹£œ¥mtt]bZ„Š„Š}ƒttsŠƒ}‘…„‘Œ…š””sre™š¤””‹µ¶·tts{u{{||¦§¨œ¤¦š””››”“Œ”“““„Š„‹„‹””‹‚v{ztl››”[[T‹‹‹‹„„‹‹‹‘ˆ}z‚l”››ƒ„„…‹’‹„„„Š}lldttscbVlldttssrerg]sle{{t‚utztl‚|ui\V‘…„zllƒ‚utll””‹JHF!””‹”š”›”›œ››²²¬¦§¨²¬µ£››‘Œ…””‹š””‹„„£››’…‹Â¾Æ£œ¥£››“Œ”ƒ‚u£››œ¤¦’ŒŒŠƒ}£œ¥{{t‘ˆ}{tt{{t„„Š‹’Š””‹’ŒŒœ››””‹””‹’ŒŒttsztl””‹‚|uƒ„„{||‹„„™š¤ƒƒ|lldŠƒ}tsldc\dc\kk]tsl›¢›ƒƒ|‚ut£››ƒ||ƒƒ|„Š„‹„‹Šƒ}””‹zllllk‹„‹œ››{u{{tt‹„„b[Uš””ƒ}Š{{ttsl{{ƒ„„ŠlribVZlritlllriVZTUTStlluztf]c„Š}ƒ„„‹‹‹mtttslkd\ƒ||‹‹‹‰ƒvuztyle››”‹„„šŒ{zm{u{JHFƒ||‹‹„|„…ƒƒ|“““{zm“Œ”¦§¨œ››|„…”››„Š}„Š„{{ƒ“““|„…|„…‹‹„…‹’lkslksekd“Œ”}‡’™š¤|„…„„Š„†™‹„‹fkk„Š„dc\ult‹‹‹tt{ƒƒ|lddd\\tsl”“›{u{œ¤¦tts‚|uVTLƒ‚nƒ}ƒ‹‹„ult£››f]cult|‚z‘Œ…ƒ„„lks{{ƒƒ||ztl‚|u{{t„Š„lekttsldd”š”Œ”•{||‹„„‘Œ…lddrfkbVZdc\{{t››”””‹u{{tll{{t{ttƒƒ|ŠutŠ}||‚zŠ}|ƒ‚uŒ‹“{zmkd\u{{ztlrg]ƒ||llk›¢›ƒ‚uƒ}ƒ‘Œ…’ŒŒŠ}|ƒ||Šƒ}¤¤£››š””“Œ”{ttlri’…‹””‹‹„‹””‹{ttŠ}|²««“““‹‹‹‹„„Š}ƒ„Š„{||‘Œ…sre“Œ”{{t‹‹‹|‚z””‹{{tƒƒ|ƒƒ|sletslŠƒ}{{t{{tztl[[Tƒ‚u[TTsleultb[UztlŠƒ}ƒƒ|{ttŠŠ}‚v{ult>B9*)(””‹¦§¨””‹ƒ||‹‹‹²««²««£››¦§¨¦§¨”𔦧¨¤¤›¢›¤¤¦§¨¦§¨¤¤””‹””‹”››¤¤‚v{‹‹‹‚v{zll‹„„tts’…‹“Œ”“““””‹£››“Œ”’‘~‹„„dc\lekyle‚v{’ŒŒ{{ƒ‹‹‹{{ƒldd{||’ŒŒ{{td\\[[Tuztllkƒ‚n””‹£››‘Œ…ƒ}ƒƒ‚uldd“Œ”œ››¢—sle|‚z£œ¥ƒ„„ztlƒ„„ƒ‚u‚|uƒ||tts|‚ztts‹‹‹œ¤¦{tt„Š„‹‹‹‚|uƒ„„{{t[[T””‹\[[ƒ||‹‹„ƒƒ|ldd‹‹„Š}|ttsƒ||ƒƒ|Š}|slesle””‹jcVƒ||kd\‹‹„tzlttsƒƒ|ƒ„„ƒ‚u£››‰|v’…‹“Œ”ƒ}ƒ‹’Š{tt{||‹‹„{{ƒ„Š„ƒ„„{{ƒ…‹‹ƒ}ƒŒ”•{{ƒtslmttmttŒ”•mttmttuztŒ‹“\[b\[[{||lddƒ„„lekultult’ŒŒ„„Š|„…rfkœ¤¦‹„„{ttlddƒ„„”š”œ››dc\ƒ}ƒ“Œ”tsllldttsldddc\[[Tlld‘Œ…‹„„lld{{t{{ƒ[[TbVUkd\tts„„Šldd‹’Šedkzll\UZd\\tll‹„„{||uzt””‹“““‹’Šlriultzll\UZ{{ttyg[TTMRK\[[llk\UZŒ‹“{ttult‹’Ц§¨¦§¨‹„„‹‹„ƒ}ƒ‚wlkk]››”‘…„µ¶·’…‹™š¤‹…’ƒ||‹„„‹‹‹£››’ŒŒ’ŒŒ£››™š¤ttsztl‘Œ…‹’Šdc\{{tƒ‚ulld››”ƒ||tzl|‚zŒ”•{zmkd\ƒƒ|lriiq]lldtllsrebVU{zmztl‹‹„ztlŠƒ}‚|u””‹tllyleŠƒ}“““”š”D;9*)(‘Œ…‹‹„£››’ŒŒ›”›“Œ”²««£››£››‘Œ…”“›ŠŠ}‚wl¦§¨µ¶·£››£››ƒƒ|«²«””‹‹‹„‚wlƒ||””‹kd\„Š„{{t{||{tt{{t£››¤¤ƒ‚u„Š„››”{||{{trfkrg]ƒ}ƒ””‹Š}ƒ{{t{u{‹’Š‹’Š‚wlƒƒ|{tt{u{„Š„d\\ƒƒ|¤¤š””˜Ž£µ¶·’ŒŒƒ‚u‹’Šztlƒ‚uƒƒ|ƒ„„ztlƒƒ|SKJttssle“Œ”Šƒ}bVU[[Tultllkult„„Šlksƒƒ|ƒ„„llk‚|u[[Td\\tts|„…ƒ‚u{{t‚|u‚|u“Œ”„Š„‹‹‹‹’Š‚|u{{tf]c””‹’ŒŒ‘…„sleƒ||{{tsleztl””‹lld‚v{ztl“Œ”””‹tsl”š”tll‹‹‹™š¤edklld{{ƒ{{ƒ|‚z…„’›¢›tt{…„’|„…mtt{{ƒmttu{{{||‹„‹{{ƒllduztd\\\UZlks[[Tf]clld{u{llkŒŒš{{tldd››”cbV”𔋄„ultlddultƒ||ƒ}ƒdc\{{t{tt[TTUMR{ttb[UmwVTLrfk{u{VTLSKJ{tt{{t‚v{‚v‚red„Š„ldd[TTtsldc\|„…‹‹„„Š„””‹šŒƒ„„‚utsle‘}z„Š}ekdllkllk„„Šldd{||’ŒŒ£››ƒ„„{{ƒuzt””‹‹‹„Šƒ}sre‹„‹Š}ƒ²««²²¬£››£››‰|vlekllk’ŒŒ‹‹‹‹‹‹‹‹„Š}|zll‹„‹ƒ}ƒ’ŒŒ‹„„ƒ||‹„„ttsƒƒ|£››Œ”•›¢›{{t„Š}„Š„|„…ztl‹„‹b[Uƒƒ|{tt‘Œ…{||{{tlddtts‹‹‹‚|u‚utztlƒ||’ŒŒ‚ut””‹ƒ||‚wlŠƒ}:97*)(››”¤¤²««£œ¥µ¶·š””””‹‘Œ…š””µ¶·µ¶·š””«²«²²¬£››¦§¨¢“ƒƒ||‚zƒ‚u‹‹„¦§¨£›››”›‹‹„tll””‹‹‹„œ¤¦{||¢“’ŒŒ¤¤tts‹‹„ƒ||‘Œ…f]cultttssleb[U’ŒŒ‚v‚ƒ‚u‹’Š“Œ”››”]bZ[TT|‚zddcb[U|‚z›”›‚|u‹„„‹„‹ƒƒ|tslŠƒ}kd\{zm‹‹‹‚v{ª³·ƒ||llk’ŒŒ›”›lddsleŠƒ}‹„„›¢›ult”“››”›ttsb[Uƒ}ƒcbV„Š}‘Œ…Œ”•ƒ||‹‹„tlli\VVTLSKJkd\‹‹‹tll{{t‚|uyletll‚|u‘ˆ}‚|u‹„„tslsle{||b[U’…‹””‹{tt‘…„‹„„tsltsldc\{u{{ttlks‹‹„{{ƒ{||uzt{{ƒ›¢›mtt„„Š|„…Œ—£mtt|‚z|„…|‚z›”›|„…{||llk{ttlek{||{{ƒd\\bVZbVZ{u{£››|‚zƒ}ƒ””‹‚|uƒ„„ƒ„„z‚lult‹‹‹‹‹‹tlluztdc\redUTSztf›”›kk]SKJƒƒ|‹„‹lekkd\f]ctllVTLmttd\\tslƒƒ|”“›ƒƒ|‚|u\[[””‹“Œ”‹’Š“““£››‹‹‹kd\{||‹„„{tt‹„„sle‹„‹ƒ}ƒldd„„Š{{ƒ‚v{ƒ}ŠlksmtttllsleultztlultUMRldd””‹’…‹“““‚utllkuzt™š¤tts“Œ”£œ¥’ŒŒ¤¤£œ¥ƒ„„‹„‹šŒzllsre‹‹‹ƒƒ|››”””‹Šƒ}‚|uŠƒ}„Š„ŠŠ}“““lddztfsre‘Œ…ƒƒ|ƒƒ|]bZredƒ||ƒ‚u{{t‹„„‹„„‚wlztlztlšŒƒ||tsl‚wlJHF*)(£››¦§¨ÃÄÆµ¶·¦§¨‹„„£››šŒ‘…„£››²²¬¸Á¹””‹µ¶·£œ¥š””Šƒ}¦§¨””‹ƒ‚u‹‹„‰|v“Œ”“““›”›£››’ŒŒ‚|uƒ}ƒ›”›‹„„yleŠŠ}ƒ„„’ŒŒ“““’…‹“Œ”£››„Š„ƒƒ|‚|uuzt‹„‹’ŒŒ””‹””‹››”mtt{{td\\ƒƒ|‚|uŒ‹“£››Šƒ}{zm‚|u‹‹‹ƒƒ|‚|uŠƒ}ƒƒ|„„Š”š”{||f]csresre‘Œ…Š}ƒultllksle{||ultultuztlldd\\{u{VTL]bZ{{tsre“Œ”‘Œ…{zmƒ}ƒJHFSKJdc\dc\‚|uztf[[Ttllkd\‚|u””‹ƒ||Šƒ}Šƒ}lldkd\ztlj]\‹„‹‘…„{tt‘Œ…tsl{{t{ttttstllddclddlekmttu{{mttœ¤¦|„…tt{{{ƒŒŒš{{ƒttslks“““²¬µtt{Œ”•|„…”“›Š}ƒ‹…’“Œ”ƒ||ttsf]cƒ}ƒbVZylelri¤¤|‚zsre{||kk]’ŒŒ{||‚|uldd„Š„|‚zkd\rg]‘Œ…œ¤¦‰|vsreztl‹„‹rfkƒƒ|Šƒ}‹„‹rfk“““ztlkk]b[U‚|uƒ}ƒzlltlltllf]c”š”{{t‹‹‹„„Šrfkrg]rfk””‹uzt|‚z„Š}{u{leklektlllekƒ||ttsmtt£››‹’Š‚utŠ}|‚v‚zll’ŒŒƒ‚nllkŠ}|‹„„‹„‹ult™š¤f]c‹‹„””‹Š}|‘Œ…‹„‹lddšŒ‹‹‹£››tsl{u{‹’ŠŠƒ}””‹‹‹„Šƒ}tll„Š„{||Šƒ}‹„‹¤¤‚wlŠƒ}{{t[[Tdc\tll””‹tslŠƒ}‚|uƒ||‚|u‘ˆ}{tt“~ˆ’ŒŒ‹„„ztlD;9*)(£›››¢›²¬µ¦§¨²««¦§¨²««²««£››’…‹µ¶·²²¬‹’Š””‹››”£œ¥šŒ‹’Ф¤«²«››”ƒ‚u£››‹‹‹‚ut››”‹„„‹’ŠŠŠ}lld’ŒŒ’ŒŒ¦§¨‚wl{tt{u{zll’ŒŒ{{t‹’ŠttsŠ}ƒMRK‹‹‹sre|‚zŠ}ƒ‚|udc\‹‹‹¦§¨‹‹„››”‹’Šƒ||{{tlriƒ‚u‹’Š‹’Š‚utŠŠ}‚|utsl‹‹„››”Š}|“““ƒ||zllƒ||ƒ||ztld\\ddcsre„Š„\UZ{{tƒƒ|Š}|‹‹‹ƒ‚u{{t‘Œ…””‹‹‹„dc\j]\f]cVTLsleƒ„„lddttsuztŠƒ}ŠŠ}b[Utll‰|vyleztlkd\kd\‚wlf]ctsl‘Œ…Šƒ}Šƒ}d\\ƒ||Š}ƒƒ„„{ttllk“““ƒ„„„„Štts{{ƒn…{{ƒƒ„„mttŒ”•lkslksultlek„„Š™š¤|„…mtt’ŒŒtt{ult]cd‚v{bVZ{tttt{tsllld{{tz‚l{{t‹‹„ƒ‚utsl’…‹f]cj]\llk{{tŒ”•””‹{{t‚ut{{t‹„„‘Œ…ƒ‚u{{tlek{zm‚|urfklks…‹‹„Š„ƒ||kd\Šƒ}ƒƒ|SKJf]ccbVƒ||sre›¢›lddƒ}ƒƒ„„slesletsl‘Œ…‚|uzllttsult””‹‹…’“““lriekd”››œ››|„…„„Š{tt“Œ”ƒ||£››¤¤‹‹„š””{tt{||{ttƒ„„rfkƒ||‹„„Š}ƒ{u{Šƒ}‹„‹tll‚|ud\\‚|u[[Ttsl‚|usrekd\lldŠƒ}œ››‹’Š››”lldrg]ƒ‚u‹‹„‹’Š‹’Šƒƒ|‚v{””‹kd\ƒ||r]Zš””sle‚|uredredVTLcbV£››FD;*)(¢—¦§¨£œ¥’ŒŒš””šŒ£œ¥¼À¯µ¶·¦§¨¦§¨¦§¨¤¤²²¬‰|v£››¦§¨››”›¢›{zm{{t‘ˆ}Šƒ}››”{{tƒ‚u‹„„‚|u{u{¦§¨£œ¥››”‹’Šƒ||‹„„{{taWM’ŒŒœ››llkƒƒ|ƒ„„{{t‹„„”𔋋„redllk{||„„Š‹’Š‚ut¦§¨›¢›{ttŠƒ}tzlSKJJHFVTLš””{tt››”{zm””‹‹‹‹b[U|„…£››ult{tt‚utldd[TT””‹ult{ttd\\slej]\kd\|‚zƒ‚udc\slelddkd\f]ctslb[UJHFƒƒ|tts{u{””‹dc\{tt‚|u‘ˆ}llk‰ƒv‹„„‹‹„””‹ttsƒƒ|lddƒ„„””‹tts{{ttslcbV‹„‹””‹ƒ||{{tƒ}ƒtts…‹‹…‹‹lks|„…|„…{{ƒ{{ƒŒ”•VZ[]bZfkklksleklkslrimttƒƒ|\[[\UZUUY{ttldd{u{‹‹‹›”›„Š„{{t””‹cbV‘…„‹’Š[[Ttllultldd{||sretsl‹‹„tts‹„‹{zmkk]lldƒ}ƒƒ||{||ƒ‚ušŒd\\‹„„tll|‚z‚v{kd\b[Utzlu{{tsl|‚ztslƒ||‹‹„tll„Š}{{tkd\‰|vVTLlldslelri{tt{u{ƒ„„‹‹‹lksmtttt{|‚z¨©´œ¤¦”š”ƒƒ|›¢›Šƒ}ƒ||{||tsl{tt‘Œ…›”›ultƒ}ƒ{||uzt“Œ”kd\ƒ||Š}|Šƒ}‹‹‹bVU{ttd\\ttstslƒ‚uuzttslƒƒ|{||{{tuztf]cult{zmzll‘Œ…””‹uztŠƒ}ztl””‹rg]d\\j]\tllrg]rg]Š}|ƒ||{{tztl¦§¨UTS*)(¤¤¤¤£››šŒ“Œ”¦§¨²««¤¤¦§¨¤¤¤¤¸Á¹””‹›¢›šŒ²¬µ™š¤””‹›¢›‘ˆ}‚|u{ttrfk{{tœ››’ŒŒ£››ztl‹‹‹‘Œ…“Œ”tll{{t‹„„‹‹‹{||rg]{{t{||zll|‚zƒ||ƒ„„tts{||š””‹„„{{t\[[llk‚|u”“›š””””‹›”››”›ƒ„„Š}||‚ztyg‚v{ttsj]\“Œ”¦§¨‘Œ…Š}|Œ‹“‚|u{u{bVUztlŠƒ}VTL]bZldd„„Šllk\[[UMRtll[[Ttsl{||›”›dc\{zmlrij]\tll{zmtsltlldc\{{tztlŠ}ƒ{ttkd\VTLlldbVUb[U{{tŠ}|Šƒ}rfkŠ}ƒƒƒ|‹„„”𔋄„››”‹„‹ƒ„„VTLsre{{ƒ|„…tt{Œ‹“|„…Œ”•„Š„{{ƒllk…‹’nv‚{||mttd\\{{ƒfkk|„…ttsf]cUTSlks\[[bVZƒ}ƒ‚v‚‚|u’…‹”š”Šƒ}‰‘~sreƒƒ|llk{{tttsllkd\\ztllri[[Tƒƒ||‚z‹„‹„Š„„Š}sreŠ}ƒƒ}ƒƒ„„dc\tllf]c{ttŠ}ƒƒƒ|tts‹„‹{{ƒ{u{„Š„”“›sle{{t|‚zŠƒ}{{t{{ƒ{{t[TTtllVZT[[Tƒ||{||ƒƒ|bVU{u{llk‹„‹…‹‹”››‹’Š‹‹‹œ››¦§¨|‚zu{{ƒ||£››’ŒŒ‹‹„¦§¨{||\UZ{{ƒlri‹„„”š”zll””‹zll¦§¨““““““sle‹‹„“Œ”tts››”{tt‹‹‹‹‹„‰ƒv|‚z{{tlddj]\ztl{zmslesleƒƒ|ƒ}ƒ‹„„’ŒŒztltsl{ttSKJlldek]‰ƒvƒ||sle‚utsle²««SKJ*)(‘ˆ}“Œ”²««›”›ÃÄÆ¨©´£››™‹†””‹””‹””‹›¢›¤¤””‹£œ¥¦§¨”››‹‹„Šƒ}{zm{zmtllŠ}ƒƒ||ƒƒ|›”›„Š„‹‹„tll‹‹„‹„„Œ”•’ŒŒ“““{u{„„Šlld[TTlrisleƒ„„‹‹„‹‹„Š}|{{t¤¤¦§¨|‚z‹‹‹’…‹ek]{tt››”‹‹„ƒ}ƒ‚|u„„Š‹„„sle{{tldd‘Œ…¦§¨¦§¨£››zllš””‹‹„{tt‹„„ƒ||{ttkd\{u{{{tttsttsƒ}ƒlldSKJ]bZuztkd\tslŠ}ƒ{{ttllVTLd\\[TTD;9{{tlld‚v{sre{||‹„‹kd\ztldkVkd\‹„„ƒƒ|b[U{{t””‹ƒ}ƒ‹’Š””‹¦§¨‹„„ztlƒƒ|’ŒŒ{{tlrisle‹‹‹ƒ„„Œ”•œ¤¦lksmttmtt{{ƒVZ[{{ƒ…‹‹fkkmtt…‹‹{u{ulttsllksƒ„„d\\d\\„„Š£››“Œ”š””llkƒ„„¤¤‚|u””‹kk]sreuztttskd\tt{\[[lldredztl{{t””‹Š}ƒllksle‚|utll“““‹„‹\UZƒ||’…‹ult{u{{tt{||dc\jcVtslult{{t’ŒŒ‚|u{zm{{ttts{tt{u{j]\d\\edkekdƒƒ|{{ƒ{||tts{{ƒ˜Ž£Œ‹“ŠŠ}u{{…‹‹‹‹„{{tš””‹’ŠŒ‹“tts››”‹‹„””‹“Œ”‹‹„ƒ„„ƒ}ƒ“““uztƒƒ|{tt¦§¨£››‚v{ƒƒ|{||›”›{{tŠŠ}ttslld‹„„ttsult››”{{t…‹‹›¢›Šƒ}lridc\b[UcbVƒƒ|‘Œ…llkkk]‚|utsl{tt‚ut‹„„ztlrg]ddcƒ„„ƒ||red¤¤D;9:97£››£››¦§¨²¬µ¤¤¦§¨£œ¥””‹¤¤’ŒŒµ¶·¤¤¦§¨«²«¦§¨“Œ”£››”š”””‹‚wlŠƒ}ƒ||“Œ”“““„Š}¦§¨ƒ}ƒ’ŒŒ{tt¤¤ƒ||²««ƒ||ƒ„„{ttŒ”•‹„„‚|uuzt‹’Š””‹rg]llktts{zmš””ultb[U\[[‹‹‹[TT{||kd\{||{ttsled\\ƒƒ|‹‹‹‹‹„œ››””‹£››ƒ„„‚|u‘Œ…‚v{tsl”š”j]\‹’Šdc\sled\\ƒ||kd\lek{{ƒddcldd\[[dc\[[Td\\“Œ”f]cslesle{ttb[U[TT]bZrfkldd‚utƒƒ|bVZj]\ztlztlŠ}|kd\|‚z{zm‹‹„“““ztf|‚zŠŠ}„Š„ŠŠ}rfktsl{||’ŒŒ|‚zkd\tt{‹‹‹{{ƒlri‹„‹{ttlri\[[|„…„„Š”››…‹‹mtt…‹‹{{ƒ…‹‹]cd\[bttsf]c{u{lks{{ƒf]cddc\UZ{||ƒƒ|lld{{tƒƒ|kk]kk]{{tlri„„Šldd{{ttllddcult]bZŠ~‹uzt{{tb[Uƒ}ƒf]cf]c{ttj]\’ŒŒ{tt‹„‹sresle‚|u‹‹‹lddult{{tttsƒƒ|››”‚|u‹„‹‹’Š{||‚|u|‚zult„Š„UTS{ttttsttsf]c{{ƒ{u{’ŒŒ„Š„„Š„ztl”𔋄‹„Š}Œ”•‚ut{{ƒ{||’ŒŒ’ŒŒƒ}ƒ‹„„ƒ„„{||…‹‹lrizllŠƒ}‘Œ…”“›””‹‹„„ƒ‚u‹‹„ƒ‚u{||‚|uuztttsƒ||{{ttsluzt‹‹„ƒ||“““‹‹„ƒƒ|sre{{t‚wl{{ttslztf‹‹‹kd\ztlŠ}|sre’ŒŒƒ||{{ttsl{||¦§¨FD;*)(‰ƒv£œ¥¦§¨””‹£œ¥²¬µ¦§¨šŒ››”¤¤¤¤””‹””‹””‹“““µ¶·£œ¥‹’Љƒvƒ‚uƒ||redredƒ‚u””‹‹‹‹{u{œ››ƒ„„””‹ƒ||‹„„Š}ƒ‹’Šƒ„„{ttztlŠƒ}{||Šƒ}””‹š””””‹œ¤¦lld{{tred[TTldd{ttslelekrg]sledc\tslƒ||“Œ”ƒƒ|‹‹‹š””‘Œ…””‹ƒ}ƒ‘…„‹„„tll‚v{[[Td\\ƒ„„‚|uztltll{||”“›ƒ}Š”“›uztf]c]bZlddb[Ulddd\\{u{{{t‚ut‹„„ƒ‚uldd„‰vredVTLkk]lddbVZ‚|uslelddŠ}|ldd{ttllkƒƒ|‚|u‚|u{{tŠƒ}{||sle‚utztl’ŒŒƒ||lriƒ„„|„…{{ƒŒŒš{{ƒtt{]cdult{{ƒmtt{{ƒ|„…tt{edkf]clksllkekdmtt{{t‹„‹ƒ„„lks{u{lek\[[d\\ek]lldllkkd\ƒƒ|‹„„tslsreldd\[[d\\sleƒ}ƒllkŒ‹“tsl‹„‹“““‹‹„sleŒ‹“ddclddtt{‚ut‚v{{ttultldd‚|u‘Œ…‹‹‹VTLkd\UTSƒ‚uœ¤¦ƒƒ|Šƒ}{tt{||uzt‘…„ldd…‹‹]bZtsllksœ››{{ƒ{u{lksult[[Tlektsl””‹œ¤¦‹’Šllkuzt|‚z‹‹„‹’Štzl“Œ”Š}ƒ¦§¨lekŠƒ}|‚zlld{u{ƒƒ|ƒƒ|’ŒŒ‹‹‹‹‹‹ƒ„„b[USKJd\\mwFD;[TTllkƒƒ|ttsƒ‚udc\{tt››”{zmŒ”•ek]llkcbV[[TŠƒ}{{t]bZtllsre{ttjcVyle‹„„’…‹Šƒ}sle£››SKJ*)(Šƒ}œ¤¦£œ¥“““£›››”››”›¤¤£œ¥µ¶·“Œ”ƒƒ|„Š}«²«ƒ„„”“›‹’Š””‹””‹‹‹„””‹ƒ„„{ttlld„Š„‹’Š{ttlldƒ||‹‹„š””Šƒ}|‚z’ŒŒ›”›{||“Œ”{{t‹‹‹„Š„‘Œ…“Œ”ƒ„„|‚z{{ttts{||‹„„ƒ„„ult‚|uŠ}ƒ‰|v{zmtyg’…‹rfk‘…„{{t„Š}ƒƒ|{tt›”›tsl’ŒŒƒ||zllƒ||ztlƒ}ƒ{ttldd[TTƒ}ƒ„Š„{{tddc{||tsltlltsl{u{ek]lektllrfkztl{ttlddkk]kd\ddcf]ckd\b[Uekdd\\zllaWMMRKƒ||{||‹‹„lri{ttj]\{zmŠŠ}{yf|‚zkk]ŠŠ}{tt”“›””‹‹„„‹‹‹¦§¨ƒ}ƒ‹…’uztddc|„…|‚zlksmtt…‹’uztllkmttf]c\[bultekdlksultƒ||iq]b[U{u{ƒ}ƒ{u{\[[ldd{{t{{t[TT{{tlldtsl{zmlldƒ}ƒdc\sleddcd\\aWMlriƒ„„ƒƒ|{{tVTLlldtllr]gtt{Š}ƒ‘…„lddd\\tsl‚utddcztlddcb[U{||[[Tlld‹„„”››{{t]bZƒƒ|ƒ||u{{”››{||””‹““““Œ”™š¤\UZ\UZSKJkd\ekdtll{tt|‚zf]c{||lksfkktslttsb[Uf]c{||‚v{{u{{ttllktsltllaWM|‚z{tt{||ztl{tt’ŒŒj]\tsl‹‹„ƒ||dc\dc\lri{zm{{ƒ[[Tredƒ„„””‹‚|uƒƒ|ƒƒ|lldtslsre{zmtsltllcbV{ttkd\ztl{{t{ttmttldd™…D;9:97ƒƒ|𔔍©´›”›‘Œ…²««£œ¥¦§¨µ¶·‹„„šŒ””‹ƒƒ|¤¤œ››¦§¨uzt›¢››¢›‘Œ…’…‹‘Œ…{tt’ŒŒ‚v{ƒƒ|{u{””‹™š¤‹‹„™š¤‹‹„‚|uƒ„„‹‹‹“““{zm„Š„”š”|‚zƒ||{ttultlri|‚zƒƒ|¦§¨|‚zŠƒ}‘Œ…ƒƒ|ƒƒ|{zmtsldc\red{{tƒ||{||„Š„|„…sle‹„‹red{u{{ttredlldslelddlekj]\dc\SKJslelritslƒ„„b[U{||ddcƒ„„uzt{{t{{tldd{{t[TT{tt{zmSKJ|„…‚utsle{{ttll{ttztl‰ƒv[TTsle“““lrilld{ttj]\Š}|kd\tslllkztlbVZttsƒ}ƒ‹‹„{{tdc\lkslksddc{{ƒ{{ƒƒ„„llkmttƒ„„u{{ddc\[[UUYUMR{{ƒ{{ƒuztmttlddlek‹‹„dc\ddclekllkultŠŠ}lrilddlriƒ‚u””‹{ttd\\lek{{t{||ztlldd|‚zƒ„„kk]VTL{u{j]\b[U\[bd\\[TT‚|ub[Ured{||[TTllkVTLb[Uredb[Uj]\]cd{||ƒ„„j]\tlltts”››ekd{u{{||{ttVTLlri{u{ƒ||…„’tllŒ”•{||tllkd\‹’Š{||“““]cd|‚zdc\lksƒ||ddcbVUSKJztlVTL[TTlrittscbV{||sletygtts|‚zrg]‹‹‹ƒ||ƒ||{u{lddztllriƒ„„Šƒ}|‚z„Š}dc\ldd[[T|‚zttskd\[[Td\\tslb[Utzl[[T[TTkd\{||„Š}redƒƒ|ƒ||tslj]\£››SKJ*)(‹‹„””‹£œ¥£›››”›£œ¥›”›””‹”››’ŒŒ›”›¤¤››”›¢›ƒ„„‹‹„”››””‹ultŠƒ}{tt‹„‹‚|u””‹‹‹„ztlƒ||‹„‹Œ‹“{zmƒƒ|‚wl“Œ”ƒ}ƒ{{tlksŠŠ}{{t{|||‚zztlsredc\„„Šsre“““ŒŒš{ttšŒ’ŒŒŠƒ}ƒƒ|‚utŠƒ}{{tzllekd’ŒŒttslddllktll{||kk]{{t‚|uultult‹‹‹“Œ”tll\[b]bZbVU[TTtslf]c{||tsltlltllƒ}ƒlldkk]tlld\\kd\j]\ƒƒ|ƒ‚uFD;tll{ttsleVTLb[UlddVTLztlƒ||tts“Œ”ultkd\cbVdc\{zmƒ‚usletts„Š}tll‹„‹…‹‹“““‹‹„[[T]cdslelks{{ƒ{{ƒedkddc{||u{{mtt\UZ\[bJHFVZ[lkstt{ddc„„Šlksƒ}Šlks[[Td\\lekllkf]ctts“““‹‹„‘ˆ}VTLtslttsbVZ[[T[TTzllkk]ƒ||mttz‚ldc\lks‹’Šƒ||VTL\UZSKJd\\lekkd\zlllddlldddcSKJVTL[TTtslƒ}ƒ\[[dc\tslVTLVTLŒ‹“lrildd\UZlldd\\{u{llkllk{tt„„Štts„„ŠtllbVZlkslridc\uztŒ”•mttƒ}ƒlektlluztlekj]\b[Uu{{d\\{tttts[TTVTLtslVTLkk]ddc‚|uddcŠƒ}{{t’ŒŒŠƒ}tllƒ||ekdƒƒ|[TTdc\lld‚|uultttsf]cƒ„„{||kk]sre‹‹‹dc\kd\lddztlddcb[U‚utlld{ttƒ||sle£››JHF*)(Šƒ}‚|u“““𔔍©´“Œ”“Œ”’ŒŒ¦§¨£››²««”››“““›¢›Œ”•ƒ‚uŒ‹“„Š„ƒ„„ƒƒ|…‹‹‹„„{tttsl{{ƒ””‹››”tt{‹‹‹””‹{ttsle‹‹„Œ‹“tsl{{tzllztl‹‹„llk‘Œ…ƒ||UTSkk]dc\ekd{ttlddtslulttsltslkd\|‚z|‚zkk]{||d\\{||lddlri‚|uttsŠƒ}ttsSKJddctllƒ„„Œ‹“ult[[TVTLSKJllkJHFSKJ\UZdc\ldd‹„‹|„…tsllldtslb[UUTS[TT]bZVTLj]\b[UVTL{tttslVTLzllztlztfldd{u{lrilddJHFb[UVTLkd\redtslttsƒ||{ttllk{{ƒtsllldUTSttsekd{{ƒ]cdf]cllkƒ„„tts{{ƒ…„’\[bfkkVZ[ƒ}Šu{{lksddc|„…{u{“Œ”ŒŒš{tttlledkuztlek‚utuzttsltslVTLtt{\[[d\\[TTekdj]\{{tlddkk]„Š„tzl[TT\[[d\\b[Umttllkllkldddc\\UZlekbVZlldtllzllŠ}ƒtslj]\[[Tdc\lldttslldllkuztkd\edk\UZVTLb[UJHFf]cUTS…‹‹u{{Œ‹“ddcb[Ukd\…„’UTSlriuzt]bZttslddMRK„Š„„„Š{ttUMR[TT{tt„„Šllk[[TlddcbV\[[{ttlldj]\[[Ttslsreƒ||kd\ddcb[Uddctll]bZkd\ƒƒ|lldtlltslƒ||{||ultŠƒ}d\\dc\ztldc\kd\tsl{u{sle‰|vsleddc{{tlld²««[TTD;9ztl’…‹¤¤‘Œ…‘Œ…ƒ||“““‹‹‹{||››””“›…‹‹…‹‹Œ”•„Š„“““ƒƒ|„Š„{{t|‚zllk‹„„””‹|‚zƒƒ|tts{||llkd\\kd\{u{’ŒŒƒ}ƒ‹„„lrilldlldztlkk]lldtsl””‹tslu{{sleedk[[TVTLrfkf]credkd\kd\]cd|‚zsleƒ}ƒlldtts{||ekdf]ctlllld|‚zslelld‹„„tts{tt{||tllcbVzll[TTdc\d\\{u{]bZbVU{tt\[[VTL[[Tkd\\[bb[U[TTtllslekd\|‚z[TT‚utztl\[[b[Usletsl{||tts[TT[TTlld|‚z‘Œ…d\\tsl{{t{{t{||lldtllttsd\\[[Td\\{{ƒlrif]cfkklkslks|‚z{||mtttt{VZ[LKRVZ[mttmtt]cd\[[\[bd\\d\\lddlekmttedk\[[r]guztekdekdd\\lridc\{{t[TTlldd\\FD;[TTd\\kd\tslUTSlld\[[[TTkk]f]cj]\f]cf]c[TTtllf]cbVZUTSllkkd\ttslksllkd\\SKJmttUTSUMRd\\tllSKJ[TT\[br]gf]cUMRUTSztlddcslelkszlltll\UZtllVTL{||llddc\lldtt{VZTtt{„Š}‹„‹ultd\\d\\tt{mttekdlkssleVTLkd\{{tdc\dc\{{tldd[TTztl\[[dc\d\\b[Uddcd\\f]cb[UcbVlldlld{{ttslcbV[TTztlVTLkd\dc\lldtllb[Urg][TTUTSredkd\””‹[TT:97{||››”’ŒŒ²²¬“Œ”“““ƒ„„Š}|”››“““ttsllk„Š„ƒƒ|tt{mttƒƒ|…‹‹‹„„ŠŠ}{{ƒ{u{ztl‹„‹‹„„tts{u{{u{ƒ„„llk{{ƒƒ}ƒ{tt{ttkd\kd\dc\{u{tsldc\slelldƒƒ|{{ƒ{||{||ƒƒ|tllttstlldc\{ttkd\{||…‹‹{u{|‚zlld|‚zVZTSKJkd\lek|‚ztts\[[JHFf]clrildd{||sledc\ttsttsllddc\\[[JHFd\\UTSdc\ztfkd\\UZsleVTLd\\tslaWM[[Tllk{ttkd\lldlritslƒ||uztƒ„„tts{||{{tlld{u{kk]ztf„Š}{{tlridc\lddultekd]bZdc\llkSKJtlllksmttlksVZ[f]cllkUTSlks\[b\[btt{\[bult\[bVTL\[bJHFUUY[TTdc\UMR\[bd\\UTS[[T[[TVTLMRK\[[|‚ztllttsekdd\\b[USKJUTSSKJ\[[dc\lldttsllkj]\d\\leklddUMR[TT{tt\UZleklldtsld\\VTLkd\[TTuzt[[Tƒ„„ddcu{{ƒ„„{ttd\\JHFmtt[TTldddc\\UZtts{u{u{{SKJ\UZ[TTVTLUTSekdlldedkddc[TTllkddcddclridc\JHFedkttsult\[[[[Tllktslf]ccbV[TTkk][[TlldSKJSKJtlltlld\\fkkd\\sretslllkVTL{||{{t[[TVTLUTSd\\ldd[[Tdc\tllrg]]bZttskd\ldddc\d\\[TTztl²««JHF*)(‹„„ƒ||‹‹„’ŒŒ‹„„‹„„{{t„„Šƒ„„‹„„tzl{||tll|„…llkƒ„„|‚zttstllƒƒ|tt{lddƒ}ƒ„„Šb[Uƒ„„{||ddcllk[[Tultlksultu{{{ttd\\JHFdc\VTLek]lld{{t{{tlddldd…‹’ƒ||sre|„…ƒ||„„Šlriƒ||ddc{||{{t|„…u{{ddcddcedk{u{{u{tsl[[TJHF[[T\[[ddc{u{lddultkd\f]c[TTddcd\\dc\cbVlddultuztkk]b[U[TT[[TVTL\UZtllVTLb[Udc\kd\redlldVTLb[Ulldtzl{||tllekddc\lldtll{{tlddztltsl]bZlrilldlddttslld{||\[[UUY]cdedktt{mtt\[b]cd\[bUUY\[bmttlkslksUUYfkkUTS]bZUMRJHFUMR:97JHF:97UTSUTSJHFllkllkVTLSKJllk]cdcbVLKRb[Ub[U[[T\[[SKJVTL\[[dc\lriddcVTLdc\llkf]cllklddlldlddUMRUTStts\[bkd\VTLllkJHFtllbVZuztttslddddcbVU[TT[TTUTSJHFJHFddcUUYUMR\[bJHFJHF[TTdc\d\\ekd[TTUTSJHFVTL\[[]cdD;9f]clld]bZd\\VTLSKJVTLJHFllktt{‚|uekdUTS]bZdc\JHFkd\[TT[TTtll[[TVTL]cdb[U[[TSKJVTLdc\lldFD;[TTUTSSKJJHF[TT[TTdc\dc\b[Ulddd\\VTL\[[bVUd\\jcVkd\ŠŠ}JHF-1+{tt‚|u„Š„ƒ}ƒ{tttts{||{tttts„„Šdc\“Œ”uzt„„Šllkttsu{{tts|‚zJHFedkleksle\[[sleek]llk\UZf]c{{tf]cedkSKJtts{ttlddlrillddc\\[[]bZ{{ttslUTSldd{u{llklksfkkllkultkd\[[TUTS]bZ[[Td\\tllUTSddctts\[[\[[dc\VZTJHFJHFJHFFD;UTSVZTVZTtllredd\\VTLVTLdc\kd\UTSd\\kk]dc\ddcUTS[TTdc\bVUcbVJHF[[T]bZtllb[UJHFd\\tllb[Umtt[TTUTS\[[VTLb[U[TTdc\VTLb[U[[Tddc[TTUTS\[[cbVVTLddcf]cf]cUTSlksllkVZ[]cdultmtt\[[edk\UZJHFLKRUMRJHFLKRUTSJHFJHF)+2:97F=CF=CJHF:97D;9d\\d\\VTLdc\VZTLKRJHFUTSJHFFD;JHFFD;UTSMSStllMRKUTS\[[UTS\[[\[[[TTf]cSKJSKJD;9JHFUTSUMRlddVZTUTSlekdc\lks\[[[TTddcF=CSKJFD;UMR:97JHF:97:97MSS:97\[[UUY\[bllkult{||JHFJHFFD;>B9>ECJHF:97JHFLKRUTS\UZ[TTUMRMRKd\\VTLJHFekdlldlddJHFF=CFD;MRKSKJSKJlldlddSKJllkUTS[[TJHFJHFD;9D;9:97:97>B9:97>EC:97D;9:97JHF[[TSKJSKJlddJHFFD;\UZJHFJHFSKJSKJ¦§¨SKJ*)(ztl{{tƒ||{{t{tt{ttllkdc\lldldddc\[[TJHFedkdc\ddcmttlkstts]bZllklddtllultVTLMRKJHFUTS]bZ[[TUTSJHF\[[UTS\[[tslbVZllktsl[TT]bZ]bZFD;JHF>ECJHFJHFJHFVZ[UTSddc[[Td\\UTSVTLd\\SKJ\[[\[[UTSVZ[JHFJHFD;9dc\JHFJHFUTSSKJUTSJHFJHFd\\JHFJHFJHF:97UTSJHF:97FD;JHFVTLJHFJHFJHFdc\[[Tkd\JHFD;9JHFJHFJHFFD;FD;SKJ[TT[[Tldd\[[JHFddc\[[lldd\\[[Tddcllddc\VTLFD;JHF]cdllkddcldd\[[[TTd\\]cd\[[]cdJHFLKRJHF]cd*)($:97*)(*)(?;C:97:97*)()+2:97:97:97:97UUY3+**)(74,!*)(*)(*)(*)(*)(74,*)(*)(*)(JHF*)(:97*)(:97*)(74,3+**)(*)(3+**)(*)(7-2*)(:97*)(*)(*)(:97*)(,55*)(*)(*)(*)(*)(*)(*)(:97&&%&*)(>EC-1+%&FD;)+2LKRLKRUTS?;CJHF*)($*)(*)(,55*)(*)(F=C*)(*)(*)(*)(*)(74,:97-1+*)(*)(*)(:97:97JHF*)(74,-1+*)(*)(*)(74,3+**)(*)(&&*)(*)(*)(!*)(*)(*)(*)(*)(*)(*)(*)(:97*)(*)(:97*)(*)(D;9:97*)(-1+VTLSKJFD;\UZ[[TJHFSKJJHFLKRJHFSKJSKJ3+*:97:97JHFJHF74,:97LKRUTSMRKMRKJHF:97*)(:97*)(:973+*:97*)(:97:97JHFLKR>ECJHF,55:977-2*)(-1+74,:9774,-1+3+**)(*)()+2*)(*)(*)()+2:97JHF:97,55*)(*)(*)()+2*)(*)(?;C*)(74,:97*)(:977-2*)(JHF*)(&&*)(*)(3+*:97*)(3+**)(*)(*)(*)(74,3+*&&&&3+**)(*)(&&-1+*)(*)(*)(SKJ*)(*)(:97*)(D;9:97:9774,74,*)(*)(>EC*)(:97*)(*)(*)(*)(*)(*)(74,*)(-1+,55,55:97)+2*)(,55:97:97:97LKRJHF?;CUUYf]c\[b\[b\[[[TTSKJUMRJHFllkUTSllkJHFMRKVTLUTSJHFF=CVTLJHFFD;JHFJHFUTSJHFJHF>ECJHF>ECJHFJHFJHF:97LKR:97F=CJHF:97D;9:97:97:97:97FD;:97:97:97JHFF=CLKRJHF\[b\[[MRKMRKdc\]cdLKRek]UTS\[bMSSMRKJHF\UZJHFJHFVZTMRKJHFMRKJHFJHFJHF:97:97:97:97JHF>B9JHFMRKJHF:97D;9UMRVTLJHFFD;VTL[[TD;9JHFFD;>B9:97:97>B9D;9FD;JHFJHF>B9D;9:97JHFD;9FD;UTSSKJD;9FD;SKJD;9SKJJHF[TT[TTJHFJHFVTLVTL:97[[Tdc\VTLllkbVZf]cek]>B9VZ[\UZ>EC\[[VZ[UUY\[[\[bLKRVZTfkk]cd\[[[TTUTS>B9MRKMSSJHFSKJddc[TTVTLVZ[UUY\UZUMR\[[MRKllkVTLJHF:97SKJ[[TVZTJHFJHFVTL\[bJHFMSS[TTLKRJHF:97JHFD;9:97JHF:97JHF\[bf]cJHF:97VTLJHFJHF>EC:97>B9JHFSKJ:97:97SKJJHFJHFJHFJHFFD;SKJD;9MRKJHF74,JHF:97:97JHFFD;UMRD;9SKJbVUFD;MRKb[UJHF:97UMRMRKMSSLKRFD;:97FD;JHFekd:97JHFUMR]bZJHFUTS:97JHF\[[LKR\[bLKRMSSJHFLKRMSSOS`OS`JHF¦§¨¦§¨“Œ”¦§¨¦§¨™š¤¦§¨¨©´…‹‹¦§¨›”›¦§¨›¢›¦§¨«²«››”²««¦§¨›¢›µ¶·µ¶·²««²««””‹¤¤¤¤£œ¥”“›¦§¨²««””‹””‹œ¤¦ƒƒ|‹‹„ztl›¢›šŒ‚v{¦§¨²²¬²««²««£››£››š””¦§¨“Œ”¦§¨tsl’…‹¤¤£œ¥Šƒ}¤¤²««››”¤¤¦§¨¤¤››”¦§¨²¬µ¦§¨¦§¨¨©´¦§¨¦§¨¦§¨£››¦§¨£››¦§¨¦§¨œ››«²«¦§¨µ¶···Ä¤¤£››””‹’ŒŒ‘Œ…‹„„””‹””‹‰ƒv¦§¨£››¦§¨µ¶·¤¤¤¤²²¬¦§¨¦§¨¦§¨›¢›¤¤””‹””‹¤¤Šƒ}””‹²²¬¦§¨””‹ult”š”Šƒ}‚wlztl£››¦§¨²««¤¤¦§¨£››™…£››£››²««””‹²««ŠŠ}²²¬[[T\UZ²²¬²²¬¦§¨¢—𔔣››¤¤¦§¨ª³·²²¬¦§¨µ¶·Ä¿¾Ƶ¶·µ¶·µ¶·¦§¨¦§¨µ¶·¦§¨¦§¨£››‘ˆ}µ¶·µ¶·ÃÄÆ¦§¨µ¶·²««‹‹‹¤¤µ¶·¤¤›”›µ¶·²««²««²²¬µ¶·¦§¨Ã¼¿¦§¨¦§¨’ŒŒ«²«””‹¦§¨¦§¨¦§¨²¬µ”𔤤‹‹‹””‹ƒ„„£œ¥£œ¥£››¦§¨²²¬µ¶·””‹¤¤¦§¨›¢›¤¤“““‹’Š”š”’ŒŒ‹„„‹‹‹£››››”²««””‹£››£››¢—””‹””‹””‹ƒ||¤¤²««£››””‹£››²²¬¦§¨²««¦§¨””‹¦§¨¦§¨£››‘ˆ}¦§¨²««¤¤ƒ„„£››””‹””‹ƒ||””‹š””””‹µ¶·¦§¨²²¬¦§¨²²¬¦§¨¤¤¦§¨¦§¨¦§¨œ¤¦¦§¨¦§¨¦§¨¦§¨µ¶·œ¤¦¨©´lks)+2?;CLKRdc\ultd\\7-2>/Att{\[[f]c]bZ!:97%lrilridc\ddc:97SKJlddlldSKJƒƒ|:97*)(JHF[[TLKRJHF\[[JHFSKJVTLldd{u{f]ckd\]cdddcred{zmSKJVTL3+*:97%JHF\UZlld7-274,%&$VZTuzttll[[TUTSMSSVZTVTLVTLtlldc\tll[[Tddc[[TJHFJHFUMRekdddcUTS74,@/7 74,73FD;VTLRP:tslredbVUVTLD;9MRKFD;FD;D;9C8.]bZ&&&&3+*FD;D;93+*3)D;9dc\VTL3)FD;%&&0FD;SKJD;9D;9VTL²²¬dc\[[TVTLjcVƒ||SKJ>R.VTLJHFGSu]cd’ˆ|‚z|‚zlrityglldsreD;9SKJsre{{t‹‹‹‚|u{tt‹„„lddf]cMRKƒ}ƒ{tttllek]f]c[[T]cdUMRD;9UUY"%VTLFD;JHF\[bf]cMRKfkktsllri[[T ,55-1+>B9VTLUMRD;9VTLVTLlldSKJ\[[sre{||VTLd\\{ttSKJfkkJHFD;9SKJsleVTLcbV>B9VTLVTLyledc\3+*"FD;FD;d\\D;9Q?@SKJ >B9*)(:97*)(]bZ7-2SKJ3+*dc\zllUTScbVJHFlldtslJHFlldf]cJHF\[[LKR%&-1+,55{{ƒVZ[llkUMRlks]bZJHFF=CLKRf]clddlek\UZf]cMSSSKJf]c>ECf]c74,[[T]bZVTLttstllƒƒ|]bZedk{u{[TT{ttUTSLKR\[bUMRJHFVZTUTSJHFJHFVTLdc\lldultVTLtlldc\uzt{ttSKJSKJSKJ74,UTSf]cf]cJHFkk]JHFD;974,*)(>B9*)(JHF3+*fkkultUTSJHF\UZUMRVZ[[TTd\\lrio€wd\\uzt]bZtsl\UZLKRultuzttts\[[lddFD;-1+FD;>B9%)*)("*)(FD;SKJFD;j]\UMR[[TFD;SKJ:97C8.D;9D;9SKJFD;JHFFD;JHFtllUMR:97SKJb[UVTLFD;JHFVTLD;9F=CPF=JHFD;9D;9SKJJHF¦§¨VTLJHF‰ƒvƒ‚u‚|u‰|v‹„„lri’ˆcbVJHFtsl‹’Š\[bSKJ7-2[TTuzt|„…lldllk…‹‹lrib[UJHFb[Uult‹‹‹„„Šult[[Tlek{{tlldSKJ\[b{{ƒ{{tj]\tllultekdSKJSKJ\UZD;9ldd\[[[[TekdF=CVZ[JHFdc\uztultlri:97]cdfkkMRKJHFttsddc\[bJHF[[Tdc\]bZlriUTSddcVTLSKJUTSf]clri[TTztlb[UVTLVTLlldVTLVTLlddd\\cbVSKJMRKVTLkd\{ttb[UUMR\UZFD;*)(:97[[TFD;[TT:97>EC:97[[TJHFFD;sle[[TMRKVZTSKJVZT\[[>EC\[[UUYUUY>EC>ECJHFJHFUUY]cdJHF\UZ]cdlksddc>ECedkJHFddcj]\UTS\UZ\[[edkbVZf]c\[b[TT:97D;9[[TMRKb[Uek]VZTUUYJHFUUYVTL]cdd\\f]c\[b\[bD;9lriMSSSKJd\\[[T[TTsle\UZ\[[UTSb[Ullk\[bSKJtll\[[SKJSKJ*)(UMRUMRSKJJHF&&3+*:97JHF74,:97JHFLKRSKJf]c]cdf]c]cdedkVTLb[UVZTmtt[[T[[T]bZ[[TUTSu{{ddc{{t{u{lksf]c]bZ]bZVTLlri&&&&SKJaWM[TT[[TVTL[TTb[UFD;3+*FD;FD;VTL74,D;9VTLSKJ[TTd\\[TTD;9SKJJHFdc\JHFJHF[[T[TTJHFbVUUTSaWM[TTVTLtll¢—llkSKJtsl{{t{zm’…‹{u{kk]]bZ|‚zMRKdc\VTLJHF%UMR{||ttsttsŒ”•\[[|„…tzlrfklddult„Š„{||ekdlddldddc\…‹‹ddcb[Umtttt{ldddc\{ttultlriUMRUUY|„…dc\lekmttVTL\[[F=CMRKVTLfkk{u{{ttMSSMRK\[b:97ekdb[Udc\ult\[[:97dc\JHF[TTMRKddcu{{dc\j]\d\\[TTllkSKJkd\j]\d\\tll[[TlddmttVTLlldVTLJHFFD;D;9SKJJHF[TTddcD;9D;9*)(FD;b[U:97SKJsle:97SKJVTLddcVTLlld{||VZTddc{||llkF=CultlrimttJHF]cd>ECLKR:97MSS\[bMSS]cdVTL\[bddc>ECSKJ\[b\[[{||ƒ}ƒ„„ŠJHFddcbVUulttts\[[FD;:97VTL3+*JHFVTL:97d\\:97]bZdc\ekdddcUMRLKRD;9[[T[[TJHFf]cbVZkk]tlldc\zllSKJb[Ukk]edkf]c{u{lek]bZUTStt{f]clddUMRUTSSKJJHFVZTFD;VTL:97FD;FD;lddJHF‚v{fkkVZ[VZ[\[[sleƒ„„lldlkslriJHF[[Tkk]\UZdc\VZTƒ„„{ttVTLlks]bZ[[TJHFJHF&& &&3)[TTSKJbVUkd\f]csleSKJ:97FD;&&FD;PF=FD;VTL[[T[TT[TTb[Ured:97[TT[[TVTLFD;VTLJHF[TTVTLf]cVTLSKJVTLD;9lldš””bVZJHF{zmŠŠ}’ŒŒ{ttlddMRKmttiq]z‚l‹’Š|‚zUMRVZTJHFSKJƒƒ|„Š„tt{d\\lkstts[TTJHF„Š„…‹’{{tlrid\\[TT[TT]bZ[TTddclldlddlldSKJJHFedkUUYJHFlekJHFUMR[TT\[[{zmUTS\[bMSSVTL]cd{{ƒ…‹‹UTSekdSKJLKRddcSKJllkJHF[[TFD;]bZlek]bZek]\UZVZ[UMRkd\lddztluzt[TTb[Ulekd\\{u{FD;VTLmttmttllkSKJMRK74,D;9VTLVTLb[USKJbVZ[TT&&PF=VTLVTL\UZek]>B9D;9tsl\[[ekdkk]mttdc\llk{ttllkSKJ\UZ{{ƒllk\[b]cd>ECLKR:97LKR{{ƒ|‚z\[bf]ctt{MSS\[bVZ[LKRttslldj]\iWUUUYldd[TTf]cf]cJHFJHFJHFFD;JHF[TTtlldc\FD;JHFbVZlldlldddcJHFUMRSKJSKJSKJJHFSKJ{ttSKJkd\ulttll[TTSKJ{zm\[[ult{ttj]\cbV]cd\[bJHFf]c‚v‚\UZkk]jcVVTLMRKVTLsreUMRFD;UTSlek‹„„llkUMRUTS]cd{u{{{tddcu{{]bZuzt[TTsred\\b[UVTLVTL{ttVTLf]cFD;74,VTLVTL>B9 :97*)([[TD;9SKJVTLkd\d\\VTLredb[UPF=FD;sreVTLjcVek]UMRldd[TTUMRlddSKJkd\b[UFD;D;9SKJdc\JHFtll[[TSKJ74,SKJlld£››f]cLKR‘Œ…ƒ‚usle‚v{JHFVTLsreFD;ZbN‹’Šlldf]cmttUMRŒŒš{{ƒŒ”•‹’Šekd””‹ttsttstll„Š„{||‹‹„|„…{||ultsleek]llkdc\ddctlltllddcd\\\[[mtttt{\UZUTSJHFb[U\[[{{ƒJHFUMRVZ[UTStslu{{{||\UZ\[b[TT]cd>B9FD;f]ctt{:97\[[VTLdc\[[TlritslMRKFD;[TT[[Tredtts{zmdc\UTSd\\SKJSKJD;9VTL]bZrfkttsFD;!D;9VTLJHF\[[SKJUMRVTLJHFSKJj]\d\\D;9i\VJHFD;9ztlUTSlek[[TekdVZTekdlddtsllekd\\]cd{{tbVZJHF\[b>ECLKR]cdlkstsl{{ƒmtt{{ƒf]cJHFUTSultlddVTLUMRf]c\UZf]c‚v{lekUTS]cd>B9MRKVTLVZT{{t‹‹‹lek¦§¨fkktlltts{||]bZF=C74,SKJddc|„…lldlekf]cdc\zlltll‹„„‚|ubVUb[Ulekd\\tllultddcSKJSKJf]cUMRldd\UZSKJD;9JHF[[TVTLSKJVTLVTLJHFƒ}ƒŠ}ƒ{{ƒllk]cd[TTd\\sleultleku{{œ¤¦ƒƒ|tslf]cVTLFD;[[Td\\UMRD;974,MSSVTLFD;%>B974,MRKJHFj]\kd\FD;UMRcbVjcVkd\ztfcbVC8.VTLFD;VTLek]VTL[TTkd\PF=JHFVTLjcV{zmd\\PF=FD;SKJ[TTSKJbVUVTLcbV]bZtsl¤¤ek]JHF‘Œ…‘Œ…ƒ„„’ŒŒzllf]clri]bZšŒztlƒƒ|g\rq^„¬¶Ã¨©´œ¤¦µ¶·”››|„…¨©´‹‹„”“›Š~‹tllultuztddcf]c{u{{ttƒ„„“““{{tuztœ››ƒ‚utllultfkk‹‹„f]cSKJ‚v{dc\{u{ddcƒ}ŠJHF{{ƒlrid\\„Š„|‚z\[[UTSUUYlksJHFddcD;9edk…‹’VTL:97lldƒ||{||ttslldldd[TTUTSj]\b[UVTLSKJ:97{u{lddSKJrg]b[Ullkllk{{t{{ƒD;9JHFMRKVTLUTSuzt[TTddcD;9:97sle[TTdc\SKJHR>SKJrfktslmttJHFdc\ttslrilriƒ„„|‚z“Œ”ƒƒ|lek{{t†~‘MSSmtt^fsfkkŒ”•Œ‹“tt{mtt„„Š{{ƒ\[b{||[[T\[bultkd\\[bVZTmttlek“~ˆmtt{{ƒmtt{u{JHF[[Tdc\’ŒŒƒƒ|llktlltsluzt{u{ultllkJHFUMR]cdcbVVZTddcF=Cb[Uƒ||tlltlllddlld{{tdc\mtttllƒ}ƒzlldc\d\\SKJ[TTlekrfkbVZ‚wlaWM74,JHFlriD;9ddctllekdŒ‹“ttszll”“›u{{u{{VTL{zmb[U{{ƒu{{‹’Štllƒ‚utll]bZ]bZztlcbVultUMRF=CSKJiq]MRK3+**)( *)(JHFredsleb[Ub[Ukk]cbVtslVTLFD;ZbNdc\jcVztfFD;]bZbVUtslb[UVTL[TTtslŠƒ}VTLZbNkd\rg]j]\{tt‰|vcbVFD;tll|‚z¦§¨>B9SKJ‘ˆ}›”›‹‹‹Šƒ}]cdjcVmttkk]ekd‹’Šš””ult„Š„‹’Ѝ©´”“›»ÂÇœ¤¦›¢›¬¶Ã‹’Š”š”{{ƒ””‹’ŒŒ{u{{||›”›ƒ}ƒztlª³·››””š”{{ƒ›”›‚|u‹„„ttsllk\[[b[U\[b]cd|‚z“Œ”{u{””‹\UZ]bZlkslld„Š}{||llkVZTMRKF=C>ECrfk[TTMRKttsJHFlddllk|„…“““mtttllj]\redUMRJHFSKJcbVVTLFD;ek]‹„„dc\j]\lldJHFlekttsuzt]bZSKJ]bZ‹„„ult‚|u[TTUTS]cdVTL[[TsleVTLD;9aWMVTLtll{{tuzttsl›¢›{||lriŒ”•“““œ¤¦™š¤‹„„¨©´|‚zzlllksOS`]bZlks]cdtts…‹‹\[b‹‹‹†~‘\[bddcUTS{||‹’Šƒ||{ttddcedkzllf]c{{ƒfkkUMRttsJHFllkVTLlddztl{ttttsdc\lri]bZddcttsVZ[JHFrfkf]cllk[[TSKJ‹„„””‹ƒ}ƒlddrfkjcVslekk]lld‹…’ƒ||‹„„|„…SKJ{{ƒUTS‚v{\[b[TTb[Uuzt[[T\UZkjVJHFD;9VTLllk‹‹‹bVZ{{ƒddc\[[\[[ƒƒ|›¢›lldddcrfktzl{||”š”…‹‹b[UFD;d\\VTL{ttd\\UTSFD;\[[FD;&&%74,>B9uzt{tt{yfztl{zmb[UaWMSKJVTLJHFVTLVTLVTL|‚zkk]VTLkd\lldbVUSKJ[TTkk]sleaWMVTLkd\SKJj]\tll‚utd\\ƒ‚ulektslª³·VZ[SKJzll£››„‰v’ŒŒŠƒ}aWMtts]bZUTSƒƒ|Šƒ}Š}ƒ]bZdc\›”›ª³·¦§¨Œ”•|„…™š¤d\\‹‹„ztlƒƒ|tts{zm“““j]\f]c“““¦§¨””‹«²«¦§¨‹„‹{ttƒ}ƒ\[[‹‹‹Œ‹“\[bf]cf]cŠŠ}ƒƒ|ŒŒšƒ||™š¤mtt“Œ”„Š„tyg””‹{||UUYtt{ttsllkUMRUMRnv‚„„Š\[[ŠŠ}ddctt{{{tƒ„„{{t\[[lddUMRredkd\lldaWMb[Urfklddsletllldddc\lld‚v‚ƒ„„UTSJHFuzt‚v{tllkd\ƒ||LKRJHF]bZb[Uƒ‚uMRKUTSkk]JHFbVU””‹dc\{{ƒsleult|‚ztts{{t{{tult…‹‹…‹‹„Š„tts]cdMSS>ECMSSldd„†™mttf]c}‡’ult{{t]bZdc\f]cSKJf]c[TTleklrif]c’ŒŒ‹„‹tts]cdD;9MRKFD;[[TSKJbVU[[T{ttlldƒƒ|\[bekd„„ŠlritslUMRlld™š¤ttsbVUttsŠƒ}›”›ƒ||‹„„‚|ulldiq]…‹‹ƒ„„{tt‹‹„‹‹‹ƒ||lkslek“Œ”tll™š¤‰|vƒ„„FD;JHF\[[dc\ultlriƒ„„ƒ}ƒllk{||tts{{ƒ{{ƒb[UztflldddcUUYiq]zllƒ‚uddctsl]bZf]cultf]ckk]\[bC8.D;9]bZJHF!FD; 74,VZTtllš””‚wlldd‚wl[TTSKJrg]C8.dc\sreaWMaWMPF=JHFFD;{ttSKJSKJ[TTVTLek]i\VSKJVTLVTLSKJ‚|ukd\VTLsrellktsl²²¬\UZ3+*Š}||‚zrr]‘Œ…tzlrg]ekd|‚zlld‹’Љƒv‚ut!VTL{yf¦§¨ª³·›¢›u{{¦§¨|„…rfk[TTlri™š¤ƒ„„™š¤¦§¨””‹””‹›¢›¦§¨„Š„ƒ„„‹„„‚|uj]\”“›|‚zLKR‹‹„{||tt{|„…FD;ƒ}Šƒ||…‹‹lksƒ}ƒultlri{||lrif]cuztedklksf]ctllttsllkUUY„Š„VTLdc\dc\…‹‹SKJ[TTd\\llk{||ƒ||ƒ„„SKJsle\UZf]cylemwrg]”“›ekdddcƒ}ƒVZ[JHFVTL{{tslekk]tll\[[ekdd\\VTLb[U{ttSKJkk]kd\{u{‚|uldd{zm’ŒŒ{ttƒ‚uŒ”•|‚z{ttlldultyl„tzlddcMSS\[bMSSUUYddc\[bMSSlks{{ƒƒ„„mtt\UZlld{{ƒtsl{ttƒ||f]c]bZŒ‹““~ˆultfkkztfMRKMRKtt{SKJr]ZVTLj]\sle‹‹„{{tlkskk]ttsdc\JHF]cdlri‹„‹Œ”•tll{tt””‹“Œ”ƒ||’…‹””‹ztllldttsŠŠ}’ŒŒœ››”“›|„…f]cf]cultƒ„„‹„„i\Vfkk]bZultkk]SKJ>B9VTLƒƒ|tsl‹„‹{{ƒ…‹’Œ”•mtt]bZdc\{zm…‹‹\[b|‚ztllƒƒ|tt{f]clri‹„„Š}|tllek]JHFsleJHFaWMJHF*)(:97!JHFbVZd\\j]\sle‚|ubVUVTLsleaWMztfztfHI/VTLFD;jcVVTLVTLSKJSKJJHFkjVŠƒ}VTLd\\d\\bVUSKJztl[TTkd\VTLult{tt¦§¨>EC:97{||„‰v„‰v²««™š¤ƒ‚uƒƒ|››”‚v{{||’ŒŒƒ}ƒ*)(&&ƒ‚n¨©´‹’Šddc|„…Š}ƒƒ||VTLD;9‹„„‹‹‹tll“““…‹‹‹„„””‹‚|u””‹”š”{{ƒƒ||””‹SKJ…‹‹tzl{zm„Š„™š¤“““\[[ztfƒ}ƒ{||ƒ„„VTL[TTb[U{{t‹‹‹ztl[TTSKJUTSMRKf]cUMRllklddultlekddcztld\\VTL‚wl\[[rfkkd\Š}|{||b[Ukd\red‹„‹{u{iq]‚|u[TT|„…tslekd[TTJHFD;9[[Td\\‚|u’ŒŒsle{||JHFVZTdc\kk]VTLVTLVTLjcVd\\{{t]bZ{{t{zmƒƒ||‚z”𔛢›Šƒ}ƒ||lek{{ƒtsl{u{{u{>EC>EC]cd\[[\[bmtt\[b{{ƒ”“›ultFD;d\\lkslld[TTlekUMR|„…¦§¨{u{ultŠ~‹mtt[[TVTLllkSKJztlredlld[[TtsluztVZTJHFFD;lriƒ}ƒf]cbVZztftzlš””’ŒŒ’…‹redƒ„„Š~‹{zmsleFD;sletsl“Œ”š””{u{ddcJHFUTSSKJf]c„Š„rfk\[[‹’Šd\\JHFJHFlldMRKƒƒ|ult{{ƒtll{u{{{ƒekdsletsl›¢›mttŠ}|‹’Šƒ||ŠŠ}„„Š|‚z|‚zz‚lƒ||lksƒ}ƒUMR\UZlekb[U\UZJHFVZT?;C3+*:97SKJ‚|uŠƒ}ztl‹‹‹rg]r]ZcbVd\\SKJi\VjcVcbVcbVVTLVTLaWMztl[TT[TTsre‘Œ…jcVredb[Utllred{ttredrg]cbV[[Tƒƒ|µ¶·\[[:97œ››””‹£››£››{u{š””ÃÄÆ””‹…‹’]bZ£››{{ƒ|„…lks’ŒŒ””‹…‹‹…‹‹‹‹‹“Œ”Š}|dc\iWUredƒ||tsl‹„‹“Œ”red””‹‹‹„’…‹cbV‹‹‹£››‹„‹f]cŒ”•fkklri››”Œ‹“Š}|lri]bZldd‹„‹…‹‹\UZj]\lddlldƒ‚uttslekSKJUTS\[[{u{rfkŒ”•bVZJHF[[TŒ‹“llduzt‹„„‚wld\\[[T\[[tll‚|uƒ||{{tlld„Š„f]c‚utb[UUMRztlŒ‹“bVZ„Š}JHF[TT\[[uztdc\‚|uŠƒ}…‹‹\[[“““‹‹„srelddkjVƒ‚nVTLaWMj]\VZTllk››”‹„‹d\\ekd‹’Š„Š}{u{{u{[[T„Š}{u{“““f]cMSSn…{{ƒ~’“…‹štts”š”tt{\UZJHF\[[|‚z|‚zœ››ultlekf]cŒ‹“‚v‚›”›ddcekdJHFmtt…‹’{ttŠ}|{tt{||SKJkd\››”|‚ztzluztkd\j]\F=C\UZSKJ{||{u{kd\‚uttlltllult{u{ztl‚wl\[[{zm‹u…ztl”“›[TT\[b\[[\[[llklriƒ}ƒUTS\[[tllŠ}|mttiq]FD;]bZ‚utƒ}ƒddcVTLddcŒ‹“kd\{tt\UZ‹‹‹ƒ„„tslš””ƒ||›¢›‹’Štyg|„…‹„„f]cUMR\[bd\\ƒƒ|VTLUTS>B9JHFUUY3)JHF‹„‹j]\‚|u‘Œ…‚|uslecbVdc\jcVŠƒ}aWMSKJb[Udc\rg]ƒ‚nrg]d\\rg]lldb[U‹„„ztfaWMSKJlldd\\‘…„ƒ||VTLdc\j]\“““Ä¿VZ[JHF£œ¥²¬µ””‹››”‘…„¢—””‹tslu{{]bZƒ}ƒ†~‘^~Y3+*’ŒŒœ¤¦Œ”•¦§¨™š¤ƒ}ƒ|‚zVTLiWUyle¦§¨£››‹„„|‚zŠ}|slesle‹‹„”š”|„…Š}ƒ“““\UZ]bZ›¢›|‚z„Š„¦§¨‹’Štzl{{ƒllkš””„Š„mttj]\dc\{{t›”›tsltts‹„‹\UZttsJHFSKJd\\lriult{u{{tt‹’Š””‹ƒ||Œ‹“UMRd\\‚ut{ttŠƒ}lddldd[TT””‹‚utš””Šƒ}ultkd\lddttstllUTSSKJUTSddc›”›’ŒŒb[Ulri|‚zƒ}ƒlriœ››””‹sresreJHFlddƒƒ|“““ƒ„„£œ¥”“›„Š„›¢›”š”œ››‹„‹{zm\[b{u{f]clrilri{||uzt{{ƒ…„’{{ƒuzt}‡’ƒ„„\[bJHFVTLfkk|‚z…‹‹{{tultƒ}Šlri‚wl{u{tsltyg›¢›mttlriVTLmw“~ˆsle|‚zŒ”•bVU{zmVTLf]cŒ”•bVZlddŠ}|‚v{zllf]cSKJ‚utultŠ}ƒzllllkcbVkd\{||b[Uƒ}ƒŠƒ}SKJSKJ“Œ”llkŒ‹“…‹‹…‹‹‹„‹]bZekdd\\f]cFD;VTLaWMcbVj]\ddc{u{\[bƒ„„Œ”•‰‘~d\\ekd„Š„„Š„‹‹„‹„„œ››„„ŠŒŒšFD;|‚zŠ}|ƒ}Šƒ}ƒtt{D;9lksJHF:C+MSSJHF MRK’ŒŒttsi\Vlld{{tkd\f]crr]‹’Šrr]ultzllkd\VTLrg]VTLrg]j]\‚|uj]\FD;sletllƒ‚u\[[{yf[TTUMRaWMŠ}|VTL‚|u‹’Š‚|u¾ÆUUYJHF£œ¥£œ¥£››“Œ”ƒ‚n£››¤¤VTLƒ}ƒJHF‹‹‹{{ƒLKRr]gšŒ‹‹„|‚zª³·”š”œ››‹„„kk]Œ‹“›¢››”››¢›Œ‹“”𔋄„‹„„š””kk]…‹‹Œ”•ƒƒ|{||d\\lld”š”™š¤¦§¨{||{tttsl“Œ””“›ƒ}ƒ{||]bZ{{ƒred‹’Šttsƒƒ|ldd{{ƒlek]bZbVZlksƒ„„ƒƒ|{{tllk£››””‹¦§¨¦§¨”“›ƒ|||‚z‚|u{tt‹‹„i\Vredd\\ƒƒ|‹„„’ŒŒj]\\[[tslŒ”•ŠŠ}[[Tƒ||lks\UZtt{sle‚v‚ƒ}ƒ|‚z‚|uf]cuztek]ztlkk]tslSKJ\[[{zm…‹‹ztl””‹Š}ƒ{zmuzt››””››fkktt{{{ƒ‹„‹tts[TTUTSlld[TTtts”››|„…„Š„mtt]bZtt{ekdtslllk‹‹‹ŠŠ}mttd\\UMRekdtlltllleku{{MRK]bZ|„…kd\|‚zkd\‚wlcbV|‚ztslekdlddttslldyleultzll…‹‹{tt‚utSKJzll£››“Œ”‹„„¦§¨‘Œ…‹‹„ttssle{tttslldd|„…{ttultlriuzt…‹‹VTLJHF[[TUTS‹„„FD;JHFkk]rg]|‚zœ››‹„‹tsl|‚z|‚z›¢›{tt{{t”𔄄Ћ‹„£œ¥‹‹‹d\\tt{fkkVTLredtts[TT\UZ:97SKJVTLFD;:97%:97\[[dc\llk””‹ztlb[UjcV‘Œ…d\\kjVd\\aWMdc\VTLPF=SKJylelddVTLSKJVTLdc\{zmrg]{yfrg]bVZjV[zll‚wl{{t‚|uƒ||‹‹„µ¶·\[[74,¦§¨£››””‹£œ¥ldd‘ˆ}rr]b[Uƒ}ƒj]\ljƒ}Š:97SKJztl”“››¢›»ÂÇŒ”•‚wlƒ||llk‹„„£œ¥“~ˆ{||¦§¨¤¤‚v{‘…„kk]””‹›”›{{ƒƒ||œ¤¦’ŒŒ‹‹„””‹’ŒŒ{zm‘…„£œ¥“Œ”‹„„ƒ}ƒ{ttmtt[[Tf]clddƒ}ƒ‹„„{u{tllmttllkŠ}ƒtts{{ƒtsl‹’Š|„…VTL¦§¨››””››‚ut|‚z{||”š”rg]ƒ}ƒ{||sleVZTFD;red‰|vztfsle\[btslŒ‹“‹’Štts{ttldd‹…’[[Ttll””‹ƒ||œ¤¦ƒ‚u\UZultlldkd\cbVztlj]\bVU¤¤‹‹„lri‹„‹ƒ„„uzttslƒƒ|”››ƒ}ƒ‹…’{tt…‹‹‹„‹{{ƒJHFiq]llk[[T{u{{{ƒ|„…mtt{{ƒttsekdVTLddc‹‹„ƒƒ|ttsj]\Š~‹ddc{ttf]c{||]bZMRKmttu{{|‚zŠƒ}{||tsl”š”llk‚|u…‹‹tsltts{tt\UZŒ”•{tt|„…bVUllkredrg]ƒ}ƒ£œ¥‚utƒ„„‰|v¦§¨””‹{tt‚utbVUd\\VTLtllttslksƒ}ƒƒ}ƒÂ¾Æœ¤¦œ¤¦|„…f]c{ttdkVkk]jV[‹’Šllkf]c{zmfkkVTLz‚ldkVœ››œ¤¦”š”„„ŠŠƒ}|„…UTSekd:97r]gUTS:97ultedkJHFD;9dc\,553+*[[TD;9JHF[TTUTS‚|uŠŠ}{{tƒ||zll{zm‚utrg]rg]kd\SKJVTLVTL[[TVTLVTLldd[TTVTLsreƒ‚usreiq]VTLsle‚utredƒ||lld‚wlztlƒƒ|µ¶·\[b:97“““£œ¥‘Œ…‚wl{ttŠ}|‘ˆ}z‚lJHFœ¤¦š””jcV.1SKJ“Œ”µ¶·‹’ŠªÁŲ¬µ’…‹ultf]clld‚v{ƒ||‚v{™š¤ƒƒ|tll‚|u¤¤|‚z¦§¨Œ”•“““™š¤››”ƒƒ|‚wl‘…„›¢›{ttrfk}‡’ult“““œ››lritslƒ}ƒ””‹‹’Štzllrilks‹’ŠŒ‹“SKJf]c{tt””‹ŠŠ}UTS‹‹„‹„‹|‚zred{||‚v{‹„„tsl‚utb[Uztl{||[[Tzllkd\i\VlddŠŠ}ultuztƒ||”š”tllb[USKJ[[Tllk‚v{‹‹„yleldd’‘~[[TMRKkk]d\\SKJkk]j]\ŠŠ}””‹„Š„{{tultŠ}|tslu{{uzt{||¦§¨‚v{„„Š{u{{{ƒ|„…LKR\UZlddllk{{ƒ{{ƒlksnv‚mtt‹’ŠUTSVTL]bZtt{llktllƒ}ƒŒŒšŒ”•Š}|tslMRK]bZ]bZiq]]cdtzl[[Tsre{zm‹’Š{{t|„…|‚zttsƒ||rg]ƒ„„f]cƒƒ|‚v{dc\llkSKJ‚v{{tt£››ƒ}ƒllkztl|‚ztslztfƒ}ƒj]\rfkŠŠ}sle\[[ultekd„Š„Œ”•{{ƒ{{ƒlri…‹’z‚lJHFtzltslyle‹„‹ƒƒ|b[Uuztlrilrilld|‚zŒ”•„„Štt{™š¤„„Š]cdlrisreztlf]c{{ƒ“Œ”tll*)(SKJkd\VTL3+**)(D;93+*JHFJHF{{tztl‘Œ…Šƒ}ztfVTLSKJjcVVTLSKJb[UVTLkk]jcV‚wlj]\kd\i\V[[Tkk]ƒ‚u{{ttslZbNzllr]Zzllyle””‹[TTkd\{{tµ¶·LKRLKR›”›‹‹‹›¢›£œ¥f]c‘ˆ}¢—„Š}tt{““““Œ”j]\JHFUTS’…‹Œ‹“„Š„¦§¨¨©´²««™‹†ldd]bZ‚|u‹’Š|‚z{{tred[TTsle£››mttmttuztš””{{t|‚z‹‹„{{t’ŒŒ|„…¤¤›”››”›{{ƒ{{t„Š}{||{||ult¤¤‹‹‹lld\UZllk{||lddb[Ud\\‚v{uzt‚ut„„Šlri{||dc\jcV{{ƒllkƒ||ƒ„„{tt\[[kd\{ttb[Uƒƒ|tslƒƒ|ƒƒ|sleSKJ‹‹„›”›””‹r]glldf]c\UZVTLŠ}ƒƒƒ|ƒ„„{{tVTL{ttlksSKJtsl[[TJHFš””‹…’‹’Š{{tlriƒ„„…‹‹mttuztuzt|‚z|„…ultllk{{ƒ“Œ”{{ƒlks{{ƒƒ}ƒ|„…edk{{ƒœ¤¦|„…Œ”•‹„„{||sleddcddclldƒƒ|f]cŒ‹“…„’¤¤{tttslVTLVZ[tzl‹…’ƒ„„tsl“““‹‹„{ttddc…‹‹|„…|‚z””‹„Š}‚utƒƒ|‹‹‹mwUTS{{tslelek‚v{Š}ƒŠ}ƒtts‚utsre\[[b[U{ttŠƒ}‹…’“““{{tsleƒ„„‹‹‹lksd\\ldduzt„„ŠŒ”•mtt‹„‹œ¤¦„Š}[TT|‚zttsŒ‹“”š”JHFz}››”llk|„…™š¤Œ”•“Œ”{{ƒ\UZek][[Tƒ||š””tlllksƒƒ|mttSKJzllekd\[b?;CFD;"[TTƒ„„slei\Vsle‚utVTLrr]bVUPF=VTLjcVd\\lldVTLsrelddi\VVTLSKJ‚wlz‚lŠ}|lrirg]b[U{ttbVU‚ut‰|v’ŒŒ‚|ukk]|‚z¦§¨VZTUTSultƒ„„””‹‘}zrg]‘Œ…ƒ‚u–¢‹„Š„j]\j]\bVUMRKSKJ{tt¨©´œ¤¦›¢›”“›µ¶·£››‚ut””‹ztl‹„„{{t··Ä|‚zŠƒ}‚|usle‹‹‹u{{‹’Š{||{ttƒ‚u{zm{tt‹„‹””‹ƒƒ|š””{||Š}ƒ™š¤‹‹‹{ttlri¦§¨’ŒŒ™š¤‚|u‚v{d\\lek\[[]bZ[TTf]c„Š}uztƒ„„bVZ“Œ”ƒ||‚wldc\lddd\\‹’Š{zmtlltsl‹„„{ttj]\ztf„Š„kk]SKJŠ}ƒ|„…£››››”{tt{ttJHF[TTd\\ult’…‹ekdJHF[[TSKJ\UZdc\dc\SKJVTLultult‚|uµ¶·u{{{u{…‹‹|„…‹’Š››”|‚z„„Š{ttŒŒš„„Š£²‹…’\[b\UZult™š¤lksu{{ŒŒš{u{Œ”•kjVu{{\UZJHFj]\]bZ]cd\UZ{tt‹„‹‹„‹„Š}””‹…‹‹tzldc\Œ”•™š¤‹‹„››”{{t’ŒŒ{||sre|‚z‚|uredf]cSKJœ¤¦llkf]cVTLJHFSKJbVUŠ~‹yleš””bVZFD;kd\{yf””‹d\\{zmzll‹‹‹ƒƒ|rfku{{d\\r]g{{tf]cJHFultf]c„Š„]bZ]bZek]{{t‹„‹\[[{{ƒ{{ƒllkf]csleƒ„„„Š„‹‹‹tt{ŒŒš„Š„edk{{t“““ldd‚|u‹„‹|„…jcV{||ekd\[[VZT[TTF=CFD;74,lldf]ctll‚wlƒƒ|‚utVTL[[TVTLb[UVTLb[Ulrikk]bVZddcƒ„„SKJsle{ttVTL{zmƒ‚u|‚ztsllldlddtll‚v{rr]‚wlztf{{t‚wl¦§¨fkkMRKtts£››Š}|‹„„tzl’…‹‹’Š””‹ƒ}ƒjcVVTL|‚zF=C?;C¤¤›¢›„Š„…‹‹ƒ}ƒ›¢›tslsleƒƒ|ƒ„„šŒ|‚z”š”””‹Š}ƒ¦§¨‹‹„ƒ‚u]bZ‹’Š…‹‹”››ƒƒ|{{tƒ||“Œ”rfk²¬µ¤¤{u{tsl¦§¨™š¤lddekd£œ¥ƒ||Œ‹“››””“›d\\ƒ}ŠlldllkbVUzll¤¤|‚z[[Tsreultƒ‚uldd‹„„tsl‚wl‚|u{{t…‹‹tslf]cekdPF=bVUŠŠ}j]\[[T’ŒŒƒ}Šlddtt{f]c{tt:97lldUMRultekd]cdVTLbVUbVZfkk|„…ztltslSKJ{tttsllri‹‹„‚|u{{ƒlri‹‹„„Š„‹‹„œ››‹‹‹ƒ„„fkklkstt{JHFVZ[›¢›g\rmtt\[b{{ƒtt{ƒ„„œ¤¦d\\[[TVTLVTL{zmcbVtts{u{bVU{u{‹‹‹››”“““uztVZTttsuztuzt„Š„ldd””‹››”f]c„Š}„Š„[TTtsl‹’ŠMRK[[T{{ƒ‚v{d\\ƒ||tsl‘…„’ŒŒ’ŒŒf]c››”‚utrg]VTLkd\’…‹{{tlek[[TŠ}ƒtygllk””‹ljVTL[TT\[[|‚zlddƒƒ|dc\lri”››‹‹‹ƒ„„edkekd]cd{{ƒ\UZ[[TŠ}|uzt“““Œ”•{{tmttttsŒ”•lriVTLsle…‹‹lldr]ZD;93+*|‚zkd\{yfFD;JHFSKJjcVMRK‚|uƒƒ|dc\‚utkk]SKJtsl]bZbVUkjVsre[[TtllD;9aWMslesreultj]\sre””‹ƒ‚usreredtts‚ut£››ult‚wlƒ‚u{{t‘…„µ¶·]cdMRK‹„„“Œ”’ŒŒ£››£››™š¤ª³·š…Ž\[[{ttldd]bZ]bZzll‚wlƒƒ|‹„‹„Š„Š}ƒ””‹ƒ||SKJFD;š””‹‹„Šƒ}„Š„ƒ‚u“Œ”š””{tt”››tll‹’ŠŒ”•‹„„{{tŠŠ}ƒƒ|tllƒ||£››|‚zƒ„„¤¤red{||cbV]bZ{u{£œ¥›¢›¦§¨ztl\UZƒ}Ѝ©´|‚zŠ}ƒ‹…’{||tslƒ„„dc\𔔤¤{tt“Œ”‹‹‹ƒ||Šƒ}‹‹„“““slekd\ultsleztlult‰|vtll{ttllktllredUMRtslVTLtts{tt…‹‹{ttekd]bZaWMred‹„„llkƒƒ|‹‹‹””‹kd\Œ”•ƒ‚uœ››¤¤”“›‚|uƒ„„”“›‹’ЄЄ{||ultlek„Š„{{ƒddc]cdf]ctslŒ”•{{ƒ“Œ”lks{{ƒ…‹’j]\VTLFD;[[Tlddƒƒ|‹‹‹ultllk{||„„Šlriƒƒ|{{t{{t{|||‚zd\\‘Œ…‹‹„tzl””‹{{t|‚zƒ‚u‹‹„Šƒ}[[T3+*lektllyfltsld\\lddŠ}|‚ut{tt‚wl{u{VTLcbVŠ}ƒƒ||‹„‹‹‹„[TTVTLVZT‚utƒ„„tsl…‹‹{u{{yfmtt\[[{u{kjVŠ}|ƒ„„“Œ”¦§¨“““™š¤tzl|„…lkslldkd\„„Šllku{{‹‹„‹‹„|‚ztt{””‹VTLƒ‚usleJHFbVUUTS:97UTSD;9VTLiq]JHF%PF=b[Ulekrg]„Š}|‚zƒ||‚|utslkk]kjVVTLdc\llkdc\JHFb[Ukd\[[Tb[U{tt‚wl‚wl‰ƒvtsl{zmš…Žred²««‰|v¤¤sleŠŠ}‘ˆ}‹‹‹¦§¨\[[JHFŒ”•¦§¨“Œ”‹„„ŠŠ}‹’Š‹’Šultdc\dc\‹„„kd\VTL’}™£›››¢›””‹«²«…‹’{{ƒ[[Tdc\b[U¦§¨””‹kd\›¢›lri’ŒŒƒ||””‹Šƒ}tzluzt|‚z™š¤sre›¢›””‹tllr]gz‚l‹‹„lri””‹¤¤››”‚|u”“›Š}ƒš””””‹ŠŠ}ƒ„„‹‹„|‚zttsVZTŠ}|{{ƒtsl[[T‚|u‘Œ…ŠŠ}‹‹„ƒ||llk“Œ”tllƒƒ|‘Œ…tslŠƒ}Šƒ}lddred‹„„aWMtllƒ„„cbVJHF[TTult{u{j]\UTSllk„Š„Œ‹“ztl|„…››”tzlkd\ultƒ„„{{tŒ”•’ŒŒ‘…„›¢›ztltslkk]‚|u‹„‹{||lkscbV””‹mttŠŠ}›”›‹…’lksJHFuztmtt|„…ulttt{ŒŒš…‹š„Š„{||mtt\[[{zmSKJMRKlek‘…„ult„Š„„„Šult[TTlritsl|‚ztsllri…‹’{tt””‹µ¶·ƒ„„Œ‹““““‹‹„ƒƒ|š””|‚zdc\b[Uedkrfkred‹‹„[TTƒ}ƒŠ}ƒ‹„„Œ‹“””‹‚v{[TTkk]‚|u‚ut‰‰w‚v{lldƒ||SKJd\\tll{||j]\mtt„Š}ƒ„„tsl{zmztl|‚zª³·¤¤“““ƒ}ƒf]c]bZu{{{ttƒ||ztlred…‹’‹‹‹u{{Œ”•Œ‹“””‹tsl‹‹„ƒ‚u|‚zƒƒ|UMR7-2SKJFD;MRKLKRtt{3+*73JHF[[T‚utsledkV[TTPF=VTLFD;bVZƒ‚u‚|u{zmtsl]bZ{||i\VztlSKJ‹‹‹edk„Š„¤¤‚wl|‚zr]Zljzll‰|vlj‚|uŠƒ}ƒƒ|‚v{¦§¨[TT:97ƒ„„tsl’ŒŒƒ‚uuzt£››Œ”•””‹„Š„\[[Š}|lld]cd“~ˆ””‹›¢›””‹””‹f]c[TTb[Uyletzl{{ƒztl„Š„””‹[TT“Œ”bVUƒƒ|’ŒŒ{{tddc”𔋄‹lrisreVTLtllult‹‹„kd\Œ”•”š”ƒ‚uš””‹„‹|‚z™š¤””‹{zmŠƒ}›¢›lritzl{tt‹’Ф¤‹‹‹ƒ„„{{ttslkk]ŠŠ}red‘Œ…“Œ”tsl‚ut’ŒŒztllri{zmaWMƒ‚ujcVd\\SKJVTLkd\{u{\[[lri{{tf]cSKJ{{ƒ[TTrfkttsƒ||lri’ŒŒ’ŒŒyfllek‹‹„{{tult{ttsresre{zmŠŠ}sretll‹„„{||lri‹„„kk]{||{{t“Œ”ultf]cVTLVZ[|‚z]cdmtt‹…’llk„„Šƒ}Šttsdc\MRKjcVtslztl””‹ultf]ctslult£››Š}ƒ„Š„dc\|‚zVTLttsultƒ||’…‹‹‹„››”›¢›„Š„Œ‹“‚|uztliq]lriSKJu{{UMR|‚zSKJf]cŠ}ƒ’ŒŒ‹‹‹‹…’{||ƒ}ƒf]csre{u{lddŠƒ}ultuzt\UZVTLlrilld‹‹‹{u{ddcek]lddkk]b[Usle„Š„ƒ}ƒ’…‹‹…’’ŒŒœ¤¦‹…’\[b””‹{zm…„’ztl{||‹‹‹|‚zƒ„„„Š„„Š}]bZƒ‚uƒ}ƒ|‚zttsmttlks[[TVTLFD;74,UTS3):97iq]dc\|‚z{{tVTL‘…„‚|uƒ„„cbV[TTVTL|‚zsle\[[VTL‚|uztlŠƒ}ƒƒ|edktll‚wl‚|utsllldd\\d\\Š}|ztlƒ||ƒ‚u{zmƒ‚u‚v{£››UTS*)(‹‹‹“““‘Œ…ztfVTL‰|vlriVTL”š”llkr]Zb[U:973+*‹’Šœ››¦§¨rfkyfl‚|ubVUVTLFD;redƒƒ|””‹››”ultult‹„‹”“›Œ”•‹’Š¡¡¨©´Œ‹“{{ttsl£œ¥‚v{lri¦§¨‹‹„…‹‹‹‹‹““““Œ”‹‹‹lks™š¤™š¤‹„„””‹”š”„Š„uzt›¢›”š”””‹tt{‘}zedkaWMek]‚|uztfzll‹„„ƒƒ|tll{tt‚wlkd\rg]sleŠ}|ztllrir]gSKJf]cb[Uekd‚|u{ttŒ‹“d\\UTSult‹‹‹ƒ„„‹„„tslsleƒƒ|kd\uzt‹…’„Š„lkskd\SKJlld””‹|‚zlld…‹’‹„„„Š„Œ”•{{ƒtzllldlldŠ}ƒddcf]clksJHF]bZmtt\[[tt{ƒ}Š{{ƒu{{…‹‹bVZFD;tslddclld‚|uu{{lks{{tƒ„„ƒƒ|’ŒŒ{{tuztekdUTSŠ~‹ztlŒŒštt{‹‹„£››‹„„uztŒ‹“{{tztlŠƒ}kjVuztŒ‹“ultjV[””‹‰|vjV[‚v‚ƒ||„„Š‚utf]c{{tcbVƒƒ|{||‘Œ…“Œ”ztfultb[Uttstll””‹ddcƒ„„MRKlriVTLFD;lld|„…llk{u{llkš””’ŒŒ™š¤“Œ”mttœ¤¦ƒ„„‹‹„‹…’™š¤llkŒ”•tt{ŠŠ}”𔦧¨“Œ”lriekd]cdf]cbVUVTL>B9FD;:97FD;&&C8.{{t„Š}‹‹„kk]ultsleulttslJHFVTLVTLsre]bZVTLbVZlldlddcbVlld’ŒŒ„Š}‚wlttskk]ƒ||ƒ||Š}|‚wlbVU‚|usrei\V‚|u‘ˆ}>B9:97››”ƒ„„‘Œ…””‹jV[bVZu{{i\Vekdllkkd\aWMVTLJHF¤¤™š¤™š¤|„…tts{u{sle\[[tzlr]gtslldd|‚z’ŒŒƒ||“““£œ¥ƒ||lri|‚zƒƒ|™š¤‹‹„SKJ„Š}™š¤{|||‚zkk]tsl|„…“““ƒ„„Šƒ}VZ[™š¤‹„‹›”›’ŒŒ‹‹„‹’Š|„…{zmƒ}ƒ””‹„Š„ztflld{zm{||„Š}SKJb[Uƒ„„ƒƒ|[TTredzllztllddƒ‚uylelj{u{tllƒ||llktllƒ„„””‹ƒ„„ultb[U{{ƒJHFtsl{||lriƒ‚u‚v{]bZƒ}ƒ|„…Šƒ}u{{tts‚wlsle‚|ulld‹’Ц§¨‹„„ƒ}ƒ„Š„ztlŠ}|ƒ‚udc\ekd’…‹rfk{{ƒmttF=C>EC]bZf]c”“›…‹’…‹šƒ„„”››dc\\[bVTLVTLUTS‚|ui\VF=Clld‹„‹‹‹„ª³·‹’Šiq]dc\[[Tƒ„„ƒ||{||šŒƒ‚u›¢›„„Šuztuzttsl””‹›¢›Œ”•]bZ™š¤redultƒƒ|rg]f]c[TT|„…‚v{Œ”•ƒ}ƒ|‚z‚|u‚v{Š}|{zmƒ||ƒ„„redbVUUTS{u{lldƒ|||„…lri|‚z‹‹‹kd\d\\kk]u{{ult\UZšŒtts\UZtt{…‹’¨©´’ŒŒ™š¤”››‹„„u{{{||‹‹‹”››ƒ„„¤¤‹„„lrilld>EC%FD;74,FD;SKJVZT3+*&&C8.yle|‚zƒƒ|ƒƒ||‚z‘Œ…Šƒ}JHFJHFlri]bZVTL:97VTL{u{tzlŠ}ƒlddrfkllk{zmlriƒƒ|VTL‘Œ…rfkŠƒ}‰|v{u{””‹Šƒ}‚utztfµ¶·MRK*)(‹’Š‚ut|‚z‘ˆ}{zmJHF|‚zllkuztlekttsi\VD;9D;9‹‹„«²«ŠŠ}Œ‹“””‹{{ƒcbV[TT‹’Šedk‹‹„ƒ||¤¤’ŒŒ™‹†‹‹‹’…‹b[Uƒ„„lri¦§¨ª³·””‹kk]Œ”•”“›ddclldVTLekdSKJj]\F=Cj]\{{ƒ„„Šƒ„„››”’ŒŒsle]bZlld{zm‹‹‹””‹‹’Šrg]ddcf]cj]\‹‹‹š””“Œ”j]\ddclddŠƒ}š””tzlztlsleƒ}ƒ‚ut{||Š~‹“Œ”fkkŠ}ƒ|„…tslmttf]ctslUMRSKJ‹„‹lksslef]clddddc{{ƒŒ”•‹„‹tslƒ„„tts’ŒŒlriuzttslz‚l{||‚utsreƒ||’ŒŒ…‹‹uztVTLtllultddcedkekdLKRu{{lkstts…‹’œ››Œ‹“”“›{tt{{ƒj]\MRKVZTrfklektsluztƒ}ƒ“Œ”“““ttstsllks‹„„…‹’„Š„ttsƒƒ|lldŒŒšŒ”•‹‹‹{||ldd“Œ”‰‘~„Š}mtt{{ƒ“Œ”£œ¥‹’Š‹„„lek‹‹‹ƒ||tts”“›‹„„ƒƒ|ƒƒ|‘Œ…‚wl››”£››b[U\UZtllrfkldd‚v{”››”››|‚zƒ}ƒ„Š„j]\‚|uSKJ{{ƒJHFddcredult„„Štt{ult‹„‹{zmµ¶·”››ultldd‹‹‹…‹‹”››‹„„¤¤‚utlldllk]bZ:97aWM3+*C8.Q?@F=C%&&&tlllri{zm‘Œ…VTLƒ||VTLƒƒ|ztl{u{JHFVTLlldJHF\UZ[TTtsllddtlld\\tts[[Tsre[[TVTLkd\kd\ŠŠ}£››£››rg]Šƒ}sle‚utµ¶·MSS:97tslƒƒ|“““‚wlekdJHF|‚ztt{uztdc\|„…rg]74,bVU…‹‹”››””‹“““UTS{||ddcekdlritsl‹‹‹’ŒŒ‹‹‹‹‹‹Šƒ}sleƒ„„””‹llkVZ[‹’Šœ››‹’Š{tt\UZ„Š„{||ƒƒ|VTLSKJ]bZ’ŒŒœ›››”›FD;[TT“Œ”¤¤¤¤‹„‹‹‹„œ¤¦””‹|‚z¤¤mttrg]tts‘…„‹‹‹d\\rg]Š}|{ttƒ„„‹„„kk]tsllldtsl‚v{{zmkd\ldd’ŒŒƒ„„mtt„Š}ƒ}Š‹„„ƒ„„{u{f]cultUMRztlult’ŒŒj]\Š}ƒkd\llkƒ||lri„„Š{||ttsf]c[[Tsreƒ„„‹‹„‹‹„{tt””‹{||ttstsl{tt{||‹‹„Šƒ}lek{ttuztMSSmtt“Œ”{u{ek]{u{{u{f]ckd\lddd\\SKJtsl’ŒŒf]cdc\{{t[[Ttllf]c\[[u{{mtt{||ekd‰|vŒ”•kd\””‹‚|u›¢›²¬µƒ„„Œ‹“‹‹„{ttVTL[[TVZTlri‚|uœ¤¦Šƒ}“Œ””››ƒƒ|{u{tsl{u{{tt‹‹„‹„„‚|u|‚zllkultlddslej]\{u{j]\‹‹‹ƒ}ƒƒ„„tzl“““‹‹„Šƒ}UMR[[Tj]\{tt‹„„ultf]c\UZ‹‹‹slerg]‹‹‹f]c{tt„‰v‹’Šfkk””‹f]ctsl\UZŠ}ƒ{u{{{ƒ:97lldmttF=CFD;>B9FD;|‚zj]\|‚z|‚z‚wlsletzlaWMrfk[[T[TTlri{zm\UZ‹’ŠlddcbVtsllldSKJttsttsVTL[[Ttllsre[[Td\\{zmrg]lldrg]ƒƒ|‰|v{zmÃÄÆJHF3+*{{t””‹”𔢗rr][TT”“›|„…ƒƒ|llk{{t‚|uC8.JHF{{t“““uztœ››{{t”“›ƒ}ƒlksdkVŒ‹“lld‹’Š‹‹„ƒƒ|‹‹„¦§¨œ¤¦\[[|„…ƒ„„‹„„£œ¥ztl‹‹‹“““tzl””‹|‚z“Œ”lri£œ¥ƒ}ƒ{u{‚utultª³·{{t’ŒŒ‹„„‹’Š‹‹‹tslkd\””‹jcVš””‘Œ…ƒƒ|‚|usleƒ„„‘…„r]gyledc\d\\‚|ulld{{tsletllrfklddllkyleœ¤¦ekd{u{edktzl{zmlekf]c{{ƒVTLrfk‹…’””‹]bZ|‚z[TTŒ”•{u{ƒ„„tzl”š”fkk{{t””‹redlri””‹‚v{lld[[Ttslzll’ŒŒ|‚z{{tƒ}ƒ’ŒŒ…‹’lek{||Œ—££››‹…’Œ‹“{{ƒ{{ƒ{u{ttsttsfkkd\\\[[‹’Š™š¤zll{u{››”ƒ||ƒ||¤¤]cd|„……‹‹“Œ”|„…››”Œ”•‚utƒƒ|tsl“Œ”””‹Œ”•œ››””‹ƒ„„JHFmtt{{t…„’‹’Šœ¤¦«²«‘Œ…ƒ‚uult””‹“Œ”tt{kd\{zm’ŒŒ‘Œ…sre{u{\UZlekult’ŒŒ“Œ”š””‹„„|„…lrirg]””‹iq]ƒ||“““ttsldd‹„‹[TT“Œ”ultƒ||lldredlld‚v{“Œ”Œ”•ƒ||“Œ”ƒ„„¤¤kk]u{{“Œ”VTLb[U…‹‹\[bSKJ{{ƒr]gUMRƒ‚uVTL]bZJHF\[b{||‚|u“Œ”dc\kk]ultrg]\UZtsl„Š„tzlddclddu{{tts{{tVTLredUTSUTS]bZdc\]bZrg]SKJrg]{yfkd\i\VSKJsreldd¦§¨SKJ:97””‹‹„„{zm‘Œ…]bZttslri„Š„ƒ‚ukd\dc\rg]PF=bVU‚v{œ››”š”œ¤¦ztl”“›Š}ƒtsl„Š„”››ƒ||“““¦§¨‹…’‚ut{||ddc‹‹‹b[Utts””‹Œ‹“lddkd\lrilritzlŒ”•ƒ‚u„„Š‹„‹µ¶·„„Š“Œ”tts¨©´Š~‹£››d\\dc\ldd…‹‹jcVVTL{{t{ttztltslƒƒ|ztl{{t’ŒŒŠ}|Šƒ}rg]mw{zm{zmredrg]‚v{lddred”“›ult‚v{fkkd\\‹„‹kk]ƒƒ|‹‹„‹„‹lek\[[kd\ƒ}ƒtllƒ„„|‚zek]uztŠ}ƒuztlri‚|ufkkƒƒ|”š”{tttslƒƒ|{tt“““‹’Š“““lddƒƒ|”𔋒Йš¤ulttllb[Ukk]|„…œ¤¦™š¤Œ”•£œ¥fkk|‚z‹‹‹{tt[[Tslelri„„Š|‚zŒ”•¦§¨‹’Š{||‹…’{{tVZTdc\\UZ|„…|„…llkŒ‹“ƒ„„“Œ”‹‹„£œ¥ƒ}ƒ›¢›ƒ||ekdttstts”“›{u{””‹{{tttsztluzt£››‹„‹‚v{tlld\\sre‹’Š’ŒŒ‘Œ…{tt‹„„d\\Š}ƒ{{tldd[TT…‹‹lldbVU’ŒŒ›”›tll‚utllktzl‚|ubVZlekllkSKJlri[TTttsd\\{zm’ŒŒ¨©´„„Šƒ||ƒ„„“““›”›‹‹„tllbVZkd\„Š}]cdu{{:97{{ƒJHFD;9”š”|„…]bZ:97dc\{||rg]‚wlekdtslztlllkultsrettsŠ}|mtt{{ƒ{tt|‚zš””{||ƒ||d\\slesrett{ŠŠ}b[Ub[UcbVrg]””‹cbVjcV‚wlrg]µ¶·ddc*)(‹’Šœ››„Š„zll›¢›u{{lld„„ŠsleUTScbV{zmHI/ultult¤¤‹’Š‹’Šred™š¤f]c{zm‹‹‹tts{{t”››‹„„£››ult¦§¨ult…‹’dc\{||tts¨©´”š”„Š„„Š}…‹‹Œ”•ƒ||cbVtt{{{ƒ£œ¥tts‚ut‚v‚ddc”“›š””ƒ||f]c‹‹‹UTSkk]lldVTL{{tƒƒ|‚|ud\\ztlsreƒ||‘Œ…‰ƒvbVU‚utlrilldVTLVTLd\\kd\b[U]bZ’…‹{{ƒJHFd\\ultek]tslƒ||ƒ}ƒlri]bZdc\lek]cduzt{{ƒkd\b[UUTSult„Š}slelek””‹ek]‹„„tsl{{tred{{t{zmj]\lkscbV{{t|‚zult’…‹kd\lekUTS{{ƒekd{{ƒ”“›“Œ”{||ƒ„„œ¤¦‹‹‹‹„„›”›„Š„‹’Š{||tllƒ„„ek]tt{ƒ}ƒ{||‹’Šlldlek{{ƒŒ”•tslŒ”•‹’Š’ŒŒ›¢›“““”“›”š”ƒƒ||‚zmttf]c]cd…‹šddcztl|„…ƒ‚u|‚zuzt„„Š‹„‹{{ƒf]clksƒƒ|¤¤«²«››””𔄄Š{u{zllult‹‹‹fkk“Œ”’ŒŒ‹„‹‹„„tlllldsle‚|u£››{{ƒƒ||lrildd‚|ubVUttsultztfŠƒ}tll…‹‹rfk{{t…‹‹‹„„cbV{||mttƒƒ|UTS]bZUMRD;9\[bekdzllVTL{ttedkSKJ>B9f]c{zmredVTL„Š}Š}ƒb[U\[[{{ƒfkk‹‹‹{||lks{{ƒ[[Tllkdc\dc\‹‹‹u{{Šƒ}‹„„„Š„dc\lri‹‹„{zm””‹›¢›ljsle‰‘~²««[TT:97››”””‹¦§¨’ŒŒuztttsj]\f]cVTLbVU{{t{ttFD;JHFyfl‘Œ…zllmtttsldc\d\\kk]”𔓓“‹„„”››””‹…‹‹šŒŒ‹“lks‹’ŠŠƒ}llk„Š„µ¶·œ¤¦…‹’{|||‚z|„…{||ƒ„„uzt‹„‹”“›ultšŒlrittsœ¤¦’ŒŒ{tt„Š„ult{||sleŠŠ}£››{zmslesreVTLtllsre’…‹i\V‚wlultš””lldztllldtllkd\VTLSKJƒƒ|ƒ}ƒlektslzlllriVTLd\\{ttultuzt\[[VTLrfkttsttsuztkd\b[Ulriƒ}ƒ{zmrfkJHFJHF74,b[U{{tVTLllktslsrelriƒ‚utsl|‚z‹„„ult‹…’bVU{u{ekdmttfkk£œ¥ƒ}ŠŒ‹“¦§¨{{ƒu{{f]cƒ}ƒJHFcbVllk‹’Š„Š}{||‹„„…‹‹£››{||lldŠƒ}|„…Œ”•Œ”•|‚z…‹’ƒ„„‘…„‹’ŠŠ}|{{ƒu{{JHF]bZredyl„lksllksreztf|‚z’ŒŒ’ŒŒ¤¤{{t{u{‹…šf]cd\\lldsle‹‹„|‚z„Š„Œ‹“\[[tllztlred“““{ttŠ}ƒtll…‹‹ek]bVUtsl‹‹‹²««š””‚v‚{{ƒŠ}|ultekdlek‹„„yle‹„„œ››œ››lld‹‹‹“Œ”tzl{||slemttuztMRKVTLJHFFD;FD;tzlD;9lldsre]cdJHFJHFddcaWMrg]VTLtslƒƒ|edklddlek{{ƒllkUTSddc{tttzlult{||llkultŠ}|ƒ„„‹‹„{{tSKJi\V””‹{zm””‹£››¤¤{||ŠŠ}‹‹‹VTL:97‘Œ…„Š„‹„„‰ƒv‹‹„ƒ„„‹‹‹[TTjcVkk]kk]VTLbVU%UTStslƒƒ|…‹’{{tlrid\\lksuztœ¤¦ldd””‹“Œ”{||¤¤“Œ”“““””‹ƒ}ƒ”››››”£œ¥z‚l¦§¨‹„‹ekddc\ƒ||…‹‹ƒ„„\UZultkd\‚v{VTLddc”š”lek›”›“““œ››lld›¢›ult‹„„kd\rg]‚|u{{tlddlrid\\ŠŠ}›”›‚wlred\[[sref]c‚|uVTLSKJVTL‚|uultredfkkd\\|„…dc\lldlektlllld[[T‚v{f]c{ttlri„Š„d\\zlllriultztl\[buztddclldrfkuztcbVllk‹‹„„Š„Šƒ}{||lddƒ}ƒ|‚zƒ||Š}ƒmttŒ‹“lks|„…”››tsl]bZ|„…ttsƒ}Štts\UZtts]bZultlldlks‚|uƒ||tllldd£œ¥ƒ„„llk…‹‹‰Š¡ƒ}ŠfkkŒ”•„Š„‹‹‹lld››”“Œ”‹’Š‹‹„›¢›\[b„Š„lldtt{d\\dc\„Š}ƒ„„‰|v‚|u‹’Š„„Šƒ„„‹„‹edk{||[[T‹‹„{{tƒƒ|‹„„‹’Š™š¤’ŒŒr]gŠ}|‹„‹‹„„œ››{{ƒ|‚zrg]llk‹‹„‚|uƒ}ƒƒ„„ƒ„„ƒ||rfk“Œ”‹‹‹tt{{u{zllkd\Š}|tt{sre‹’Štllƒƒ|\UZddcek]…‹‹‹„„|‚z\[b>B9\[[ddc\UZVTLJHFC8.JHFFD;ddcylecbVztllriztlllkddclek{ttttsllkllktts””‹‹„„ddclek{tt|„…tsl’ŒŒsrerfkcbV‰ƒv‰|v£››””‹‰|v“Œ”‚|u¤¤VZ[JHF‚|u{{tœ››Š}|ƒƒ|{{ƒ™š¤†~‘lldtllkk]‰ƒvsleD;9UMRultsle{{t‹‹„“““uztu{{Œ”•“““››””š”™š¤‘…„ult‚utldd[[T’ŒŒddcŒ‹“‹‹„“““Œ”•š””tts”››‹‹„Œ‹“”››œ¤¦“Œ”Š}ƒ¦§¨b[UllkŒ”•£œ¥›”›|‚ztslœ¤¦llklldlldrg]cbV‚|uVTLj]\{{tztlztl‹‹„red“Œ”d\\ƒ‚u‹’Š{ttFD;cbV{{t¤¤’ŒŒultztlSKJ]bZMRKkk]ƒ}ƒ“Œ”u{{tsl››”“Œ”‹’Š|‚zu{{Šƒ}‹‹‹ttsƒ}ƒylef]c›¢›]cdlridc\”››‹’Š{ttœ¤¦{zmultlld{||tllllk{u{ƒ„„[[Tdc\]cdlks…‹’lks‹’Š{{ƒtt{lks‹uŠbVZldd\[[{tt\[[]cd‚utƒ}Štllƒ}ƒ“““‹’Šƒƒ|Œ”•‹…’lks··Ä‹’Š‹’Š“Œ”’ŒŒkk]“Œ”›”›ttsuztllk{{t{||edkJHF“““‘Œ…”“›‚utuzt””‹›”›lek‚v{Š~‹tlltsl’ŒŒlriƒƒ|‹„„”“›ƒ||ultj]\‚|utts{ttlddƒ||b[Usleš””lri””‹“““{||Œ‹“ƒƒ|”“›“Œ”ƒƒ|‹„‹“Œ”ƒ||š””“““{{tslemttjV[tsl‹’ŠŒŒšllkmttSKJMRK]cdJHFD;9JHFSKJD;9fkkaWMedk‚v{ddcrg]{zm››”lld{zm„Š„tts„„Š{u{bVU|‚ztllƒ}ƒ“““|„…‹„‹lddttsŠƒ}lldŒ‹“tslrg]b[Uƒƒ|ztlƒƒ|‰|v‘ˆ}rg]››”µ¶·UUYLKR‰ƒv¤¤Š}ƒ™‹†ƒƒ|[TT{ttuzt‚|uƒ„„i\Vrg]FD;VTL[TT{||dc\|‚zƒ||tts]bZ\UZ››”’ŒŒŠ}ƒœ¤¦ƒ„„‹„‹‹’Š’…‹‹’Š|„…tt{dc\ƒ}ƒƒ„„„Š}jcVzll…‹‹lri¦§¨‹„‹„Š„ƒ„„lks“““›”›ekd‹…’‹‹„¦§¨¦§¨”š”d\\lks›¢›tslŠŠ}srerfksre{{t‘Œ…””‹‚ut‹„„›”›jV[Š}ƒ{||ƒ‚uƒ||tzlek]cbVmtt[[T‹„„lekSKJlld|‚z››”’ŒŒ’…‹‚ut|‚z[TT””‹…‹‹tsl|„…‹‹‹slelldFD;sreƒ||“Œ”|‚zƒ„„{{t‚|uƒ„„ƒƒ|”“›‹‹„‹‹„‹„‹£œ¥“Œ”‚v{‹’ŠŠƒ}{ttultuzt|„…MSSmttu{{ttsllklkstt{{||Š}ƒlekuztƒ‚uddcultttsƒ„„{{ƒ™š¤ldd”“›”š”™š¤··Ä„„Š|‚zfkk“““‹…’”š”tslztlƒƒ|uzt‹’ŠŒ‹“‹„‹‹…’tlllekdc\‹„„‹’Š“Œ”‘…„‹’Š›”›’…‹¨©´ƒ||VTL„Š}ƒ||ƒƒ|Œ”•{ttŒ‹“”“›””‹tts“Œ”u{{ƒ||ƒ„„’…‹‘Œ…‚wllks|‚zkk]ƒ}ƒsle“Œ”Š~‹‚v{œ¤¦redrfknƒ’…‹£››“Œ”tslŒ”•cbVztlƒ‚u{||ŒŒšƒ||UTSFD;ZbN:97:97SKJ[TTcbVsreSKJVTL[[T{u{[TTsleult‚wlcbVŒ”•dc\{ttlekƒ„„ztlnv‚mttƒ}ƒ‹‹„ƒ„„tllf]clddcbVdc\‹„‹kk]‘ˆ}ƒ||ƒ‚u””‹””‹‚wl‚|u£››“““¤¤\UZ>ECztf›¢›‹„„rg]iq][[TŠ}ƒllkztlkd\tts””‹redFD;{tt{tt‘…„|„…|‚zŒ”•ekd{{ƒ‹„„ƒƒ|ƒ||¦§¨¨©´²¬µ£››“Œ”‹’Šmttƒ„„tll{{tekd››”kk]Œ‹“‹‹„ƒ„„™š¤tt{”››‹„„Œ‹“‚ut“Œ””š”ekd’ŒŒŒ‹“‘Œ…{{t””‹tt{ƒ„„”𔋋„””‹Š}|‹„„{{tjcVƒƒ|ƒ||””‹‚wl{{t\[[d\\lld{||iq]rfk„‰vdc\d\\[TT\[[tts””‹llk|„…š””’ŒŒ‚v{ƒ„„f]csle{u{ƒƒ|…‹’lldSKJd\\tll‹‹‹‚|u£œ¥ztflld‹‹„””‹uzt{{t“Œ”Œ”•‹„„|„…‹„„œ››ƒ„„Œ”•ztlbVZddctsllld}‡’|‚z{{ƒddcŒ”•ƒ„„lksƒ}ƒddc“““\[[{||tt{{{ƒ””‹‹„‹„„ŠšŒ{tt“““ƒ||¨©´™š¤›¢›lkstt{ƒ„„…„’””‹{{t{u{œ››”“›Œ”•„„Š…‹‹‹„‹™š¤lriztlrfkf]czllztltsl›¢›ƒ}ƒƒ„„ultldd|‚zƒ||‹‹‹dc\‹‹„£œ¥š””b[Ukd\{zmtslŠ}|Œ‹“‹„„””‹ƒ||ƒ}ƒlriSKJrfkultf]cƒ}ƒ“““lks‚|u™š¤ƒ}ƒš””Š}|ƒ||Šƒ}‹‹„„Š„””‹{zmƒ}Š|‚z’ŒŒttsb[Ullk\[bFD;%UMR[TTtzlJHFVTL’ˆVTLlriŠ}|kd\Šƒ}ƒƒ|llkttsllkddcllkƒƒ|ult{{ƒ{u{„Š„Œ‹“u{{lksult‹‹‹‹„‹{||ƒ‚u{tt››”¤¤””‹‚|u‚v{¦§¨‰|v‹’Š›”›UMRJHF{{t””‹j]\‚|uttsb[Ub[Ured‰|v‚|u{ttztlD;9FD;{{ƒ“Œ”sle|‚z‹‹„œ¤¦llk[TT|‚z“Œ”‹„‹„Š„‚v‚µ¶·››”|„…œ¤¦mtt…‹‹|‚z”š”|„…{{tƒ„„{||”“›{||ƒ„„lkskd\f]c{u{‘Œ…{tt‹„„ƒ}ƒ¨©´{ttrg]‚|uldd{u{Š}|tllkk]tsl’…‹[[TVTLš””|‚z“Œ”‘Œ…‰‘~‰‰wtlllritsld\\JHF’ŒŒƒƒ|tslƒ||{tttts\[bekdllktsl‘Œ…‚|u‹„„lritlllek‹„‹|‚zdc\‹‹„lldttsd\\‹„„bVUtlltts[[T[TT{{ƒttsVTL{u{›¢›lridc\Š}ƒƒ||ƒ||‹‹„lddf]c{{t”š”{{ƒmttfkklldmttuzttt{lksVZ[{||ztlVZTƒƒ|llkultŒ”•’ŒŒ\[b‚v{‹’Š«²«ƒ||™š¤¦§¨¦§¨Œ‹“{{ƒu{{™š¤”“›ƒƒ|›”›ƒƒ|‹„‹|„…µ¶·›¢›™š¤„„Й𤋒Šf]csre‹„‹tllllkkd\‹„‹‹„‹{||d\\llkult””‹tts‹‹„]bZ‹„„lld[[TSKJult‚v{{||’ŒŒ“““{||“Œ”tzli\V{tt„Š„Š}ƒ‹„„š””fkk\UZ{u{tllƒ||redƒ„„””‹ƒ„„„‰vuztdc\{||ekdj]\tlllddVTLMRK[[T>B9\[[kd\tsl\[[MRK*)(u{{{||redj]\‹‹„œ››ttsekd[TT[TTddc‹„„edk\[[tts|‚ztts|„…„„Šlek„Š„lddƒ}ƒ‰‘~‰ƒv‹‹„››”””‹””‹ ™‹†tll””‹µ¶·\[[,55‹‹„ƒƒ|‹’ŠjcVz‚l]bZttsztlƒƒ|‚utFD;sref]cVTL‹„‹“Œ”d\\œ¤¦››”œ¤¦„„Š™š¤lek”“›‘…„”“›tts“Œ”ª³·ª³·¨©´ÂÅÓ›¢›ª³·”››ƒ„„””‹|‚z“““{{tf]cultŒ‹“ƒƒ|{ttd\\Š}ƒŒ‹“tzl„„Š”“›ƒ}ƒtllƒƒ|redu{{zllkd\‚wlƒƒ|‹„„„Š}›”›i\V‰‰w‹„„Šƒ}{zmƒƒ|ƒ||lldbVUttsb[Uƒƒ|tygredzll‚v{\UZ[[Tkk]{{ƒlks››”kd\rr]lld‹„‹uztmwœ››ƒ||„Š„d\\ddcultzllŠ}|yle’ŒŒsle‚|ubVU{||SKJŠ}|[[TultŠƒ}ƒ||zllllktts‚utƒ„„uzt\UZMSSMSS|„…UTSUTS\[[ult\[b|„…“Œ”{||{||››”ƒ„„ultedkddc‹„„‚v{{{t”š”{||œ¤¦ŒŒš‹…š{||mttª³·Œ‹“¦§¨ª³·“Œ”‹‹‹Œ”•”š”ƒ‚u‹’Štt{llk{|||‚zf]ccbVtllmtt“““|‚z\UZ‚v{jV[sle[[Tkd\{||ttstts{tt‚|u””‹ztlkd\š””tts“Œ”„„Škd\‹‹„r]g‹‹‹tsl‹‹‹‹„‹Œ‹“sle‚ut|„…ƒ|||‚z“Œ”‚ut|‚ztts£››ƒƒ|£››¤¤“Œ”lrimtt‚utœ››|„…{ttek]JHFJHFFD;JHF{||MSSMRKƒ}ƒJHF|‚zƒ„„‹‹„‘Œ…dc\ƒ„„UTSyfllekf]c“““mttred‹…’llkŒ”•tts‹„„{tt‹’Štllœ¤¦ƒƒ|‰ƒv{zmŠƒ}››”›¢›¢—“Œ”{ttŠƒ}²««MRK:97£››{tt‚|usreSKJsrezll{{t‚|u‚|ubVZsrekk]SKJrfk’…‹Š}ƒ‹’ŠŠƒ}lks„„Š|‚zedkUTSƒ||”››™š¤š””Œ”•‘…„¦§¨œ¤¦œ¤¦››”|„…lri‘Œ…’…‹tllddcrfkf]cult𔔣››{u{‹‹„{{t|‚zddc‹„‹f]c‚|u”“›…‹‹lri|‚zrfk{{t‹„„’ŒŒ„Š„{tt’ŒŒtslzllƒ‚uzll‘Œ…ƒƒ|ttsb[Ullkdc\ƒ‚uVTLd\\‹„‹f]cddcekdf]cf]c|„…£››Š}ƒtsl’ŒŒ{tt‚v‚{tt‹’Š„Š}lldSKJtllbVZztf“Œ”Š}|ultdkVƒƒ|zllƒ„„œ››‚v{{{t‰ƒv{ttred{{tƒ}ƒult{|||„…ultllk>ECMSSUTSllkddc…‹‹{{ƒmttfkkƒ„„{tt{||ekd{||f]clksddctlltll{{tœ››”››„„Š”“›ult”››ultŒ”•ƒ}ƒ›¢›ÌÖЦ§¨¦§¨™š¤”››‚|uuzt“Œ”Œ”•”“›sreœ››ƒ„„ƒ||‘Œ…{{tƒ„„ƒ„„ƒ||‹…’{{t{{t²««{tt„Š„{||ttsztl„Š„{ttkd\ƒƒ|ultƒ„„{||lld…‹‹›”›’ŒŒƒ||ƒ}ƒ{{ƒ…‹‹‚|ulddult|‚ztzlƒ„„œ››Œ‹“’ŒŒ“Œ”ztlƒ‚uztl{ttyfl…‹‹lddtll{u{VTL\[[FD;F=CUMRd\\ƒ„„[[TZbNedkUTS™š¤Œ”•µ¶·‚|u{{t{||rfkƒƒ|‹‹„|‚zƒƒ|ttstslŠ}ƒlriu{{]cd„„Й𤓓“{{t“““{{t‹„„‘Œ…kk]‘Œ…{{t‚ut£››tll{zm²««llk7-2ŠŠ}””‹ƒ„„””‹cbVkd\‚wlƒƒ|tzlœ››yfd{||SKJPF=ƒ„„„Š„‹„‹‹’Škd\Œ”•|‚z{{ƒ]bZztld\\|‚zŒ‹“‹„‹tsl“Œ”ƒ}ƒ„Š„…‹‹„‰vœ¤¦„„Šd\\››”’ŒŒlldf]cŒ‹“{{ƒ‘Œ…rfktlllks›”›‹’Štts¦§¨{{ƒƒ}ƒtsl‹‹„MRKlks‹‹‹{tt{zmtll{||ƒƒ|””‹[TTredkd\Š}ƒƒ‚uddcƒ||ƒ||u{{lldbVZ[[Tek]\[[{u{leklekŠ}ƒ|‚zultsleekdtllkd\redllksleuztcbVlldFD;lekj]\ztl‰|v{tt‹„„ƒ||ƒƒ|“Œ””››ƒ}ƒult“““ƒ||i\Vredrfkult{ttultlrifkklld|‚z]cdmttultuzt„Š„ult^^qf]cƒ||ƒ}ƒfkk„Š}ƒ||”››uztf]c‹„„‹„„{||‹’Š“““|„…f]ctlltslddc¨©´„Š„¨©´¦§¨“Œ”˜Ž£lri„Š}ƒ}ƒ{||{tttt{ultlddzlluzt£››‹’Štzl‹‹‹{u{‰v|ƒ}ƒddc‹‹„›”›lldlldƒƒ|™š¤‚utƒƒ|‚ut‹„‹slekd\ult¦§¨ƒƒ|kd\{{t‚wl‹…’£››ƒ„„ƒ„„‚|u’…‹…‹‹lriztllekƒƒ|ƒ}ƒ£œ¥”››tll„Š}‹’Š‹„„“Œ”lld“Œ”Š}|Œ”•kd\VZTVTL:97UMR{zmekdUTSFD;MRK]bZ|‚z””‹””‹sle{{t|‚z{{t‹„„Œ‹“ztl{{tllkd\\sle|„…ttskk]llkldd‹‹„lektsl‹’Šztl{tt‹‹„{zm‹’Š‚v{Šƒ}ƒ||ŠŠ}²²¬VTL*)(œ››tzlœ››ljcbV|‚zzll””‹tzlkd\sreŠ}|74,D;9{{t”š”ƒ„„œ››tll„Š}{||ƒ}ƒ„Š„ƒ„„ultœ¤¦“““¤¤‘…„jV[yfd|‚z”››””‹ƒƒ|„Š}Š~‹ƒ||‹„‹tslƒ}ƒƒ}е¶·””‹šŒµ¶·¦§¨{{ƒƒƒ|tt{œ››¨©´’ŒŒ[[Tddcek]slettsƒƒ|ª³·‹‹‹{zmultsle\[[kd\tslVTLƒƒ|{{tlddlddulttll‹‹‹JHFultred’ŒŒtsl{{ƒbVZmttlri‰v|mttkd\kd\dc\‹’Š›”›|‚z„Š}{{ttslUTS{{t{ttljtlltll{u{’…‹‹„‹tts‹‹„’ŒŒ„Š„ultredlddkd\{ttult{||edkultJHFmtt\[bfkk{tt|‚z„„Š…„’ult|„…{||‚v‚UTSdc\“““Œ‹“llkŒ”•‰|v‚v{Œ”•‹‹‹u{{mtt{{ƒ“Œ”Œ”•‹‹‹ƒƒ|‹’Š{{ƒ””‹‘…„£››‹’ŠŒ”•ƒ}ƒ‚v{{tt[[T‚|uƒƒ|¤¤ƒ||’}™„Š}|‚z“Œ”‹„‹Š}|”“›››”{zmƒ||{{tmttttsƒ„„zllƒƒ|›¢›uzt‹„„’ŒŒd\\{{ttslztf|‚ztslƒ}Šƒ}ƒtslsle””‹ƒ}ƒ{u{kd\d\\””‹››”„„ЄЄƒ}ЄЄekd”š”“Œ”rfkJHFƒ||bVUlekb[USKJJHFFD;MRKSKJVTLJHFƒƒ|\UZ|„…f]cƒƒ|‚|uŠ}|llk…‹‹ekdƒ||lri{||kd\MRKred{|||‚ztts‹‹„ƒ||ultu{{{||…‹‹{||kd\‚|u«²«„Š}ŠŠ}{{tsle‚|uŠŠ}µ¶·JHF-1+|‚z“““‘Œ…rg]kk]jcV‰ƒv”š”b[U‹‹„ƒ„„b[UVTL3+*‘Œ…„Š„‹…’ttsVTLƒ}ƒtts|‚zmtt£œ¥””‹tt{‹‹‹›”›¦§¨œ››ƒ}ƒ”“›llktt{¦§¨¨©´£››‹„‹{tttslf]clkstsl“Œ”‹…’{{ƒƒ||‚v‚”𔦧¨„„Š‹„‹Œ‹“‹‹‹ultttsdc\f]c‚ut„„Šƒ||‹‹‹redi\Vkd\zllVTLldd{||[[Tllkƒ||ttssredc\ƒ„„bVUttsSKJƒ}ƒultllklriœ››redztltsl„Š}d\\ztlƒ„„{tt’ŒŒdc\‹’Šd\\”š”‚|uztlŠ}|cbVkk]kd\“Œ”ƒ||ƒ„„Š}|””‹’ŒŒ‚wl“Œ”kd\ult{{ƒultƒ„„lldfkk|„…JHF\[btlluzt‹„„„„Š{{ƒ}|’Œ‹“{{t{u{”š”’ŒŒƒ„„ddcƒ„„tll„„Š‹…šœ››Œ”•{||”››’ŒŒlriŒ‹“”››{tt|„…|‚zƒ||›”›””‹ƒ}ƒ”“›edk…‹‹|‚z“““‹‹„sle…‹‹lek¦§¨{||tslƒ„„ƒ}ƒŠ}ƒ{{t{{t“““{{t|‚zdc\‹‹‹rfkœ¤¦””‹’ŒŒ‹„„Š}ƒ‹„„{||‹’Š‘Œ…llkƒ„„’…‹ult|„…‹„„‹„‹›”›Œ”•{{tslett{”𔋄‹“““{{ƒƒƒ|””‹‹‹„Š}|bVZlldlekztluztkd\D;9VTLFD;[TTsleUTSf]c&&\[b„Š„‹‹‹‹„‹‚|u‹‹‹‹’Š…‹‹Š}ƒŠ~‹””‹sleƒƒ|ƒ}ƒ‹„‹ƒ}Šlld‹‹„ztlttstts‹‹„“““‹’Š”š”‚ut‹‹„lld‹‹‹ƒƒ|‚v{yletslƒƒ|¦§¨:9774,ƒƒ|ƒ‚u{{t‚|urr]rg]‘Œ…tslyle{u{ƒƒ|ƒƒ|VTLSKJŠŠ}œ››ƒ}Ц§¨ƒƒ|ƒ„„„Š}tt{lri‹’Š£œ¥uzt…‹‹“““””‹£››‹„„ult|‚z«²«|„…ƒ||‘Œ…™š¤›¢›…‹‹dc\Œ”•ƒ„„d\\[[TUTSrfkldd‹‹‹|„…ƒ}ƒ“Œ”Œ‹“™š¤“““„Š„j]\“Œ”b[U“Œ”{{t‹„„š””‹’Škk]{ttƒƒ|kk]uzt|‚ztts“Œ”f]c{{tsletslƒ}ƒd\\‚v{|‚z{{ƒultƒ„„’ŒŒ‹‹„{||Šƒ}Œ”•uzt‹‹„‹‹‹¦§¨{||jcV\[bƒ||{u{”𔋄„š…Žult‚ut{{t‹‹‹‹‹‹tllŠ}|Šƒ}‹„„{u{ƒ„„Œ”•”“›f]cƒ}ƒ‹’Šlri|„…lri]cd\[[ekd…‹‹‹„‹tt{{{ƒ…„’‹‹‹tsl{u{{||ƒ||„„Šƒ„„ekdtllŒŒš†~‘llk„„Š…‹’“Œ”“Œ”„„ЄЄŒ‹“’ŒŒ“““‚wlult‹„„µ¶·Œ‹“…„’‚wlult|‚z„Š}ƒƒ|ult“““ult{tt{{t{ttƒ„„“Œ”£››ƒ||sle’ŒŒtsldc\{||œ››lek{{t{{tŠƒ}‹„„“Œ”£œ¥¦§¨“““¦§¨ƒ„„ƒƒ|“““tll‹‹‹‹„„„„Šmwmttd\\mttztl‹‹„{u{š””’…‹{{t‹’Š|„…‹„„redlldtllŠ}|‘Œ…rg]uzttygC8.dc\[TT‹‹‹ldd\[bmtt„Š„”“›\[bkd\rfk…‹’{{t[[T‹„‹|„…š””‹‹„ttsŒ”•‚v{’ŒŒ{{tslellk”“›””‹‹„‹¦§¨‹’Š£››››”ƒƒ|‹’Ф¤‹„‹ztl››”‚utü¿SKJ:97kd\kjVŠƒ}ztlkd\ŠŠ}d\\tsl|‚zuztƒ}ƒ{zm[TT‹„„{zmuzt”“›£œ¥ƒ‚u£œ¥ƒƒ|b[U£œ¥{||{u{Œ‹““Œ”{{ƒ{{t’ŒŒ‘Œ…››”Œ”•{||‹’Š”“›””‹£››tts\[[ek]|„…u{{ƒ‚ulksult{{t{{ƒƒ‚uu{{”“›’ŒŒ“““„„Š‚ut‹‹‹Œ”•ƒ}ƒ‘Œ…”“›“Œ”ª³·ƒ||b[Usreƒ||sreŠƒ}tt{ƒ||‚|u“““ult{ttsretzlŒ”•d\\lrir]Z|‚z‚ut“Œ”‘…„‹‹„œ¤¦tts{{t‹„‹{{ƒ{ttek]tslkd\d\\tll‹‹‹£››‹„„¦§¨››”tlllddf]cƒƒ|llkŠ}|„Š„ƒ||ldd£››sreƒ}ƒ{{ƒ“““ƒƒ|]bZ…‹‹„Š„{||…‹’{u{|‚z|„…ƒ}ƒmtt{||…‹‹|‚z‹„„ttstt{ƒ}ƒtllultƒ„„ldd£œ¥™š¤¨©´œ¤¦“Œ”“Œ”𔔦§¨«²«‹‹‹ƒ„„ƒ‚u¦§¨‹‹„‹’Š‹„‹‹…’f]c„„Štts››”””‹››”µ¶·‹…’tzl‹‹‹””‹|‚zŠ}ƒ‚ut{||ldd’ŒŒ””‹|„…{tt{{t„Š„{zmuzt””‹›”›“““£œ¥”“›œ››””‹{u{ƒ||{tt›”›ttsƒ}ƒlddldd{{t[TTllk‚|u¦§¨ƒƒ|”“›ƒ}ƒu{{‹’Šƒ„„’ŒŒ‹„‹‹„‹Š~‹ztf{{tsleŒ‹“kk]D;9ult{{ƒ|‚z…‹’mttUUYƒ„„d\\fkkzll‚|u›¢›ƒ„„uztƒ}ƒ{u{’ŒŒ‹‹‹\[[‹„„Š~‹ddc]bZ[[Tddctsl‹’ŠŒ”•Œ”•tslb[Uƒƒ|{||””‹¤¤“Œ”£››‚v{ztl¦§¨[[T74,››”„Š„{zmŠƒ}Šƒ}|‚z{zm|‚zllduztœ››‹‹„ƒ|||‚z‹„„Œ”•Œ”•“““ztlldd[TTddc|„…{u{{u{’ŒŒ‹„‹”››Šƒ}Šƒ}„„Šƒ„„VZ[u{{…‹‹¦§¨‹„„ƒƒ|ldduztdc\lksŒ”•lriŒ”•ult‘…„{tttsluzt”“›Œ‹“{{ƒd\\œ››‹’Š‹„‹ƒ}ƒ‘ˆ}ultŠ}ƒzll{ttœ››lddœ››››”Šƒ}{{t{{ƒlddtsl{||ƒ‚uƒ||kd\‚|uultj]\tllllkrfk‹‹„ƒ||{{tœ››ƒƒ|›”›{ttlld|‚zrfkj]\‚v{mttƒ}ƒlekrg]Š}ƒ‘…„‘…„ztl“Œ”›¢›‘Œ…tsllddƒ„„{tt{{ƒƒ}ƒredƒ„„„„Šuztkd\b[Utts{||{{ƒ„„Šƒ„„|„…{u{~’“mttlks[[T{||llkdc\rfkmtttt{|„…””‹ƒ}ƒ“Œ”f]c‹…’™š¤£››››”Š~‹tsl‹’Š{{ƒtt{‹‹‹{zm””‹£››ƒ„„¦§¨ƒ}ƒŒ”•‹‹‹‹’Š””‹œ››™š¤Œ‹“‚|uœ¤¦‘Œ…{||“““‚v{ƒ}ƒ‚|uŠƒ}lldƒƒ|lld‚ut¤¤‹‹„”š”‚ut‹„„›”››”›‹„„tts›”›š””‚utƒ„„“Œ”Š~‹mw„„Š{ttƒƒ|ddc“““ƒƒ|››”lks”š”{u{…‹‹|‚z”››“Œ”‹„„ƒ}ƒ‹„‹ƒ||d\\sred\\|‚z‰|v™š¤ttsŒ”•\[b>B9f]cJHFtll{||uztkd\tsl{{ƒŠ}ƒ“Œ”„„Šš””|‚z””‹„Š}›¢›{||lld{{t\UZmttƒƒ|‹„‹llktslSKJVTLkk]kk]{{tš””Š}|’ŒŒtll¦§¨VZT-1+‹‹„””‹ƒ||‘…„‚|ukd\tzlVTL[TTllkŠƒ}ƒ‚ulrilks{{t|‚zlksƒƒ|sre‹‹‹[[TUTSUUYƒ}Šzllœ››£œ¥”š”››”ƒ||‹‹‹lri|„…cbVŒ”•…‹‹‹…’slettslrikk]lddlkstts|„…”“›‚|u[[TŒ”•„Š„ttsekdldd„Š„tt{„Š„„„Š‹‹‹[TTztltts{u{‚ut|‚z”š”””‹ƒ‚uƒ‚u‘Œ…‹‹‹tll‹„„{u{lddkk]‰ƒvlddredbVUtlllldƒ}ƒtt{ƒ||ƒƒ||‚zƒƒ|b[Utts{{t{u{Œ‹“sleSKJd\\d\\„Š}sleldd[TTddc’…‹ek]‹‹‹„Š„“““‚ut‹‹„llk{u{{{t””‹„„Š[TTkd\|„…slelrimttlek|„…ƒ||‹’ŠŒ‹“{{ƒ…‹’{{ƒ{||llk{|||‚z’…‹‹…’|„…{||ƒ||{u{ƒ}ƒ‹‹‹{{ƒƒ}ƒ¦§¨›”›ƒ„„|‚z„Š„ult¦§¨”››’ŒŒ“““{||”››{{ƒ‹‹‹|‚zlld„Š„ŠŠ}‹’Š{||›”›“““„Š„¤¤“““Š}|{u{{u{ƒƒ|””‹ƒƒ|tslœ››¤¤ƒ||ƒƒ|””‹{zm””‹d\\f]c‹‹‹„Š„sle{||Š}ƒ››”“Œ”{u{”“›£œ¥””‹uztbVU|‚z‹‹‹kd\‹‹‹tsl…‹‹“““|‚z”››œ››’ŒŒ]bZ‹„„š””tll„Š}Šƒ}sletzl{{ƒlddtzltt{SKJJHFFD;llk|‚z››”tsl|‚ztt{sle“Œ”ztl{u{kd\Œ”•‹„‹ekd{u{[[TbVUtts|‚ztsltt{lldlrib[UaWMcbVdc\tslŒ‹“ƒ}ƒtsl‰|v’ŒŒJHF3+*ƒ}ƒ””‹‚|u‚wl””‹tsltslsletll„Š„lriƒƒ|u{{sle“““{||ddclri‘Œ…\[[ttsf]cUTSzll“~ˆ{u{’ŒŒ¦§¨sreƒ||’ŒŒŒ”•mtt|‚zf]cttssle¦§¨ddctsl:97ek]VTL[[T‹‹‹ttslri{||ƒƒ|{||“““”››”“›„vŒƒ|||‚z‹…’{u{zll‚v{‹„‹„Š}ult„Š„‹„„‚|u‹„„ztlœ››‹‹‹ƒ„„ult”“›‘Œ…sreyfd‹„‹sleredd\\kd\bVUtts‹‹„sreƒƒ|’ŒŒ‘Œ…]cddc\{||ttsredredUMRd\\…‹‹‚|ud\\yleŠ~‹‚|uƒ„„‹„„‹’Š{tt‹„„„Š}{u{ttsreduztƒ}ƒtll‹’Šƒ„„{u{\[b]cdyl„lksƒ„„|„…”››|„…Œ”•ƒ}ƒ’…‹llkƒ„„{{ƒ„Š„“Œ”ƒƒ|ƒ„„ƒ}ƒ›”››”›“““”“›Œ‹“››”›”›Š}|‹’Ц§¨”››|‚ztsllld‚|uƒ„„„„Šult’ŒŒ‹‹‹|‚zš””›¢›‹‹„\[bƒ}ƒ{tt|‚zsleœ››ult‚|u‚v{Šƒ}š””tslƒ„„ŠŠ}{zmsle‹‹„ƒƒ|‚|u’ŒŒ£œ¥‹„„{u{ƒ„„‚utlldŒ”•{{t¦§¨ultƒ||ƒ}ƒ‹„‹ƒ„„ƒ||¤¤tts‚|u‹„„”š”dc\tt{”››¦§¨œ››£››Œ‹“Œ”•’ŒŒzll|‚zj]\[[TŠ}|SKJ‹„„ŠŠ}SKJVTL[TTlrimttddc‚wl{{tu{{Œ‹“tt{ƒ||{u{‚v{b[Utsl„Š„{{ƒŒ”•Šƒ}lldlekƒƒ|‹’Šultttstsl‚v{{zm¤¤tsl””‹››”‹‹‹“““{tt«²«JHF*)(ƒ}ƒuztƒ||f]c‚|udc\‚|ulritllUTS‚|ulri”𔓓““Œ””š”Œ”•‘ˆ}SKJ‰ƒvlldekd\[[UMR{tt£››‹„„£›››¢›œ››Šƒ}™š¤‹’ŠlksŠƒ}ƒ„„‹’Š{{tred„Š„lldSKJ{||tslŠ~‹uztlri™š¤ƒƒ||‚z™š¤…‹’”“›”“›ƒ||¦§¨œ››ultƒ||zllztlŠŠ}£››dc\ƒƒ|Šƒ}’ŒŒrg]£œ¥ƒ„„|‚z”“›d\\tlltsl{ttƒ„„rg]ultSKJ{||ƒƒ|{{tsre{{t‹‹‹‘ˆ}ƒ||tsld\\mttƒ„„{ttƒ„„‹‹„ƒ„„slešŒldddkVbVU{||”“›{||mtt‹’Š‹„„uztllk{{ƒ‘Œ…ƒ}ƒŒ‹“lld{||[[TbVU\[bd\\\[bedkƒƒ|]bZ…‹’u{{Œ”•„„Š‹’Š|‚ztts‚|u{u{¦§¨ƒƒ|ƒ}Š{{ƒ¨©´¦§¨ƒ„„¨©´„„Šzll{u{„Š„|‚z‹‹‹”“›leklld””‹[[TlldŒŒš{{ƒ|„…„Š„|‚zztlœ¤¦‚utVZTƒ}ƒ””‹ŠŠ}››”“““£œ¥š…Ž{tt[TTkd\ek]‹’Šƒ„„‹‹„Šƒ}‹‹„‹‹„Š}|‘Œ…‹„‹ƒ}ƒŠ}|ƒ„„Œ‹“„Š„ttstslš””ƒ||„Š„››”“““‹’Š{u{‹’ŠŠ}ƒƒ||ƒ||„Š„ƒ}Šƒ||‹’Šƒ||”š”‚|uƒ„„”“›bVUƒ||rg]ztl|„…ult[TT{{tƒ„„slelrif]c{{ƒldd{|||‚z“““{{t‹‹„{||d\\f]ckd\VZTtts{u{¦§¨{tt‚v{‹’Š“““lksƒ„„”››‹’Šƒ„„šŒ¤¤›¢››¢›«²«£œ¥›¢›¦§¨‘Œ…””‹VTL*)(sreƒƒ|lriztl‚|uVTL””‹{{t‘Œ…„Š„ƒ}ƒ”𔋋‹{tt[[T|‚z„Š„‹‹„b[U£œ¥{tt]cd…‹‹£››’ŒŒœ¤¦‚ut“Œ”ƒ||ƒ}ƒƒƒ|ƒ}ƒ…‹‹z‚lŠ}ƒ„‰vsle[TTUTScbV‚|udc\‹„‹ŒŒš™š¤{||ƒ‚uƒ}ƒ›¢›u{{‹‹‹“““”››‚v{ƒ}ƒtsl£œ¥ƒ}ƒtll‹‹‹‚ut|‚z‹’Šek]zll{zm››”‰ƒv{{tuzttll‰|v„„Šƒ}ƒbVUztl›”›sleredƒ}ƒlddŠ}ƒsle””‹ƒƒ|llddc\””‹{ttllkd\\{ttkd\tll|‚zj]\”››Šƒ}ƒ}ƒ‘Œ…{ttŠƒ}šŒllk‹’Šllkƒ||‚v{ƒ}Š””‹tllŒ”•{{ƒ“Œ”tts„Š„tslmttf]c{{ƒmtt“““uzt{{ƒ|‚z|„…Œ‹““““{ttVZ[{ttŠƒ}uztŒ”•‚v{Š~‹…„’ƒ||tll“““”“›””‹‹„„’ŒŒœ››Œ”•{||ddc‚v{‹‹„Šƒ}”››‹‹„“Œ”™š¤Œ”•‹‹„”𔤤››”dc\{||£››’ŒŒ””‹’ŒŒrfkŠ}ƒš””Šƒ}ztlŠŠ}tsl„Š„œ››ztf{{t{ttkd\sle‹„„”“›‚|u|‚zultŠŠ}‹„‹‹„„‹„„··Ä‹‹„£œ¥Œ”•ƒƒ|‹„„j]\ƒ}ƒŒ‹“red„Š„™š¤¦§¨Œ‹“”“›‚|utsl¤¤{||‚utlldtzl…‹‹{{tSKJ‚utVTL{{t’‘~f]cJHFlrittsŒ”•ŠŠ}“““‹‹‹”š”ultj]\ƒ}ƒ’ŒŒllktsllksƒƒ|“““’ŒŒ”š”{zm„Š„{{tƒ}ƒƒ„„tsl››”‹’Š””‹›¢›’‘~²¬µµ¶·µ¶·¤¤¦§¨\[b)+2Šƒ}””‹ƒƒ|››”‘ˆ}dkV‹’Š‚|u‹‹„‹‹‹Š}ƒsreVTLsle‚|uŒ”•lrimttztl‹‹‹|„…\[[lrizll’ŒŒ‚|uuztVTL¤¤“Œ”šŒ“Œ”‹„‹lld“““”š”“Œ”Šƒ}‹„„lri‹‹‹f]ctsllri{{ƒ™š¤¨©´‹‹‹”š”…„’{{ƒ{u{‹„‹™š¤tllsleŠƒ}{u{‹‹‹‹’Šƒ}ƒsle{ttj]\„Š}ldd{zm‚|u””‹ƒ||‹‹‹sle‹„„„„Šdc\‰|vj]\‹‹„“““‹„‹]bZŒ‹“”››tll{{t‹’Š{zm‹„‹{u{‚|u“““Œ‹“kd\’…‹ttsedktlllddsleztf{u{ƒ||‰ƒv{tttsldc\‚v{‚|u{u{ƒ‚u›”›””‹edk{u{ƒ„„ttslldult{{t{||™š¤|‚zuzt|„…Œ”•|„…|„…|‚zlksu{{{zmƒ„„lekŠ}ƒtt{ƒ}ƒ““““““Œ‹“Œ”•‹‹‹£››ultlksƒƒ|ƒ„„„„Š{||‘Œ…”š”š””‹’Šƒ„„„„Š|„…ttsŠ}ƒ‘Œ…‹‹„‹„„{{ƒultœ››”“›¦§¨›”››”›yfl‚|u””‹‘Œ…””‹sre””‹ŠŠ}„Š„‹‹‹yfdztl‚|u‚|uƒ„„‹’Š‹‹‹‹‹‹‹„„{ttœ››’ŒŒ‹„„|‚z|‚zrfklri{ttult“Œ”¦§¨¦§¨›”›‹„‹ƒ„„|„…›¢›‹‹‹{tt‹‹„{{tš””uzt„Š}lldztfVTLSKJsleuzt[TT:97f]cmtt\[[lri”š”™š¤{{tmttƒ}ƒ“Œ”{u{¦§¨„Š„ƒƒ|“Œ”‹’Šƒƒ|‹„‹„Š}ek]tlltt{[TTƒ„„“““””‹ƒ‚uŠŠ}”𔦧¨™š¤£œ¥››”¦§¨¦§¨JHF*)(‹‹„‹‹„lri‘Œ…ztliq]‹’Š‹‹„‹‹„lld{u{VTLtsld\\ƒƒ|ƒ„„uzt™š¤ƒ||uzt‹’Šu{{u{{tll‹„„œ¤¦ulttts{||£››¤¤œ››Œ‹“‘Œ…rfk“Œ”š””œ››‹„„ƒ„„ldd\[[{{t„Š„{ttƒ„„“Œ”tt{ƒ„„u{{|‚zultœ››red‹‹„²««ƒ||{{ƒ“““tll‹„„b[U’ŒŒ{||tts{zmslei\VŠƒ}{tt‹„„‚utddcddckd\‚|ud\\„Š}tllƒ||zll‘…„UTStll|‚z””‹ƒ‚usle“Œ”{u{ttsŠŠ}Šƒ}{||{ttƒ„„f]ctll‚wlš””lldsleƒ|||‚z‹‹‹”š”›”›‹‹„“““{u{ultttstts{ttƒ||ƒ||‹‹‹lksƒ||lriu{{|„…„„Š„„Š|„…VZT]cdu{{{{ƒ]bZ‹’ŠŠƒ}™š¤’ŒŒ{u{tll“Œ”lri‹’Š„„Й𤦧¨Š}|sleƒƒ|ulttts‹‹‹£œ¥””‹‘Œ…«²«””‹Œ‹““““{{tJHFztl{{tŠƒ}ultŠ~‹tll‹„„£›››”›£››Š}|‘ˆ}lj²««lri‹‹„{zm‹’Š””‹ƒ„„Š}|zllkd\šŒ‹„„‹‹‹|‚zƒ||UTS{tt{||š””’ŒŒ‹‹„‹„„tll\[[Š}|{tt{u{’ŒŒŒ‹“‹’Šƒ„„‹„‹Œ”•œ¤¦‹’Š“““¦§¨ƒ„„œ››“Œ”|‚z]cdztlVTLSKJŠƒ}…‹‹Œ‹“MRKSKJuztd\\mtt‘Œ…„„Š‹„‹“Œ””“›“Œ”›”›œ››‹‹‹ƒƒ|tt{|„……‹’ƒ}ƒ‹’Šƒ}ƒ‹‹„ttslkstllƒ„„š””tsl›¢›{{t‚|ullkƒ||ttsƒƒ|¦§¨MSS*)(cbV„Š}Œ”•{{tƒƒ|cbV’ŒŒdc\‹‹„sreŒŒšztlekdldd‚|u‹’Š‹’Ц§¨¦§¨¦§¨|‚zJHF¦§¨ƒƒ|[TTred[[T‹’ŠŠ}ƒœ››‹’в««Š~‹{zm””‹llk’ŒŒ{{t‚ut…‹‹„Š}|„…›¢›”››{{ƒlksƒ}Š|‚z„Š„…‹‹‹„„™š¤ƒ}Š‚wl””‹‚v{Œ”•yflf]clld{||‹’Š‚|uddcdc\uztb[U‹‹‹ƒ||{||²««Š}|ƒ„„tllkd\„Š„lek‚ut{ttƒ}ƒtt{ƒƒ|lektll„„ЄЄztlrg]”š”tts{u{lld‚v{{{tddcVTLƒ||ƒ„„‹’Šultƒƒ|sleiq]]bZlri’ŒŒ›¢›Šƒ}Œ‹“\[[‰v|sleƒ||’…‹{ttœ¤¦”“›“Œ”{{tu{{u{{fkk“Œ”ƒ}ƒmtt{{ƒ\[bŒ”•tsl„Š„{{tkd\lekultddc{u{UMRuzt‹‹„uzt›”›¦§¨ƒ‚u”š”Œ‹“…‹‹{{tllk¦§¨‘Œ…“““µ¶·ƒ„„{u{’ŒŒiq]‹‹„tllŠŠ}‹‹„‹„‹ƒ„„šŒ{{ƒ‹„„’ŒŒš””’ŒŒ²««Šƒ}{tttslƒƒ|ttsuztŠ}|ƒ||b[Utsl››”š””Œ”•„Š„uzt“Œ”„„Š{u{ƒ||ultƒ}ƒ‹„„{ttedk’ŒŒSKJsle¦§¨tt{ƒ‚u“““œ››“Œ”„Š„‹‹‹¤¤š””””‹Š}ƒ¦§¨…‹‹sle‹‹„cbVrr]SKJdkVŒ‹“Œ‹“MRKf]ctzlmwekdŠƒ}ƒ„„›”›‹’ŠŒ‹“”“›“Œ”ldd”››„Š}tts‘ˆ}…‹‹£œ¥‹‹‹ƒ„„{||Œ‹“ƒ„„‹‹‹“““tll|‚z{{ttslztlƒ„„Š}ƒƒ„„ult²¬µ[TT*)({{t¤¤„Š„’ŒŒšŒlks{zm{ttƒ||{{t„„Šuzt‹’Štslyle””‹{{t‹„‹””‹”››Œ”•|‚z¨©´²««ult‹’Šuzt{||f]c””‹{tt››”‹‹‹¦§¨›”›mtttlltzlttssle]bZ„Š„ƒ„„„Š}lri\[[™š¤\[[uzttt{tts{ttƒ„„£››ƒƒ|uzt¦§¨ttslddb[U‹‹„|‚zƒ„„ddc{{tlriztl“Œ”ŠŠ}‹‹„š””ztlttsztllddb[U‹„‹‚|uslekd\{{tŠƒ}’ŒŒ“Œ”|‚z””‹{||›¢›„Š„{{ƒ””‹‹‹„j]\ƒƒ|VTLtll“““|‚z¦§¨{u{“““š””””‹ttsllk{{tŒ‹““““œ››tllztl|‚z’ŒŒ£››ƒ}ƒ¦§¨tlledku{{ddc|‚z|„…”“›ekdmttmtt|„…ƒƒ|tll“““ztlztlultult…‹‹ttsƒ}ƒ‹‹‹‹„„Œ”•£››¦§¨‚v{ƒƒ|”“›œ››Œ”•ŠŠ}¨©´¦§¨›¢›¦§¨›¢›¦§¨‹„‹ƒƒ|ƒ„„{{t‹‹„{zmœ¤¦{{ƒlddƒ||‹„„”“›“~ˆš””œ››‹„‹‚|u‚|udc\›¢›””‹ƒ||‚|uƒ||£››Šƒ}„Š}ƒ„„‹‹‹””‹ª³·„Š„u{{ƒ}ƒš””ƒ}Š{||““““““…‹‹ƒ||tll‹„„tts£››ƒƒ|lddedklld‹‹‹””‹ztlkd\“““£œ¥¤¤ƒ„„‚|ukk]b[U{tt‘Œ…”››†~‘mttƒ}Štts{||llk‹‹„VZ[{ttƒ||“Œ”“Œ”‹…’mwmttuzt{||¦§¨ƒ„„ƒ||Œ”•Šƒ}‹’Šœ››„„Š‹’Šddcƒ||””‹[[T{u{{zm£œ¥{{ƒƒ}ƒŠ}|”š”LKR)+2ƒ‚u‹’Š“““d\\Œ”•Š}ƒ‚|usleuzt””‹tt{‹„‹VZ[VTL‹„„„Š}\UZ‚|uƒƒ|…‹‹u{{|‚z…‹‹”“›£››‹‹‹lriuztcbV‚|u’ŒŒ‹„„„Š„››”„Š„„„Š‹’Šƒƒ|ƒ}ƒƒƒ|tsl\[[|‚zu{{‚|ulks£²u{{”š”œ››tzlŒ‹“|‚z“““’ŒŒƒƒ|‹‹„ztl{u{{{tœ››lritts‰ƒvtslsleylelrirg]¤¤ztl‚|uƒ„„ultƒ}ƒztlcbVf]cš””d\\‚|u{zmŠ}|{u{lldtslddcƒ„„|‚zƒ‚u””‹ƒƒ|tsl{||d\\sle‚|u{||sre‚|u‹„‹‘Œ…d\\‰|v‹’Škk]tlltsl‹‹‹uztŠƒ}sreŠŠ}ƒƒ|‹„‹„Š„ƒ||{u{„Š„Œ”•{{ƒ”››„„Š|„…ttsŒ”•|„…‹„„‹‹‹„Š„ztlƒ„„Š}ƒƒ„„{||‹’Ц§¨”š”œ¤¦¦§¨¦§¨£››µ¶·²««‹’Š“““‹„„Š}ƒ¤¤µ¶·ª³·””‹¨©´‹’Štt{sreŠ}ƒ’ŒŒš””ddctslult›”›{{ƒ‹‹‹ƒ}ƒ›”›‘…„‹‹„tll››”|‚z|‚z¦§¨™š¤‚|u„Š}‘ˆ}››”””‹yle‹‹‹‹‹‹{||¦§¨‹’Šllk„„Šƒ}ƒ“Œ”‹„‹£œ¥‹’Š‹’Šf]cred…‹’ldd”››ldd|‚z’ŒŒ”››¤¤ƒ‚uultdc\£››ztl”𔋋„|‚z‹‹„VTL𔔔𔋒Š{u{Œ”•lek{{t‚v{llk‹’Šu{{‚v{lekƒ}ƒ‚v{‹„‹ƒƒ|{tt|„…llk¦§¨Š}ƒ’ŒŒƒ„„¦§¨‹‹‹™š¤‹’ŠŒ”•‹„‹ƒ„„Šƒ}kk]ult‘…„“Œ”›”›f]c[TT¤¤JHF:97sreƒƒ|‹„‹”𔋋„{ttƒƒ|[[Tb[Uƒ||‹„„Œ”•lldtlllrilld[[T|‚zƒ}ƒtzl{||mttƒ„„{{t››”‰‘~ultƒƒ|‚|u‘Œ…’ŒŒƒ||ƒ}ƒtslœ¤¦|„…‹„„dc\\UZ\[[{{ƒddcztlVZ[ztlƒ}ƒŒ‹“}‡’„Š„|‚z“Œ”ƒ}ƒlriddcŠŠ}{{tœ››sreƒ}ƒ{||‹’Š|‚z{ttdc\ttsƒƒ|lldkk]ztlSKJi\V[[T{{ƒek]ƒ||‹’Š{ttzll{ttj]\ƒƒ|zll“Œ”‚utztlœ¤¦llk{tt{||ƒƒ|ztlŠƒ}zllllkdc\lldultUTS‚|ub[UsleŠƒ}sre››”‹‹‹ƒ||””‹{{t“Œ”|‚zŠƒ}‘Œ…“““{{t“Œ”{||\[[{u{{|||„…]cd|„…‹„‹{||ƒƒ|¨©´‹‹‹{{t{u{{zmŠƒ}‘…„zllƒ„„red‹‹‹‹‹„”š”Œ”•|„…“““‹‹‹£››””‹„Š„¦§¨¦§¨›¢›¤¤²««‹‹„”š”{{t‹„‹‹’Š‹„„¨©´ƒƒ|µ¶·tzl{||{{ƒŒ”•¦§¨¦§¨‹„‹£››ƒ||’ŒŒ{tt‘Œ…‚wllriŒ”•“““ƒ||‚|u‰ƒv””‹Šut“““”“›œ¤¦lri‹„‹£œ¥”››‹’Šš””{u{{tt{||{||{||ult‹„„‹„‹ƒ}ƒ„„Šƒƒ|ƒ||{tt‹‹‹‹‹„{zmyleƒƒ|‹‹„‹„‹”“›‹’Šuzt””‹]bZ“““¤¤|‚z£œ¥u{{ult]cdf]c„Š„ƒƒ|“““„Š„„„Šult“Œ”‘Œ…››”dc\ƒƒ|‹„‹ƒ„„lekredsre‚v‚{||‹„„{|||‚zbVUrfk¢—{{tlld‚|uldd{ttzll‚ut‹‹‹:97JHF‹‹„{{t|„…sleƒ||„„Šƒ||‚|uƒƒ|‹‹„‹„‹ekdlri””‹tslƒƒ|Œ”•ƒ||tllŒ”•|„…VZT‹’Š{{t””‹„Š„ƒ„„«²«‹‹„š””ƒ||ŠŠ}…‹‹’ŒŒ”“›{||b[U|„…sreŠŠ}lekttslri„„Š\[[lkssleVZ[{u{…‹‹£œ¥ƒ„„{tt{{tƒ||lri‹’Š{tttllVZ[ƒ||ƒƒ|f]cƒƒ|{||sretsllddsre{{tsre{{td\\{||ƒ„„lld””‹d\\‰|vƒ||b[Ukd\‹‹‹ldd’…‹œ¤¦‹’ŠtslŒ”•lldb[UUMRtll‹‹„‹‹‹red’ŒŒ„„Š[TTtsl{||Šƒ}‹‹„{||¦§¨¦§¨{tt‹„„œ››”𔋋„‚ut‚|ukd\tt{uzt›”›„„Š‹‹‹ldd{tttt{fkkmtt{ttu{{{{ƒ”“›’…‹‹’Šƒ‚uldd“Œ””“›tt{™š¤ª³·“““«²«£œ¥›”›¦§¨£››‹‹„‹‹‹{||›¢›£œ¥£››‚|utsl«²«“““‚v‚rfk“Œ”™š¤”››››”‹‹‹{||{u{“““ƒ„„tts“Œ”“Œ”{||‰|v‰ƒv””‹””‹”š”œ››‚v{‘Œ…{{t‹’Š‘Œ…š””“““{{ƒ{{t{{t“Œ”™š¤“““””‹¨©´“Œ”¦§¨¤¤Œ”•tzl“Œ”zll‹„„ƒ||lldŠŠ}“““”››”››‹‹„µ¶·²²¬‹‹‹Œ”•ƒ||„Š„\[[ƒ||ttsMRKztl“““|„…Œ”•lkslksƒ}ƒbVZ…‹‹¦§¨„Š„›”›‹’Šult›”›Œ”•‹’Š„Š}„Š}ƒ„„‚ut{u{{u{‹’Š‹„‹„„Šƒ„„SKJlrifkkred‚|u“““ƒƒ|Šƒ}‹‹‹ƒ||‚utldd””‹JHF:97rg]|‚zƒƒ|tzllri‹„‹¦§¨‘Œ…ƒ}ƒtllƒ}ƒ{{t]bZVTLƒ||‹‹„œ§²›¢›llk‹’ŠŒ”•tts|„…“““d\\“““tt{‹‹„d\\\[[£œ¥yle{tttlllks‹‹„ttslldVTL‹‹„leku{{edk‹’Šd\\UTSultŒ‹“ƒ„„{u{‹’Šslelrilldƒ‚uƒ||‹’ŠŠƒ}ƒ„„{ttztlldd|‚z‹„„tts‚v{lldŠŠ}j]\jcVkd\VTLtzlŠ~‹ult{zm‚|u[TTšŒ‘Œ…jcV¤¤ult””‹‹‹„›¢››¢›{u{{{tdc\Šƒ}bVUldddc\{{ƒ””‹“Œ”ƒ„„ztl‚|utsl‹„„rg]„Š}Œ‹“„Š„ƒ||ƒ}ƒ„Š„{{tlddztlkd\sle{|||‚zult|„…ƒƒ|”š”{u{Œ‹“…‹‹tts„„ŠlriedkUMRtll“““{{t‹‹„ƒ„„{u{ƒ„„£››¦§¨”š”œ¤¦µ¶·››”„Š„š””œ››”𔛢›“Œ”ƒ}ƒšŒ‹’Š‹‹„„Š„“Œ”ƒƒ|¦§¨£œ¥rfkƒ„„¤¤„Š}{{t„„Šœ››ƒ}ƒœ››‹„‹ultiWUzllrg]‚utztf””‹„Š„Š}|ztl‚|ukd\‚|uŠƒ}‹’Šu{{tts‹‹‹œ››š””mttllk{||ult“Œ”tsl›¢›uzt¨©´ƒ„„“Œ”ƒ}ƒ„Š„|‚z›”›”š”œ¤¦“Œ”‹’Š‹’ŠŒ‹“ult£œ¥uztzlllddttsVTL[[Tsreœ¤¦f]cJHFultultzll{tttll””‹‹‹„‹„„Œ”•’ŒŒŒ‹“{u{|‚zƒ||Œ‹“{{tsledc\|‚z‰‰w{{ƒddcƒ||tsl{||ztltllƒƒ|‰ƒv£››lddultlddƒ‚uƒ„„D;9,55ƒƒ|UTS{||lld\[[{u{tll“““|‚z‹„„‹„„uztult‚|u{tt‹’Š…‹‹’ŒŒ‚v{lkslks]cdddc{{t‹‹‹cbVŠ~‹‹‹„d\\‚wlf]c‘Œ…ƒ||‘Œ…£œ¥ƒ‚utzl[[Tmttlld\[bttstt{lri‹‹„tts‹‹„tslŒ”•ƒƒ|ztl‹‹‹|„…zlldc\{||”››sleVZTuztlriƒƒ|”“›tts{ttŠ}ƒƒƒ|MRK£››‚wl{{tsle“““‹„„tllkd\tslsle£››{u{lri‚wltt{Šƒ}tll„Š„”š”tll…‹‹lld‹„‹‚utb[Uredllkƒ||Š}ƒ{tt“““{{tŠƒ}‘Œ…Š}|ulttzlf]c‹‹‹‹‹„‹’Š{{tsled\\‹„„‚|u{u{\[[]cdƒ}ƒŒ”•ttsƒ„„‹…’ƒ}Š‹„„{||edk{u{kd\„„Šƒ„„|‚z„Š„š””ƒ}ƒƒ}ƒkk]ª³·tts£œ¥š””‘Œ…””‹£›››¢›œ››“Œ”¨©´“Œ”‚ut²²¬²««œ¤¦œ¤¦„„Š›”›¦§¨[[Tztl”››œ››ƒƒ|ƒ}ƒƒ„„{u{{{t‹„‹š””Š}|b[Uztl‘Œ…‚|uek]¦§¨£œ¥ŠŠ}‰‘~‚utztf¤¤””‹“Œ”Œ‹“{||‹‹‹’ŒŒ{||tll£œ¥ulttt{tsl”š”™š¤ŒŒš£››””‹„Š„“Œ”‹‹„ƒƒ|™š¤œ¤¦‚|u¦§¨‹‹‹sreƒ‚u‹„„u{{lld|„…JHFdc\tsl‘Œ…[[TUMRMSSUMRultlks{{t{{t“Œ”{ttlddŒ‹“{||llkuzt{{tƒ„„ttsŒ”•››”{tt‹’Šlld[TT‚v{ƒ„„„Š„‚ut‹„„‹‹„””‹Šƒ}››”lldldd‹‹„“~ˆ£œ¥:97*)(ƒƒ|ƒ„„ƒ}ƒztlu{{ƒƒ|d\\Šƒ}‚|u|„…tts{{tUTS£››…„’”››ttsredldd{u{llkekdtt{¤¤‹‹„{{tlld{||ttstll“““‹„‹‚v{‹„„mttdc\ƒ||ekdlrikd\{ttŒ”•™š¤lriƒ„„|„…Œ”•tts„Š}|‚ztllŒ‹“‹’ŠŠŠ}tzl„Š„Š}ƒ{u{LKRd\\rr]f]cd\\ddcf]c‚utdc\kk]ztl›¢›¤¤””‹ƒ„„tt{srekd\[TT[TTj]\ultsleŠƒ}ƒ„„‚utŠ}|Œ”•tslult{{ƒƒ„„ƒ||‘…„‚|uult“““tslŠ}ƒ””‹{yf‚|u‘Œ…‘Œ…‹‹„z‚l‹‹‹uzttllrg]|„…tsl›”›{u{’ŒŒ{tt‚v‚dc\{ttƒ„„‹’Š‹‹‹„Š„{{ƒ‹‹‹‹„„{u{{{ƒ{tt‹„„red‘…„‹‹„¦§¨‹„‹”“›ƒ}ƒ‹„„”𔛢›„Š„£›››”›¤¤ztl‚|u‹’Š{u{‚|u’…‹šŒ¤¤››”ƒƒ|‹‹„Œ”•rfk™š¤llk‚|uƒƒ|¨©´‹’Š‹‹‹ƒ„„tts‹„‹¨©´“““‚utzllrg]Šƒ}jcVsreŒ”•‚v{‹’Š””‹redŠŠ}ztlkd\„Š}VTLtsl””‹‚v{’ŒŒƒ„„››”‹„‹kk]››”lri‹’Šedktll›”›{{t™š¤¦§¨‹‹„œ››™š¤¨©´«²«”››‹„‹„Š„…‹’{{ƒmttd\\VZTƒƒ|ƒ||”š”ƒƒ|[TTJHFf]c{{ƒf]ctsl‹‹„”“›‹‹‹‚ut“Œ”lri|„…{||uzt¦§¨™š¤ƒ}ƒ””‹‚|uƒƒ|‚wlƒ„„ult{||‹‹‹““““Œ”“Œ”’…‹‚ut‹‹„‹„„Œ”•‹„„Šƒ}£œ¥JHF*)(‹‹„‹„‹ƒƒ|ƒ||mtt””‹ztl‚|u‚ut›”›¤¤{{tlri{||d\\ldd‹’Š]bZƒ}ƒƒ}Š|‚z|‚z„Š„‹‹‹‹‹„”››¦§¨™š¤‚|u””‹Œ‹“¦§¨‹„„””‹”š”uztlrillddc\{{tztl‹„‹rfk‹…’’ŒŒkk]™š¤|„…”š”[TT{||tts{||{ttlldllkmw’ŒŒ\UZƒ„„{zm‹„„{u{ƒ||‹‹‹‚v{tslsreztf‚wlkk]ddcdc\ultzll‹„‹{tt‚v{{{tkd\dc\’ŒŒƒ„„d\\›”›d\\[[Tkd\rfktslVTL‚ut£››„Š„tslb[U“Œ”{ttulttllztltll‚ut|‚zlriŒ‹“f]cŠƒ}“““{zm‹„„››”Š}ƒd\\f]clri‹„„{||‹’Š|‚zlldtt{‹„‹‹„„‹„‹{{ƒ|„…ƒ||Š}|ƒ„„ƒ„„Œ‹“‹„„’…‹ttsŠŠ}œ¤¦uztsleŠ}ƒ’…‹£››¦§¨£››‹‹„ultŠ}ƒ‚v{“““Šƒ}¦§¨„Š}ƒƒ|…‹‹zll‹‹‹“““‹‹‹dc\‘Œ…dc\{||ƒ||mtt””‹tll‚v{’ŒŒ{ttŠ}|Š}|kk]sle‹‹„‚v{‚utztfƒ}ƒ››”””‹|‚zsreSKJllk{||kk]›¢›…‹‹›¢›“Œ”‹‹‹ldd|„…Œ”•„„Ц§¨‹‹„’…‹ƒ}ƒ””‹”š”œ››ƒ„„£œ¥|‚z{{ƒ“““‹‹‹lekttsƒ„„lrilddlri’ŒŒ„‰v{ttf]clriƒ}ƒ“Œ”‹„„›¢›ƒƒ|{u{Š}|‹„„…‹‹‹’Š|„…ƒ„„ƒ„„‘Œ…Š~‹¦§¨ztlŠŠ}‹’Š{{tŒ”•‹„‹tts|‚z{u{{u{Š}|£››™‹†¦§¨¦§¨ƒ||“““ŠŠ}£››:97*)(Šƒ}Œ”•‘…„{ttŠ}|ƒ}Š‘Œ…ƒ||{||ƒ„„Œ‹“›¢›llkkd\{u{…‹‹”“›’ŒŒ‹‹‹tts“““\[[z‚l{||‹‹‹µ¶·“““¦§¨‚|u›¢›”“›Œ‹“{{tslerfk„Š„‹‹„‹‹„›¢›{{tdc\ƒ}ƒ‹„„›¢›‹‹„ek]f]c|„…ƒƒ|‹‹„‚v{„Š„‹„‹“““zll{tt{u{[TT{{tllkzll{ttllklribVUultf]cdc\{{tVTLƒ||ƒƒ|lri{zmkk]ƒƒ|lddtllŠŠ}‹„‹VTLredƒ}ƒ“““›”›„„Š‹‹‹ƒ„„f]c|‚zsle‹„„ƒ||tllddc””‹š””‹‹‹ƒ„„‹’Š{zmbVUƒ‚u“““dc\ƒ„„[[T‹‹‹{{t‹’Š“““‘Œ…ƒ||Š}ƒztlttsultttsfkkllk|‚z\[bttsƒ„„“Œ”mttlri‹‹‹tts‹‹‹””‹ult‚ut›”›ult‚|u{{t„Š„ttstll“Œ”£››š””£››{{tƒ„„redf]cŠ}ƒ””‹‹‹„””‹¦§¨›¢›ƒƒ|\UZ”š”|‚z››”tsldc\{||‹’Šult‹‹‹{{t‚v{ztlƒ}ƒzll¦§¨b[Utzlƒ„„œ››Šƒ}dc\‘…„Šƒ}‚wl{zm{{tuzt‹‹„œ››{tttzl{ttƒ}ƒ››”{{t¤¤uzt”𔋋‹‹„„‹‹„“““u{{‹„„Œ”•”“›„Š}“““tsl{ttfkkŠ}|‹‹‹ƒ„„{||sle]cdtts‚|u|‚zƒƒ|Œ—£edkf]cultƒ}Š„Š}ƒƒ|¨©´š””””‹|„…ƒ‚u‹‹‹ƒ„„ƒƒ|‰|v›”›™š¤µ¶·¤¤››”›¢›“Œ”“““”š”ƒ„„lddultultred𔔣››£››“Œ”’…‹‚wl¦§¨JHF)+2››”ŠŠ}ult‹„‹”“››”›£œ¥‚v{sle‹„‹‹„‹lldlek[TTlks‚v{Œ”•ƒƒ|ƒ}ƒ„„Š”››uztu{{{u{‹‹‹¦§¨„Š}¦§¨¤¤ƒƒ|¦§¨£›››”›‹’Š‚|u£œ¥”š”ƒ„„mtt[TT|‚zlek{||ƒ„„{||lldultddctsl„Š„sle™š¤’ŒŒjV[{{trfk‹„‹lek‚v{ƒ„„f]cƒ||lddd\\d\\b[Ullk””‹rg]{{tkd\|„…‹‹„Š}|ttsttsƒ||sle‘Œ…””‹ƒ‚n‚|u„„Šš””œ››””‹ƒ„„ƒ}ƒlddlddtllkd\‚utrg]f]cztlƒƒ|’…‹‹‹„ƒ‚uƒ}ƒb[Ullddc\ƒ||ƒ}ƒ{u{llk{||tsl‚|u””‹{tt‹„„ddcŠŠ}{u{ddcƒ„„‹„„“““tt{{{ttt{„„Š™š¤ƒ„„UTS‚v{lek|‚zddcd\\‹‹‹kd\ztl…‹‹“Œ”“Œ”¦§¨Â¾Æ£››””‹¤¤«²«””‹Š}ƒult‰|v“Œ”uzt„Š}‹’Šƒ„„œ››‹„‹‹‹‹ŠŠ}„Š„{||™š¤¦§¨“Œ”{ttd\\œ››š””ƒ||‹„‹“Œ”š””””‹ƒ„„‹’Š“Œ”‹’Š‹‹„²¬µsre‹‹„sretsl¦§¨Œ”•›¢›‚v{Šƒ}{{tƒ||“““‹’Š‹‹„lld|‚zƒƒ|ldd“““‹‹„“““ƒ}ƒuztƒ||{u{„„Š‹‹„ƒ„„‹„„tts£œ¥ƒƒ|…‹‹‹„„]bZ‹„„‚|u|‚zœ››‚|u\[b\[bbVU‹„‹kk]ƒ„„“““›¢›ƒƒ|ƒ„„“Œ”tsllld{u{Š}|£œ¥¦§¨dc\””‹¤¤{zm”“›œ››Œ‹“œ››„Š„“Œ”‹„„‹„„zll¦§¨‹„„£œ¥‘Œ…‹‹„²²¬\[b*)(zll[[T{tt‚|uddc{tt„Š„œ¤¦ƒ||ult{{t‚|u„Š„š””ƒ}ƒedk{||“Œ”tt{‚|uztl|‚z„Š„ult“Œ”tzl”𔋋„„Š„‹‹‹“Œ”ƒ||ƒ„„ztltts]cd””‹|‚z‹’Š””‹|„…u{{‹„‹…‹‹llklddtllmttƒƒ|š””ŠŠ}tts‹„„{u{ƒ}ƒ™š¤tllUMRllkttstll{ttmwSKJ[[Td\\“““’…‹cbV‚|uyle‹‹„ƒ„„š””‚|ulldŠƒ}tts‹‹„sleŠŠ}””‹£œ¥{u{™š¤“Œ”zllrfkf]ctsl{tt{tt{zmŠ}ƒ…‹‹ƒ||‹„„™š¤”››ƒƒ|‹„‹‹‹‹kd\llkƒƒ||‚z‹„‹zlltsl{zmƒƒ|’ŒŒ{ttš””„Š„‹’Štlltsl|„…{{t{||“Œ”{u{Œ”•‹‹‹‹…’”“›lri‚v{ult{||¦§¨“““ƒ||‹„„ƒƒ|£››””‹“Œ”“Œ”£²Ã¼¿¦§¨{zm¦§¨Œ‹“œ››²¬µ{{t‘…„f]c“““›¢›¦§¨ƒ||„„Š‹„‹ŠŠ}{{tœ››lri””‹ƒƒ|‹„‹‚v{lekf]c‚wl{||“Œ”šŒ””‹ƒƒ|“““›”›œ››{{t“Œ”sre””‹¦§¨‹’Š|‚z–¢‹‹‹‹ddc‹„„{{t‹„„šŒtslŠƒ}llk\[[ƒ}ƒztlƒ}ƒƒ}ƒfkk¦§¨“““Œ‹“””‹“Œ”Œ”•ultllksle‹‹‹“““|‚z{||„Š„VTL\UZ„Š}£œ¥lddedkUMRŒŒšf]c‹‹‹{{tult{||‚ut‹‹‹ttslddllk””‹Š~‹›”›’…‹uzt‘Œ…tsl””‹‹‹‹Š~‹„„Š|‚z‹‹„ƒ„„‹‹‹Š}ƒj]\‘Œ…ƒƒ|‹‹„tt{š””µ¶·f]c*)(tll‚|uš””‹…’mtt{u{Š}|{zmtslf]c|‚zlrikd\[TTtt{‚|ulri™š¤ƒ}ƒdc\„„Š„Š}ƒ„„‹„„{tt¤¤œ››Œ‹“›”›tts²««‹‹‹‹„‹‹‹„{{tƒ||”››ƒƒ|„Š„ƒ‚uŒ”•”“›tt{“Œ”Š~‹‹‹„‹’Š{{ƒVTL‚v{|‚z™š¤‹‹‹’…‹|„…ƒ}Š‹„‹‹‹‹ƒ}ƒŒ”•‚utdc\kd\\[[‚utƒ||{{t‹‹„‚|ulri‰v|ttsttsllkƒ„„|‚z’…‹j]\‹’Š{u{i\Vsreš””›”›Šƒ}ƒ||VTL‹„„ylellkztfmwlddtsl{zmƒƒ|„Š}{u{‹„„‰ƒv‚utœ››ƒ‚ullk„Š„sreƒ}ƒd\\kk]Šƒ}‚ut{tt‹„„‚ut{||ekdƒ„„”š”tslƒ}ƒƒƒ|{||{{t{{ƒ››”ŒŒš™š¤{u{‹„‹¦§¨{{t¦§¨µ¶·‹’Š‹‹‹“““£œ¥Œ”•‘Œ…£œ¥‹„„‘…„’ŒŒ™š¤ƒƒ|¨©´tll‚v‚““““Œ”{u{œ››””‹“Œ”ekdŒ‹“ƒ}ƒ‘Œ…ƒƒ|‹„„kk]ttsrfk‹‹„‚v{ƒ||zll‹„„lri›”›‘Œ…‹‹‹¦§¨”››£››‹’Š‘Œ…‚utŠƒ}{{t‹’Š‹‹„‹’Š”š”{u{tsl{{t‹‹‹u{{ddcttsƒ‚u…‹‹{||ƒ„„{{t„Š„‹’Ц§¨{u{“““tll›¢›‹„„‹‹‹‹„„‹„‹””‹…‹‹”››lek{{ƒ|„…d\\ult{zm¤¤ultlkslks{u{rfkdc\ƒ„„ƒ}ƒlri{{t”“›ƒ}ƒ„Š„{{t‚ut{tt›”›Œ‹“‹’Šƒƒ|llk{zmƒ}ƒƒ||tts{zm{{ttllrfkŠƒ}{ttsreƒ||{yf‹’Šztl””‹JHF?;C‘Œ…‘Œ…”››‹„„ƒ}ƒtzlulttll[[T›”›‹‹„\[[ultƒ||tllƒ||Œ”•|‚zƒ||’…‹‘…„lri“Œ”‹‹„”“›“““ekdlld‹„„u{{ult‚|ukk][TT{ttkd\ddc‚|uƒ„„{{t„„Šƒ||“Œ”“Œ”tllek]‹„„ddc‰‰w„Š„[[Tllkd\\…‹‹f]c{u{llk‚utlrittstllultsle{ttj]\{||ddcsleztl[TTred‹’Šlddzllƒ||\[[‚v{{||{{t™š¤{ttlld’ŒŒ‹‹„u{{{||lek“Œ”£››tslƒ||ztl…‹’tsl„Š„”š”|‚z£œ¥š””””‹|„…{{ƒƒ‚ulriƒƒ|lld‹„„dc\{ttƒƒ|ztfultƒ||‹„„lks{{t“Œ”|„…‹‹‹›”›””‹{u{tll™š¤llk£››£œ¥‹‹‹dc\|‚z””‹œ››‹„‹¤¤’ŒŒult””‹”››tllƒ}ƒultƒƒ|‹‹„lld”š””››lriŒ”•tllƒ||””‹kk]‚ut¨©´›”›„„Š‹„„‹„„››”tts{||››”…‹‹rg]ƒ||šŒ£œ¥‹„‹ƒ„„ƒ}ƒŠ}|ƒ||‹„‹{||²¬µŒ”•Šƒ}ƒ‚ukk]‰ƒv›¢›‹’Š”š”ƒƒ|’ŒŒ‹„„¦§¨œ››ƒ„„ldd|„…|„…‰‘~]bZult‹…’ƒƒ|››”sleƒ„„llkƒ}ƒ””‹‹„‹|‚zƒ}ƒ{u{„Š„ƒ„„„„Š‹‹‹„„Š|‚z]bZŒ‹“›¢›„Š}|„…JHFlksult›”›‹’Šƒƒ|’…‹ƒƒ|tllŠ}ƒ{{ƒª³·“Œ”‚wl‘…„„vŒ‹‹‹¨©´””‹sletts””‹‚ut’ŒŒ{||ttsœ››ztl“Œ”‘…„‚|uztl‹‹‹{{tek]¤¤:97*)(‘Œ…tlltslekdult‹„„Š}|ultkd\mttƒƒ||„…u{{kd\{u{lddekd{{ƒlekVTL™š¤œ¤¦œ¤¦”𔓓“ƒ„„œ¤¦{{ƒ{|||„…’ŒŒ››”¨©´lldtll|‚z›”›ƒ||tslƒ„„¦§¨”“›ult”š”|„…‹’Šƒ„„ddcƒ||ƒ}ƒ{{t\UZllk„„Š‹‹‹{u{ƒ}ƒultj]\“Œ”r]g{||ƒ||{u{j]\›”›Šƒ}tsl‰|v”››Šƒ}ª³·ult{yfšŒtzl‚utbVUllkzll’ŒŒf]cƒ||‚uttts\UZ{{tztlƒ||ƒƒ|‹‹„šŒlld{{tz‚lŒ”•tts”››””‹{{t’ŒŒtts‚ut{||‹‹„ƒ„„“““d\\‹„‹ztf’ŒŒzll‹„„’ŒŒƒ„„››”ult…‹‹ƒ||š””Œ”•{u{›”›lks‹„„”››llk“““Œ‹“””‹ztl™š¤œ››²¬µ£››{{t{{tllk‘Œ…‚v{š””””‹œ¤¦‹‹‹›¢›œ¤¦“Œ””“›{{ƒ‚utkd\lld”𔋄‹’ŒŒ¨©´‹„„ƒ„„{{tƒ„„tzl›¢›‹‹‹‘…„¦§¨››”£œ¥¦§¨£››“Œ”£››‚|u{{tƒ„„‹„„”š”{u{“Œ”dc\‚ut{{tjcVœ››“““{u{lek›¢›””‹„Š„mtt‹’Šuzttzllrimtt\UZmtt”š”œ››{tt‹’Š‹„‹›”›¦§¨œ››ztltt{Œ”•¦§¨”“›„„Š›”›”“›‹’ŠtllŒ”•œ¤¦ƒƒ|UUYUMR\[bult‹’Š”››…‹‹uzttll“““ƒ}Š{||lks””‹ulttt{lddƒ„„“Œ”sretslƒ||‹„„tllƒ„„‹‹„{u{“Œ”‚ut‚v{ŠŠ}{{t|‚zƒ||lld¦§¨VTL74,‹’Šš””‹’Štt{“Œ”ƒ||‚v{[[T]bZlek‹„„”š”ztllri{{ƒult{||llkultkd\sle¦§¨Œ”•‹’Ц§¨Œ‹“¦§¨‚utš””ƒ„„“““”››{{tƒ||””‹Šƒ}{||“““b[U›¢›œ§²£œ¥Œ‹“mttŒ”•‹„‹ultf]c‹„‹ldd‹„„tts‹„‹uztSKJ[TTultult„„Šllki\Vƒ}ƒ{tt‹„„””‹j]\£››ƒ||¤¤Œ”•‹„„dc\‹‹„ŠŠ}{{tVTL‚utSKJtzlb[U{ttSKJ{ttkd\ƒ„„bVU[TTŠƒ}{ttuzt‹„„zllkk]tll{||‘…„‹’Š“““lddbVU‚utkk]lri‹‹‹ttsŠŠ}…‹‹|‚z“Œ”¤¤‹„„{ttrfk‹‹„{ttŠƒ}‹…’‹‹‹”š”tts”“›tllš””{{ƒƒ„„„„Š“Œ””“›{tt›¢›kd\”››“Œ”‘…„ultttslld‹„„sle›”›ƒ}ƒ£››‹’Š“““”𔓓““Œ”|„…‹…’Œ”•‹„„””‹£››“Œ”Šƒ}“Œ”“Œ”¦§¨›¢›’…‹u{{tzlƒ}ƒedk“““¦§¨‰v|red¦§¨“Œ”‚ut|„…Šƒ}‹‹„{||”“›‘Œ…£››‹’Š{zmŠƒ}„Š„¦§¨š””œ››™š¤››”‹„‹Šƒ}Œ”•{{tƒƒ||‚z|‚z’ˆllk”š”|‚zddcƒ„„…‹‹ƒ||{u{‹u…„Š}tt{‹„‹”››”š”Œ”•µ¶·œ››lri‹’ŠŒŒš¨©´‹’Šƒ}Š[TTf]clek¦§¨{||lld|‚zmtttt{{{tƒ||tt{{u{redd\\ƒ}ƒ™š¤””‹{u{‹‹„tslztlulttll‚ut„Š}‹„„Šƒ}šŒ{tt‹„„…‹‹tzlmtt{zm›¢›JHF:97{{t‘ˆ}dc\…‹‹Œ‹“š””ztlztlllk‹’Šdc\ƒƒ|cbVz‚l„„Šult››”llk{||ultŠƒ}„‰v|„…ƒƒ|ƒ}ƒ“““‹’Štt{¦§¨¦§¨{tt”››tt{‹‹„lriztl{||tllƒƒ|VZT|‚z™š¤tt{fkkllkƒ||[TTJHFf]c\[[lldultf]cf]c\UZllk‹„„ult‹‹‹lekyfllek¤¤ƒ}ƒ{zmŠŠ}‚wlSKJšŒd\\JHF{{t|‚zsre’ŒŒ{{tƒ||red{{t‚|usre{||Š}|cbVtllzll‹’Š{tt‹‹„‹„„ztl‚uttllllkƒ||‹‹„{tttzlVTLtll]bZkd\ƒ‚uƒƒ|”››‹‹„™š¤lld{ttƒƒ|‹’Š“Œ”‚v{’ŒŒŠ}|››”{|||„…„Š„tt{Œ”•“Œ”‹„„„„Š‹‹‹{ttmttultzllƒ„„¤¤ƒ}ƒlddldd£››“Œ”ddcƒƒ|ƒƒ|‘…„¤¤””‹Œ”•”››tts”š”””‹£œ¥ƒ„„Š}ƒ¦§¨ƒ‚u››”£œ¥’ŒŒ“Œ”£²‚|uredu{{ztl’‘~Š}|ƒƒ|𔔣œ¥{tt‹„„b[U£››kd\Š}ƒkd\‹’Š‹„‹ƒƒ|£››£››””‹Š}|{{ttts””‹””‹£œ¥{{tlri‹’ŠŒ‹“tsllriz}‹’ŠŒ”•tsl“““ult””‹ztlzllœ¤¦Š}ƒƒ||{ttŒ”•„Š„ztl”š”…‹‹”››‹’Š”“›ƒƒ||‚z\[[›¢›lldŒ”•‹‹„’ŒŒ{u{‹…’’ŒŒŒ”•ƒ„„œ¤¦™š¤‹…’‹„‹uzt‹„‹¤¤‹„„{tttll¦§¨ƒƒ|{zm„„ŠŠ}|ulttll”››{zm{{t’ŒŒš””tll‹‹„‹‹‹”𔓓“””‹¤¤JHF*)(ultcbV|‚zttsƒ„„]bZŒ”•red{ttj]\‹’Štslƒƒ|kk]ult¤¤”“›Œ”•f]ckd\bVU‹’Š…‹‹dc\d\\¤¤‹’Š|‚zŠ}|ƒ}ƒŒ‹“ƒƒ|“Œ”zll£œ¥{{t{{ƒllkuzto€wlkstt{™š¤u{{Œ”•UMRd\\ldd‚v{UMRj]\ultmwtsledkUTSƒ||ƒƒ|ƒƒ|tt{‘Œ…tll‹‹„‹‹„{{t[[T{ttredztllldlriƒ}ƒtzl{{td\\ƒ‚u‚|uƒ||ƒ‚u{||£››ldd{tt[TTd\\FD;rr]{tt{tt“““š””tll‹„‹ƒ„„‹‹‹tsllldd\\ztl{{t””‹ztltzl{{t|‚z’…‹‹‹‹…‹‹‹„„ztlƒ„„rfk”“›‹‹„{u{‹‹‹{{ƒztllddj]\mtt‹„‹{ttlek“““„Š„tt{\[bllk|‚z””‹™š¤ƒƒ|ƒ||tll{||„Š„’ŒŒ„Š„¦§¨œ››£œ¥{||”š”ª³·œ¤¦ƒ‚uŒ”•Š}ƒ··Ä£œ¥¦§¨«²«œ››f]cŒ‹“‹„„{{tƒ„„f]c‹’Š‹„„“““ldd{ttŠ}ƒtllŠ}ƒcbVddc{u{š””ƒ||ztlttsƒƒ|Šƒ}–¢‹››”””‹ƒƒ|ƒ„„𔔣œ¥„„Šztl{{t‹‹„…‹‹u{{lddlriŒ”•mtt]cd]cdŠ}ƒedkj]\‚|u‹‹„¦§¨redult”š”™š¤’ŒŒ™š¤š””¦§¨uztƒ}Š|„…dc\tlllri|„…|‚ztt{u{{™š¤{{tƒ||„Š„ƒƒ|œ¤¦ƒ}ƒtslƒ}ƒ|‚zƒ}ƒ‹„„‚|umtt{u{{zm„Š„ztlddcztlult‹‹‹{ttztlƒ||kd\‚|uultf]c{{ƒƒ||”𔣛›“““>EC:97tslSKJ{{tŒ‹“‹’ŠVTL‚wlŠ}|{u{d\\rg]|‚z„Š}mtt‹’Šš””™š¤{{tbVZ{u{sre|„…‹‹‹ƒƒ|{||zll|‚z{u{””‹”š”uzt”››ulttll{{tlddƒ}Š{tt|‚z‹’ŠUTSŒ‹“ult\[blrilldf]ctll£œ¥mwtsllek‹„‹””‹…‹‹JHFuzt¦§¨{tt[[T›”›{||kk]’ŒŒ‚utSKJred‚v{‹’Šllk|‚z‹’Љƒv‹„„d\\tslultedkƒ}ƒ“““ƒƒ||„…b[Uztl‘Œ…„Š}kjV‚|utllƒ„„{{t{tt›”›dc\ƒƒ|ƒƒ|{||lldƒ‚u””‹‘Œ…””‹‹„„‹„‹”š”ƒ}ƒƒ}ƒtts{tt‹‹„{{t‹„„ƒ}ƒƒƒ|{||Œ”•‹„‹”“›|„…{||Œ”•ttslektt{{tt{||Œ”•‹„„œ››‹‹‹¦§¨ƒ}ƒ{{t’ŒŒ‚v{tslŒ”•š””‘Œ…“Œ”¦§¨››”’ŒŒµ¶·œ¤¦‹’Štslœ››{tt…‹‹¦§¨›¢›¦§¨“““‹…’ƒ}ƒš””¤¤¦§¨£››š””›¢›¦§¨ª³·œ››‹„‹‹„„{tttts{zm‹„„£››{tt{{t{ttŒ‹“\UZred‹’Š{u{uztš””Šƒ}œ››‹„‹{ttbVU{|||„…]bZŒ”•‹’Š›¢›Œ”•…‹‹‹‹„ult””‹‹’Š“““„„Šult“““š””‹„‹“““|‚zultdc\llkkd\tlledkttsultfkklks\[blekllk{{ƒkk]‹’Šœ¤¦¤¤Œ”•œ››¦§¨ekdttsƒ}Š{||‹‹„“Œ”{u{uzt{{tdc\|‚z‘Œ…“Œ”ƒ„„Œ”•{{tztf‘…„ƒ„„›”›llkšŒ””‹“““’…‹‹’Š:977-2”››‹‹„ŠŠ}”š”llk{u{ƒƒ|‹„„„„Š{u{tzllld|‚zlldu{{ttstt{lriultŠŠ}]bZkd\{ttƒ||tll””‹lld’ŒŒŠƒ}‘Œ…|‚zƒ}ƒ”“›rfk¤¤‹’Š“““|‚zƒƒ|{||™š¤llktt{„Š„lksf]c{u{SKJƒ}Š{ttlldŒ‹“tll{tt‚v{…‹‹|‚z|‚zuzt[TTƒ||llk‚wlrfkVTLsleƒ||slettslld‹‹„tts|‚zsleƒ||aWMSKJFD;ztlultu{{“Œ”[TT””‹slelldkd\‚|utsltts„Š„‹„‹uzttllb[Utyg{{ƒ””‹ztlsrekk]‹„‹{{t™š¤¦§¨››”“Œ”ddc””‹‹„„sle‹…’ƒ„„”𔋋‹|‚ztts…‹‹ƒ}Š{tttt{{||“““ddc‹…’{||{{ƒtts„„Š‹„‹¤¤Š~‹“““‘…„ƒ}ƒ›¢›‹’Š››”{{t£œ¥™š¤’ŒŒµ¶·œ¤¦œ¤¦¤¤””‹¨©´µ¶·™š¤œ››µ¶·¦§¨“Œ”£œ¥“Œ”f]cƒ„„mw‹„‹‚wl‚|u””‹””‹””‹„Š„„„Š“Œ”uztbVU››”“Œ”lld‹‹„ddctsl‹„‹{ttsle‚|uƒ„„ult“Œ”{||“Œ”rg]ƒƒ|Šƒ}ƒ„„lri{||œ››mtt|‚z„„Štt{ddc’…‹“““›¢›{||rfk››”£œ¥‹‹‹„Š}ztlŒ”•zll‹’Šƒ||lddŒ”•ƒƒ|‚v{uztVTLultSKJtslŒ‹“[[Ttzl‹’Š‹‹„{||{||„Š„{tt””‹„Š„““““““Œ”•{{ƒ‹’Šultƒƒ|ƒ„„{{t‹„„{u{“““”𔋄„Š}|ƒ||tsl{u{‚|u{tt|„…uzt”š”>B9*)(zllƒ|||„…“Œ”{{tllklddbVUd\\lddek]UTSlri[[T{{ƒtslult{{td\\„Š}u{{cbVbVZ››”ƒ}ƒsleb[U{||zll‹„„{||”“›ƒ}ƒtsl{ttƒ‚u|‚z„„Šuzt|„…|„…{{ƒ\[bJHFJHF\[[f]cd\\\UZb[Ud\\ƒ„„ttsd\\VTLƒ}ƒ‹„‹{zmtsl{||‚|u{{tƒƒ|„„Šf]c]bZsleldd£››ddclld|‚ztzl‚|utllaWMsre{{ƒ{zmŒ‹“j]\tllƒ||‹„„tslztlf]cb[U|‚z{||Šƒ}Œ‹“dc\|„…zll‹‹„Œ”•ek]tsl‚ut‘Œ…{ttƒƒ|lri‚v‚‹‹„ƒ}ƒ¤¤tlliq]tsld\\{||{{t‹„‹|‚z›”›{{ƒƒ}ƒš””Œ‹“›”›ƒ}ƒ{{ƒ{||ƒ}ƒ”š”{u{ƒ||‹„„Œ”•Š}ƒ‹„„¦§¨’ŒŒ‹’Š”“›”››“Œ”™š¤‹‹‹””‹¦§¨‹’Ѝ©´{{ƒ”“›ƒ}ƒŠ}ƒ“Œ”¤¤œ¤¦sle“““Š~‹£œ¥’ŒŒ“““œ›››¢›‹’Šƒ||‚|u{{tƒ|||‚z“Œ”ŒŒš\[[‚v{„Š}ztl{||“““‹„‹tsllldj]\ttstzl{||‚wl“Œ”ƒ}ƒƒ„„lldƒ||››”„Š„„„Šlldmttlks|„…lksuzt„„Š“Œ”››”‹‹‹{{ttts“Œ”ƒ}ƒ‹‹‹“““””‹Œ”•{{tƒƒ|ƒƒ|’ŒŒ‹‹‹lriƒ„„œ¤¦”“›Œ”•r]glldƒ„„mtt|‚z„Š„lddœ§²‚v{‹’Š’ŒŒƒ„„‹‹‹‘…„‘Œ…tt{{{ƒƒƒ|‹„‹š””Š~‹’ŒŒ‹‹‹‹„‹‹’Š{{t…‹‹{{t’ŒŒ“Œ”dc\VTLtllVTL]bZ’ŒŒJHFJHF“““‹‹‹|‚z|„…]bZSKJd\\ultddcd\\b[U|„…|‚zlekttssleultuzt‹‹‹‹„„{{t{{ƒ‹„‹“““ƒƒ|‘Œ…‹’Š|‚zllkldd|‚ztts{u{lddƒ}ƒ|‚z|‚zMRKddcult]bZlddultf]cmtt„„Štsl[TTultd\\lddu{{Š}ƒtllj]\„„Šf]c‚|ukd\{||{u{[TTŠ}|{u{sreztl‹„„{zmcbVƒ||„Š„tzltzlultkd\{||’ŒŒllk…‹‹zll‚utult‹‹„¦§¨kd\VTLsle””‹|‚zdc\“Œ”ƒ||ztl’ŒŒsresre”š”kk]tsl‚utsleldd‹‹‹‹…’ulttlllddllkSKJiq]tsl‹„„ƒ}ƒ‹‹‹Œ”•{tt{{ƒ{||llk‹’Š{{ƒ™š¤’ŒŒ™š¤|‚zŒ‹“™š¤ƒ||tts“““{{tkd\””‹ƒ||¦§¨Œ”•{||ƒ}ƒ””‹£œ¥‹„‹”𔛢›”››™š¤ult‹‹‹|‚z™š¤£œ¥uzt‹’Šœ››¨©´Œ‹““Œ”tsl|„…{{tœ››‚|u¦§¨“““œ¤¦Šƒ}™š¤ldd¦§¨Œ”•“Œ”‹„„’ŒŒ‹„„£œ¥Œ‹“ƒ„„dc\ldd‹„‹””‹‹‹„‹„‹‚|utt{ƒ„„›”›‹‹‹…‹‹tt{œ¤¦tsl|„…|„…{{t¨©´”š”„„ŠŒ”•{{ƒ|„…tts’ŒŒ””‹‚utŠƒ}Œ‹“sle™š¤””‹”››‚ut{||ª³·Œ”•£œ¥ekdœ¤¦£››…‹’Œ”•œ§²|‚z‹‹‹”››”𔦧¨™š¤œ›››¢›tsl”š”ƒ}ƒztl{u{llkƒ||¦§¨‘…„ƒ}ƒ‘Œ…‚v{ƒ„„””‹{{t{||{ttj]\ttsŠ}ƒ|‚zttsddc„Š„‹„„SKJ*)({||dc\lddtllVTLf]c‹‹‹{u{uztttstslu{{””‹lriu{{f]c‹‹‹ƒ„„u{{lld‹‹„Œ‹“‹„„ƒ„„…‹‹’ŒŒƒ||ƒ||²¬µdc\b[U¦§¨‹„„„„Šllk“““‹„„uzttzlddcu{{d\\ddcJHFVZTSKJ“““’ŒŒ‚v{tt{[TTlksƒ||tsld\\[TTddc””‹‚|utts’…‹{||red{ttd\\sle””‹d\\ƒ}ƒ\[[z‚lŒ”•ƒ„„bVZŠ}|’ŒŒƒ||ƒ||{||‚v{rg]rfkkd\‹„‹ƒƒ|kd\{{tslesrelld‹„„red|‚zsletslztl…‹‹{tt‚|uš…ŽŠ}|“Œ”‹’ŠŠ}ƒ{{t‚|u{tttslƒƒ|sleƒƒ|‚v{tsl{tt”››ƒ„„£››tts|„…ƒƒ|{u{ttstt{ƒ„„mtt“Œ”™š¤‚v{llk{ttŠŠ}™š¤ztl£œ¥‹„„‹‹‹¨©´’ŒŒ™š¤“Œ”“Œ”„Š}‹‹‹|‚z¦§¨ƒ„„„Š}¦§¨“Œ”‹„„„Š„µ¶·Â¾Æ£››£››Š~‹›¢›”𔄄Л¢›Šƒ}¦§¨‹‹‹{tt¦§¨””‹‹’Š›”›{||“Œ”tts‚ut£››’ŒŒ‹„„‘Œ…{||Š}ƒŠƒ}ƒ}Š”š”‘Œ…‘Œ…”“›ultœ››››”|„…lriš”””››|„…’ˆŒ‹“…‹’|„…|‚z”“›ult|„…dc\“““²¬µ’ŒŒœ››{u{ƒ}ƒ”“›‚|u{zm{tt‹‹„™š¤Œ‹“‹„‹„Š„Œ‹“ƒ}ƒ{ttttsu{{ª³·¦§¨ƒ„„Œ”•Œ‹“j]\””‹””‹uzt‹„„tsl‚v{ƒ}ƒuzt‹‹‹‹‹‹bVUƒ||ztl‹„‹Œ‹“{{t{tt{{t‚ut{ttllk‚|u{{t|‚z\[[dc\‹‹‹:97&&UTSd\\d\\u{{ztl|„…š””™š¤{{tƒ„„œ¤¦””‹|‚z|„…“““”š”“Œ”mtt‹‹„„Š„sle”››£œ¥‹’Š‹’Š‹‹„{{tlld›”›sletts‹‹„£œ¥ª³·{tt“““ekd…‹’ekdsrelrif]c‹„‹{{ƒmttsle{zmzllƒ||Œ‹“¦§¨ldd››”lektlledkult{{t\[[|„…£œ¥f]cttslddtslkd\sleSKJ‹‹‹\[[leklldtts{u{tll””‹{{tƒ}ƒš””ztlrfkttssle””‹VTLtllsleztf{u{uztŠ}ƒf]csredc\Šƒ}sre{u{{zm{||£››Š}|‹‹„“““lldkd\‹„‹{tttlld\\„Š„sreœ››„Š„{{t™š¤Œ‹“ƒ||ttstll{u{mtt””‹{tt”“›‹‹‹{{ƒ{{ƒ{tt{{ƒf]c”››”“›‹‹„Š~‹£œ¥ttsŒ—£››”tts’…‹ƒ}ŠŒ”•‹’ŠŒ”•ƒƒ|tsllri…‹’¦§¨‹‹‹“““»ÂÇ”š”“Œ”²¬µ›”›””‹tsltsl›¢›š””Š}|ult”š”””‹‹„‹‚|u{u{{{t{u{š””›”›ƒ„„tts‹‹‹ƒ}ƒ{{ƒ“Œ”llk›”›‹’Šƒ||š””|‚z‹„‹{{ƒ‹‹„|„…mtt\[[‹„„ƒ„„|„…|„…Œ‹“mttŒ”•f]cd\\|‚zƒƒ|‚ut‹…’‹…’‹„‹„Š„tllmtt‹„‹tll”š”ƒƒ|›¢›…‹‹™š¤mtt™š¤¨©´ztl{ttŒ”•Ž¡›”››u{{œ¤¦ttsƒ}ƒ¦§¨‹‹„Œ”•”››ƒƒ|lrilekttsŠ}|{||{tt{{tƒƒ|‹‹„š””ƒ‚uuzt‹„„‚ut‚v{lks‘…„‹„„{||{{ƒJHF£››:97*)([[TSKJJHF\[[lri“Œ”{||‹„‹tsl{ttlri‹’Š|‚zŠŠ}ƒ„„u{{™š¤kd\„Š„ƒ„„£››…‹’‚v‚›¢›Œ”•|‚z‹„‹œ¤¦“Œ”¦§¨„Š„Œ”•¦§¨“Œ””𔦧¨f]cf]cVTLek]kk]Œ”•ultd\\VTLŠ}ƒ{||„Š„f]ctt{Œ”•edkš””lddedk„„ŠuztVTLmtt…‹’ldd„Š„‹‹‹ƒ||kd\lddzlllksƒ||š””|„…{||{u{ƒ||lddtlld\\u{{ƒƒ|f]c[TTtllƒ||‚|u{zmj]\zllj]\{{t”“›tllŒ‹“{{tSKJ…‹‹¤¤|‚z„„ŠŠ}|ldd‹„„‹‹„ƒ}ƒ{ttƒ‚u‹‹‹„Š„“““ldd‹‹„‹’Š“““|‚z…‹‹{{ƒ{tt{{t{{ƒ‹‹„sle{||„Š„uzttts{u{ƒ||{{ƒ{tt{u{‹’ŠtslŒ‹“‹„„Œ‹“£œ¥tslŒ”•llktt{“Œ”lek„Š„”š”|„…›¢›œ››„‰vŒ”•œ››¨©´ª³·…‹’œ¤¦tt{‚v{²¬µ””‹œ¤¦Š}|‹‹„‹‹„ƒƒ|Œ”•””‹œ››ƒ}ƒ‘Œ…™š¤ƒƒ|‹„‹{||£››’…‹Œ‹“””‹›”›£››£››{{ƒ›”››¢›¦§¨œ››ƒƒ|Œ‹“{tt‚v{ƒ}ƒƒ„„‹„„zllmtt™š¤|„…ŒŒšJHFlldlks{ttsleldd“““™š¤‹„„‘…„‹’Šš””™š¤‹‹„‹‹„””‹Œ”•œ¤¦”››Œ‹“dc\…„’ƒ}ƒttsƒ„„{u{lld’…‹„„Ц§¨llk“Œ”“““{||tts|‚z“Œ”lek{{ƒult‚|uztl‚v{‚|u‹‹„š””‹„„„„Štzlœ››‰|vtlluzt”š”ttsllklld{{t››”SKJ*)(lkslldVTLUTSsref]ctllbVZtzllldmtt|‚z{{tƒƒ||‚zƒ„„Œ”•‹’Š‹’Šlld›¢›Œ”•šŒ¦§¨{||\[[‹’Š‹‹„””‹ƒ}Š{||…‹‹tll››”|‚z›¢›ŒŒšult”››lld{||mtt£››dc\MSS“““…‹‹”››’…‹{{ƒ„Š}lriztlsrezllŒ”•ttslddztl{||‹„„llkf]cllkultVTLsre{zmzllƒƒ|f]ctsl{||{u{dc\SKJ‹„‹ultlldƒ„„nƒf]c{||ŠŠ}””‹‰ƒvŠƒ}ult{||ƒƒ|‹„‹tts{zm{tt””‹‹‹‹“““{||{tt{tt‘…„tslŠ}ƒ£››ƒƒ|‹‹‹kd\sleulttllƒƒ|£››{{tŠƒ}ƒ„„”››‚ut…‹‹“Œ”llkllkttsllk™š¤{u{ddc…‹’Œ‹““““‚|uƒ||”››”š”’ŒŒ¦§¨œ¤¦|‚z‹’Š{{ƒ{u{ƒ}ŠŒ”•‹‹„|‚z‹„‹¦§¨›¢›«²«™š¤”“›„„Šš””‹‹‹ƒ}ƒ‹„„]cdƒ„„|„…š””uztkd\’ŒŒ{tttsl”š”Œ‹“{tt›”›ƒƒ|‹„„lek›”›¦§¨Œ”•{tt¤¤‹„„’ŒŒ£œ¥ŠŠ}tzlš””ƒƒ|”𔋋‹tllƒ}ƒ|„…redUMRtt{…‹‹UTS„„Š…„’ƒ„„…‹‹ƒ}ƒ“Œ”‹‹„ŠŠ}Š}|¦§¨µ¶·“Œ”‹‹‹“““tll“Œ”””‹››”›¢›Œ”•…‹‹lri„Š„{u{¨©´ŒŒš…‹‹u{{’ŒŒŒ”•”𔋋‹tt{™š¤uzt™š¤tts„„Š›”›¦§¨ƒ„„ƒƒ|tslš”””“›‰v|ƒƒ|Š}ƒkk]|„…ldd¦§¨š””’ŒŒ”𔋋„””‹{u{“““{||²««JHF3+*”››ƒƒ||„…UTSdc\Š}|‚ut[TT{||lkstsl|‚zƒƒ||‚z|‚zƒ}ƒ“Œ”lri’ŒŒ{{ƒ””‹|‚z›”›{||‹’Šƒ||ekd…‹‹rfkkd\ƒ‚uttsƒ||“Œ”‹‹‹›¢›ª³·‹„„mtt>B9JHFlksƒƒ|tsl””‹\UZ{{ƒ…‹’Œ‹“\UZfkk››”VTLult‚|u‹„‹¦§¨…‹‹d\\\[[ult‹‹„ek]llkbVUj]\tzlztlslekd\ult¦§¨‹’ŠŠƒ}ldd{tt{u{tt{b[USKJiWU{u{”“›ƒ„„{zmVTLrg]sreedkƒ||{ttttsƒ„„„Š„‹„„Š}|‹‹‹zlltllƒ||rg]ztlƒ||ztlbVUlddu{{Šƒ}kd\lldtsl‹’Štllsle{{t‹‹„{ttllkedk{ttttslldedk{u{tt{llklks|„…sre„Š}Œ”•Œ”•¦§¨ÂÅÓ”“›¦§¨…‹’”š”œ¤¦”“›“Œ”‹‹„|‚z¦§¨ƒ„„ƒ‚u›¢›œ¤¦™š¤£››{u{{{ƒ””‹‚v{lrif]cdc\”“›œ¤¦ƒƒ|ƒ‚u“““„„Š‹‹„‰‰wsretts{tt””‹£œ¥„Є𔔋„‹”“›‹‹‹„Š„ult‚v‚tllult|‚z„Š„{{tœ¤¦‹„‹’ŒŒ‚v{ƒ„„ldd{tt{||œ¤¦…‹’…‹‹{{ƒ›¢›lkslek‹„„‹„„ƒƒ|‹‹„‹u…’…‹‹„‹‹‹„’ŒŒ{{ƒ››”{{t¦§¨ŠŠ}¦§¨™š¤…„’{{tult„„Š|‚zŒ”•llktslmtt£œ¥|„…llklddlek{{ƒ{{tƒ„„‹„„ƒƒ|‚v{’ŒŒ¨©´¦§¨š””ƒ||””‹“Œ”‹„‹œ››‰ƒvkd\redulttsldc\sleƒ}ƒlekƒ„„””‹JHF{{tlldkd\UMRUTSlksSKJUTS]bZƒ||lritslkk]tslllk{tt{||ƒ||Š}|‚ut|‚z¦§¨‚v‚œ¤¦|‚z‹‹„|‚ztsl‹‹‹‹‹„…‹‹llkj]\Œ‹“|‚z£œ¥{u{tt{\[[|‚zlldŒŒš“Œ”uztkk]ƒ||tt{lek{u{“““dc\f]cuzt‚|ucbVu{{tzlddcƒƒ|dc\sleƒƒ|””‹‹‹„VTLb[Ulri{zm‚v‚ek]lldsle{||’ŒŒllkd\\›”›JHFttsb[UbVUztl{zmtzlŠŠ}SKJ]bZfkk|‚z‹„‹tll“Œ”[[TtslultŠ}|ƒ}ƒllkyle‚|u’…‹tllƒ||‚v{ztld\\{||yletlllri‚wlj]\‹„‹uzt‹‹‹ldduztult“Œ”‹„„{{ƒ{u{{{ƒŒ‹“lekmttddc„„Š™š¤{||¦§¨Œ”•{||··Ä¨©´œ¤¦Œ”•|‚z™š¤‹‹„u{{”“›ƒ„„ª³·¨©´ª³·Œ‹“¦§¨Œ”•‹„‹tsl™š¤œ››’ŒŒ‹„‹’ŒŒ¤¤”››“Œ”“““‹’Šƒ||‹‹‹¦§¨tsl“Œ”‹‹„ƒ}ƒtll£œ¥ƒ„„£››‹„‹‹„‹ƒ„„‹’Š‹‹‹Š}ƒttsš””‹‹‹{{tƒƒ|ƒƒ|[[T“““{|||‚ztllƒ}ƒƒ„„œ¤¦mtt|„…fkk£œ¥”“›“Œ”‚v{‹„‹„Š„|‚z“Œ”‹„„tlllri‹‹‹‹„‹£œ¥ldd‹‹„‰‰w”š”|„…{{ƒu{{¨©´Œ‹“lri„„Šllk{{tlks‹’ŠŒ”•‹’Šylelks{{ƒtslƒƒ|‹„„lks‚v{‹‹‹{{ƒŠ}ƒ‹„‹ztlztlbVZƒ}ƒ™š¤ztld\\Šƒ}{u{„Š„ƒ}ƒsrelekedkƒ„„£››JHF:97llklldj]\lek[[T„„Štslldd{||lekdc\dc\{ttb[UŒ‹“lkstsl‚|uŠƒ}ŠŠ}ƒƒ|Œ”•{{ƒœ¤¦””‹“““‹‹‹sleœ››{u{ttsŠ}ƒ›”›‹’Šlldƒ}ƒlddmtt|„…mtttll{{ƒ¨©´“““sle‹‹‹ƒ„„f]cJHFlks|„…b[UJHF{{tD;9u{{ƒƒ|‹‹‹œ››tts{||b[U]bZ[TTƒ||‹’Šƒ„„dc\ƒ||ttstsllldllkztl{{ƒ‹’ŠlekbVZf]cƒ||‚v{Š}|ƒ||ztfrg]VTLd\\lldllkttsf]cƒ„„ƒ‚u|‚z‚|uŠ}ƒlld‚|utll‘ˆ}zll’ŒŒrg]j]\{{td\\|‚z‹„„ztltt{‹‹‹uzt‚v{„Š„lldlldƒ„„mtt…‹’ƒ}ƒ„„Š{u{Œ”•|„…mttllk\[[›”›‹’Š{{ƒŒ”•|‚zƒ„„£²”››|„…œ§²›¢›Œ”•„„Š£œ¥“““Œ”•‹„‹{{ƒª³·››”lks™š¤£››ƒ||{{t¨©´“““œ››Œ‹“„Š„”››¨©´‹’Ц§¨¦§¨„Š„uzt¦§¨“Œ”{u{›”›‹„„’ŒŒƒ||””‹ultddc“““slerfk{u{{tt‹‹‹œ¤¦{{ttzl]bZmttƒ„„Œ‹“lri{ttŒŒš{tt\[[mttŒ”•{{ƒƒ}ŠŒ”•tt{‹‹„fkk{{tƒ„„ƒ}Šztlœ››uzt’ŒŒ“Œ”{{ƒ‘Œ…‘Œ…ƒ‚u„„Šedkƒ}ƒ‹‹‹¨©´{u{lriultnƒ|„…{{ƒ”“›lri‚utš””“““‹‹‹{{ƒ››”¦§¨”“›ƒ„„‹’Š£œ¥fkk‹„„‚|u””‹{tttzl£›››”›{{t‚v{{u{tsllddcbVSKJlddf]c£››JHF*)(\[[[TTSKJ‹’Šdc\ƒ}ƒ[TT‹’Š{{tlddSKJtsliq]b[U{{tek]‹‹‹sle””‹lldlrittsultlld]bZ”š”ddc£››ttsf]cttsu{{ultUMR‚|ulddultŒ‹“}‡’|‚z{tt”“›yfl{||‚|utsltt{edkSKJlksuzt{{tJHFtll\[[‹’Škk]›¢›ƒ„„‹‹‹ƒ||lldœ››Šƒ}{zm{ttddcb[U{||z‚l‹’Š”“›{||b[Ud\\VTLf]c\[[b[UUMRj]\‚|u{tt‘Œ…‚|uredsreƒƒ|…„’„Š„{||„Š„uzt”š”kd\kd\ƒ„„™š¤Šƒ}{{tƒƒ|tsl{u{‘Œ…lritlllld{ttzllyleƒƒ|tslttsŒ”•lldekd‹‹„{{ƒŒ‹“yl„]cdultuztult{{ƒ{||tt{¦§¨…‹‹”››uzt…‹‹¦§¨Œ‹“¨©´œ¤¦lrimtt…‹’Œ‹“‹‹‹ƒ„„‹‹‹|„…“Œ””››|„…£œ¥¨©´¤¤‹„„œ¤¦“““¦§¨··Ä‹…’ŠŠ}{{ƒ{u{{{ƒƒƒ|…‹‹”››“““µ¶·Š}ƒ{ttƒ}ƒƒ||“Œ”ƒ}ƒ{ttƒ}ƒ„„Š“Œ”‹‹„‹‹‹“Œ”‹…’…‹‹|‚zœ¤¦mttddctzl{{ƒultf]cƒ||UUYlddœ¤¦|„……‹‹rfk‹…’mttf]cd\\edk£››”››{u{ƒ||ƒ||››”“““lld“Œ”’ŒŒµ¶·’ŒŒƒ„„™š¤‚|u£œ¥Œ‹“‹„„”››„„Šmtt„Š„f]c‹…’Œ‹“’ŒŒ’…‹„Š}„„Š‹‹„‹‹„²¬µ‹„„ttslri„„Šƒ||llkƒƒ|ttsred{{tŠ}ƒ{{tƒƒ|tll‹„„\[[{{tkd\‹„‹ek]fkk¢—FD;3+*Œ”•VTLb[Ulrisrelddƒ||[TTJHFd\\\[[ƒ||sre{zmƒƒ|ztl‚utztlztllld””‹…‹‹“Œ””››ult|„…uzt‹‹„{u{uztultƒ||tt{llk„Š„lektlld\\[TT\[[[[TŒ”•œ››„„ŠbVUztlb[Uttsf]cf]c{||Šƒ}[[TVZTŒ”•|‚z…‹‹tzl|‚z{tt{u{{zmrg]“Œ”ztfkd\dc\{{tultlrikk][TT„Š„’ŒŒttsƒƒ|„„Šdc\ek]\[[mwiWUzlltsl’ŒŒlldldd|„…Œ”•lri””‹|„…tsl‹’Š‚utŠ}|‹„‹£››srekk]kd\ekd‚v{bVZdc\ƒ}ƒtygb[Uƒ||redlldlekult|‚ztts{{t{{tƒ}ƒ„„Š”“›{{ƒ{{ƒ]cd{{ƒ”“›tt{{||™š¤|‚z{{ƒ›¢›Œ”•tt{‹…’£œ¥…‹‹{{ƒª³·…‹š‹‹„‹‹„”››Œ‹“Š}|“Œ”¨©´…‹‹™š¤‹„‹š””‹‹‹{||‹’ŠedkUUY{{ƒ¦§¨tt{š””ultŒ”•‹‹‹¦§¨£œ¥¤¤uzt’ŒŒult£œ¥‹…’’ŒŒ{||{{tldd„Š}{{tred’…‹ztl”››”š”…‹‹š””tsltts{tt{u{ƒ}Štslu{{ƒ„„‹’Šlksƒ„„mttƒ}Š]cdtts‚ut{{ƒƒ„„|‚z”“›£››rfk‹‹‹’…‹œ››‚|u’ŒŒ“““¤¤™š¤„„Š‹’Š™š¤tt{‹„‹“““{u{„„ŠŒ”•lks‹…’Œ‹“£››”š”ƒ„„‹‹„Œ‹“’ŒŒ£œ¥ttstllulttts’…‹f]cz‚llri{u{‹„„œ››‹‹„‚uttts’ŒŒ|„…]cd‹‹‹{u{{{tllk””‹SKJ*)(|‚zd\\\UZ[[TJHFƒ„„ultddc|‚zsle‚ut‹’Š|‚z””‹“““‚v{ultlldzll|‚z“““kd\ƒ„„™š¤‹‹‹œ››Œ”•{{t‚v{ƒ}ƒ…„’kk]f]czll¦§¨ddcnƒult…‹’›¢›ult“Œ”£œ¥”š”tt{kd\{{ƒf]cult\[b{||\[[„Š„llk“““œ¤¦tt{dkV]bZ{u{|‚zslesleztl‘Œ…ekdlri{||[TT{zmsle‚wlƒ}ƒŠ}|”“›{||“Œ”‚wlƒ||dc\Š~‹‚wlŠŠ}ƒ‚nŠŠ}kk]›¢›tslƒ„„lri‰ƒv…‹’|‚ztsl‘ˆ}Šƒ}ztlcbV|‚zd\\‚utultŠ}ƒedk{{ttlltslb[Utlltllƒ||mtt{{tuztkk]lld{{tlks{{ƒ‹‹‹ƒ}Š…‹‹{{ƒ{{ƒtt{ƒ„„ƒ||Œ‹“™š¤™š¤„„ŠŒ”•‹‹‹‹‹‹¨©´™š¤Œ”•…‹’¨©´¨©´¦§¨›¢›…‹štll‹‹„™š¤£œ¥¦§¨£œ¥¦§¨Œ”•ƒ„„{{tš”””“›{{ƒ«²«mttƒƒ|¨©´{{ƒƒ}ƒ™š¤”š”ztl{u{‹„„£œ¥¦§¨›”›µ¶·£››Šƒ}‹„„„„Šttstsl{ttƒ||…„’ƒ„„|‚z‹„„{||Œ‹“ztlult„„Š‹‹‹nv‚{||lri‹„‹„„Š[[T{||{{ƒŒŒšf]c„Š„[[Tƒ„„{{t²¬µlritsl‹‹‹tt{”“›‚|uš””‹‹„“Œ”ƒ}Š›¢›””‹…‹‹™š¤„„Š”“›‹‹‹|‚z“““™š¤{{ƒ“Œ”ƒ||{||{||sle{u{{u{j]\j]\¨©´Œ‹“œ››‚v{{{t””‹‹„‹”“›¤¤Šƒ}’ŒŒ“Œ”tllƒƒ|uztuzt‹„‹„Š„{||””‹D;9*)(f]cVTLlriu{{sre{u{ztlVTLttsddc[TTuztlri‹’Štzl‹„‹£œ¥uzt””‹lriult|‚z{tt¦§¨“Œ”ƒ„„”š”{{t’ŒŒ”››{||d\\llklriƒƒ|tts‚v{{tt‹…’Œ”•‹‹„ƒ||›”›ultultŠƒ}„Š„uzt”“›JHF[[T‚utlritlldc\”“›tt{]bZkd\tsl{u{red‹„„slelddtslŠƒ}sle\[[{{t‹’ŠbVU{{tztfŒ‹“‘…„rfkldd‹‹„sreŠ~‹r]g{||ƒƒ|{u{lri›¢›ƒ„„|„…lek[TTb[Utsl[[Tsle‘…„dc\tllrg]|‚z‚|u{tt{u{kd\{zm[TTƒƒ|ƒƒ|‹„„’ŒŒztltt{uztƒ„„lri“Œ”ƒ„„ƒ}ƒtt{‹„‹}‡’“““…‹’Œ”•{{ƒ…„’|„…”“›|„…edkƒ„„Œ—£œ¤¦{{ƒ{{ƒ„„Š|„……‹’‹‹‹œ¤¦“““…‹’‹’Д𔦧¨¨©´ƒ}Š£œ¥·¶Ñœ¤¦Œ”•„„Š”››ƒ}ƒtzl„„Š{{ƒlks{u{Œ”•Š}ƒ¦§¨‹‹‹tts„Š„{u{llk‹„‹‚v{µ¶·¦§¨{u{tll{u{tllƒƒ|{ttultllkttsu{{‹’Ц§¨””‹¨©´|„…{u{lks†~‘edk›”›„Š„“““„„Š„„Šlks{{ƒlksb[Uyle’ŒŒ””‹“““››”ƒƒ|››”¦§¨“““{tt’ŒŒ‚ut„Š„Œ‹“ƒ|||‚z“““‹‹‹ª³·…‹‹ƒ„„tt{|„…”“›‹„‹™š¤tll‹„„tts{{ttsl‹„„‹’Š‹„„“““Œ”•œ››š…Žƒ‚u’ŒŒŠƒ}ƒ}ƒ|„…ƒƒ|’ŒŒ{tt’ŒŒƒ||ttsƒ„„{||{tttslfkk””‹MRK*)(leksre]bZ{tt„Š„lddkd\d\\UTSUMR{{tuztmttdc\{zm‚v‚tll“““ldd|„…SKJu{{|„…|„…‚|uª³·Œ”•ƒ‚u‹‹„™š¤‹„‹Œ‹“ƒ„„¦§¨kk]\[blksŒ”•edkldd…‹’bVU„„Š””‹{tt‹‹„{zm{{ƒ{u{{u{tllƒƒ|tzl””‹|„…””‹[[TbVUlri“Œ”£››FD;ttsredkd\b[Ud\\{zmVTL›¢›ƒƒ|[TTllkƒ||{||b[U{ttŠ}|sle’ŒŒƒ||kd\lldƒ‚n{{tlld‹‹„{||Œ‹“|„…“““ƒ}ƒlriƒƒ|‹„‹’ŒŒttsb[U‹’Šek]ztlrg]‹„„ƒ‚uztf[TTtts‹‹„‚v‚zllkd\Œ”•llkuztddc‚|u{tttt{tsl™š¤œ››“““™š¤™š¤…‹š|„…Œ”•ŒŒšttsfkkƒ}ƒ{u{{{ƒ›”›{{ƒ}‡’Œ”•|„…|„……‹’}‡’mtt|„…¨©´tts··Ä™š¤…‹’›¢›‹„„‹‹‹‹„‹“““œ››¨©´ttsrfk£œ¥£››‹„„“Œ”“Œ””𔋋„‹‹„{u{zll{||‹’Š‚wlœ¤¦|‚zƒ„„uztlkslri|‚zttsf]clekekd„Š„|‚zŒ”•™š¤|„…lkslriultlksdc\tsl|„…‹‹„Š}ƒUUY{{ƒƒ}Š›”›š””kd\””‹›”›œ››‹„‹‹„„¦§¨“Œ”sle””‹ult{{t{{ƒƒ||‹‹„””‹‹‹‹{u{{{ƒ™š¤„„Š{||Œ”•“Œ”f]crfkŠ}|lriztl‹„„‹„‹›¢›‹‹„tt{Š~‹ƒƒ|ddcŠŠ}””‹ƒ||{u{ttsŒ”•‹„‹”𔋄„ultddcƒ„„{ttultsre\[[ƒ||JHF*)(llklldkd\lldƒ‚u‹„‹ddcd\\UTS{u{ddcttszllddc{zmtll{||tts‚|u„Š„„Š„”š”œ¤¦‹’Šƒ}ƒlkssretsl’ŒŒlri“Œ”j]\j]\¤¤”š”{||lekƒ}ŠŠŠ}{||[[Tf]c“Œ”|‚zzllkd\ttstslƒ„„‹‹‹lri’ŒŒ>EC|‚zŒ”•{u{uztztlŠ}ƒ’ŒŒ{{t{{tsle‹„„bVZu{{ldd{{tlld|‚zlriVTL£œ¥VTLultkd\ƒ||j]\ƒ||]cd‚v{VTLdc\dc\ƒ„„tzl{ttuzt’ŒŒ…‹’‹„‹yle{{tllk‚utƒ||ŠŠ}llktsl‹‹‹tllztl“Œ”{{tek]sleƒƒ|‚utƒ}ƒldd‹„„‹’Šƒƒ|‹‹‹lldƒ}ƒ“““‹„‹{||“Œ”mtt{{ƒ{{ƒlks…‹’|„…tt{”“›{||„„Š{{ƒ™š¤Œ”•ŒŒš|„…}‡’}‡’|‚z…‹’Œ”•tts™š¤“““œ¤¦Œ”•”››lksnv‚mtt“““|‚z{{ƒ™š¤ƒ}ƒƒƒ|ƒ}ƒ‹‹‹mttztl’ŒŒult“Œ”Œ”•{u{ƒƒ|¨©´“““ƒ||{{t“Œ”ƒ||llkddcttsƒƒ|Œ”•’ŒŒ‚v{lks{u{{{tƒ„„Œ”•{u{{{ƒ…‹’ultlksUMR™š¤”››‹’Š|„…lri|‚z]bZUMRd\\b[U‹‹‹llk‹„„”š”|‚z{zm‹„„›”›ƒ}ƒldd’ŒŒŠ}|ƒ„„{tt£œ¥›¢›sre›”›“Œ”¦§¨‚v{Œ—£‹‹„“““ƒ||llkd\\{ttsreƒƒ|›”›œ››“““‹„„ƒ}ƒ{{ƒkd\lddƒ„„›¢›ƒ||›”›“Œ”‰|vŠƒ}œ››ƒƒ|ddc\[[d\\[TT\UZ[[Tƒ}ƒ¤¤74,74,lddVTLb[U‹‹„uztdc\ddc{u{u{{dc\d\\tsl]bZddcredlritllsleƒƒ|ekd™š¤ƒƒ|lekª³·”“›lek„„в²¬ultu{{b[U¦§¨tlllri‹‹„{{ƒtt{Œ”•‹‹„SKJUTS{u{{tt””‹’ŒŒtsllldtt{yl„ttsztltllƒƒ|kk]\[[ddc„Š}¦§¨ƒ}ŠultttsŠƒ}|‚zj]\‚|uztlu{{tllƒƒ|ttsƒ„„d\\fkk{tt“Œ”ult{||Œ‹“ƒ„„ƒƒ|“Œ”{zm|„…lksdc\Š}|Œ”•ztf{u{“Œ”“Œ”¦§¨tts‚utult[TTek]ƒ||ztl{ttkd\ztlƒ„„”š”››”{tt{zm‚|uultldduztŒ”•{{ƒƒƒ|{{t‹„‹uztllk‹‹‹…„’ultf]c|„…nv‚fkk{||Œ—£ŒŒš{{ƒ£œ¥“Œ”œ¤¦u{{Œ‹“Œ”•…‹‹|„…|„…|„…ƒ}Š”››tts„„Й𤋄‹ƒ||{{ƒŒ—£mtt””‹„Š„™š¤”››™š¤dc\{{ƒƒƒ|{tt¤¤“““„„е¶·ult¨©´œ››£œ¥zlltllllk”“›ttsu{{‹‹‹”“›”››ekd”“›ƒ}ƒtzlƒ}ƒlldtts…‹‹f]crfkŒ‹“\UZd\\\UZ‹…’|‚ztsl‹’Š‹„„uzt]cd|„…lks[[Tš””{u{‹„„„Š„¦§¨µ¶·”“›‹„„ƒƒ|uzt²²¬{tttts{||{tt‹‹„Šƒ}¦§¨Œ‹“”››‹„„Œ”•”››„„Š›”›{u{bVUƒƒ|”š”‰ƒv{||™š¤“““‚|u”“›ult¦§¨ŠŠ}„Š„|‚z…‹‹ult”“›{||ƒ}ƒkd\‚|uƒ„„|„…Œ”•lrif]c|„…tt{²««JHF3+*bVZllkj]\tll]cdlld]cdult{{tUTS“““[[TlriVTL‚|u„„Šlksd\\j]\ttsœ¤¦‹‹„›¢›™š¤lddldd”››‹‹‹ldd…‹‹‚ut””‹“Œ”››”d\\uztttsedk‘Œ…lekƒ„„“Œ”{u{ƒƒ|‚v{‹’Š|„…{{tslellkVZTlri|‚zz‚lddc™š¤ttstll|„…š””u{{‘Œ…sreb[U{ttŠ}ƒsled\\tts„Š„{ttldd\[b››”ldd{zmtt{„vŒ™š¤tzl‹„‹f]cdc\lri‚|ukk]{yfd\\llkf]c{{tŠƒ}‹’Štlltll{u{‹‹„…‹‹‘Œ…””‹‚utj]\zll|„…‹’Šsle{{t””‹›”›‚v{œ››{{ƒƒ„„‹„„tsl„Š„‹‹‹‹„„”š”{{ƒƒ„„“Œ”¨©´Œ”•Œ—£Œ‹“‹„‹”“›‹‹‹¨©´™š¤ª³·”“›ŒŒš|„…œ¤¦|„…Œ‹“|‚zŒ—£¦§¨…‹‹£œ¥™š¤ƒ||œ››„„Šlks™š¤››”„Š„œ§²{||redƒ}Š‹„‹ƒ„„‹‹‹{tt”››‹‹‹ultŒ‹“··Äƒƒ|ldd‹„„Œ‹“tt{sleuzt‹„‹ƒƒ|fkkƒ}ƒ…‹‹ƒ}ƒlld{||{{ƒ‹’Š…‹‹ƒ„„{u{MSSf]cUTS”“›f]cmtt{{ƒƒƒ|™š¤Œ”•‹‹‹u{{edkedktslƒ||ƒ}ƒ“Œ”””‹ŠŠ}‚wl“““›”›{||”𔋄„‹‹„„Š„ultƒ}ƒbVU[[Tƒ}ƒtts]bZŒ‹“ƒ„„Š}|{||“Œ”‚v{{tt¦§¨«²«‹’Štsl¨©´…‹‹“Œ”Œ”•Œ‹“{tt[[Ttsl‹‹‹„„ŠŠ}|sle‰ƒvƒ||ultuztŒ”•uztƒƒ|tllUUYddc\[[£››:97&&red{zmJHFVTLMRKƒ‚u\[[[TTVTLJHFVTLtslsle[TTllddc\””‹i\Vtsltts“““ƒ„„lriœ¤¦£››\[bddcƒ||ultœ››{ttƒ||“““ƒƒ|Š}ƒ™š¤{{ƒlksSKJedk{{ƒƒ}Šlld‹‹‹sleƒ„„]cd‹’ŠbVZUTSVTLdkVfkkFD;„Š„aWM]bZVTLSKJƒ||uzt‹„„lri’ŒŒldd’ŒŒ“Œ”lddƒ}ƒtts{ttddctllƒ||redf]cŠ}ƒzlld\\tzlƒ„„{ttuztdkVVTLŠŠ}JHFredf]cult{||tll“Œ”{u{’…‹lekƒ„„{tt{||‚|u‹„„tllƒ||ldd|‚zŠƒ}tts‚ut{ttf]c‚|u‹’Š››”{|||‚zŠƒ}ƒƒ||„…‚v{™š¤…„’‹…’…„’}‡’lks{u{ŒŒš™š¤™š¤|„…Œ‹“›²¦§¨…„’tt{œ¤¦}‡’ª³·…‹’‹„‹{||œ¤¦›²›²œ¤¦›¢›¨©´Œ”•Œ”•£››«²«…‹‹‹‹‹‹…š{{ƒ‚v{‹‹‹ult«²«œ¤¦™š¤“Œ”ƒƒ|¨©´£œ¥rfk”“›£œ¥„„Šƒ}Š„„Š…‹’‚|u{||{{ƒƒ}ƒ{tt{{ƒ››”£œ¥›¢›œ¤¦”››¨©´|„…|‚zd\\“““{{ƒ]bZƒ}ƒlldƒ}ƒœ¤¦ƒƒ|{{ƒJHFult”𔋋‹tt{…„’‹„‹””‹tzl{||{tt¦§¨”š”’…‹ƒƒ|„„ŠŒ”•“Œ”|„…lldldd|„…›”›ƒ||Œ”•|‚z„„Š‹„‹™š¤š””sreƒƒ|{yff]c‹’ŠŒ”•|„…ƒ}ƒ{{ƒ‹„„lriVTLek]ƒ}ƒ‹„‹llkcbVldd[[Ttlledk\[buztztl[TTUTSedk””‹:97&&\[[SKJVTLz‚lVZTek]FD;ultd\\|‚z‹‹‹lldsre’ŒŒsle…‹‹kd\jcV‹’Šƒƒ|llk‹’Šlld\[[„Š}uztƒ„„„Š„“Œ””𔋅’‹…’ª³·£››{tttsl{||›”›tllf]ctlllldŒ”•Œ‹“‚ut”š””››\[[ultSKJ{{ƒ{zm[[TVZTlddJHFu{{lddVTLtlllldd\\tsltsl‚v{‹’Šztllrillkttsj]\lriUTSb[UlddŠƒ}lddƒ}ƒultzllf]ckd\lritzluzt››”‚wllddttsƒƒ|‚utreddc\‚uttts{{ƒ“““Œ”•‹’Šƒ||Šƒ}‚wl{{t{{tddctlllriŠŠ}redddc{{tztltsluzt|„…‹„‹”š”u{{„Š„ƒ}ЄЄ’ŒŒ…„’{{ƒ{{ƒ‹…’™š¤u{{ŒŒš{{ƒ”››…‹’Œ—£{{ƒ{{ƒŒ”•…‹’“Œ”Œ”•¨©´™š¤…‹‹Œ”•™š¤£››‹‹‹™š¤edkœ¤¦›¢›¦§¨™š¤”››‹„„›”›”››œ›››¢›¦§¨‰‘~ŒŒš£œ¥µ¶·¨©´‹„„¦§¨¦§¨™š¤‹…’„Š„|„…ƒ||“Œ”tt{Œ‹“‘Œ…“Œ”Œ”•‹‹„‹…’”››lrimttŒ”•‹’Šekd{u{rfklks\[buzt’ŒŒ“Œ”u{{Œ”•…‹‹f]c[TT„Š}“Œ”ult”“›œ¤¦‹’Š‹’Š‘…„{|||‚ztts“Œ”ult‹’Š“Œ”ƒ}ƒ‹„‹|‚zb[Utts£œ¥‹„„{||{tt‹‹‹ƒ}ƒƒ}ƒ”“›‚|u|‚z„Š„Œ”•‹„‹«²«“Œ”ldd\[[‚|u]bZkk]sleŠ}ƒldd{||„Š„{{t{tt››”‹‹‹|„…|‚ztlllek{||JHF£››JHF3+*edkek]lldb[Udc\lld\UZVTLVTL[TTlddlld{{ttlllddƒƒ|Šƒ}yle¤¤‹‹‹{||{{t„„Š|„…{u{‹’Š”“›ƒ„„‹„‹›¢›”››{u{{{ƒšŒ›¢›fkkr]Z{{ƒs_q‹…’rfklek™š¤lld”››‹‹„uzt‚v{ƒ‚uldd‹’Šƒƒ|MRK]bZVZ[llklld‚utekd‹„„ddcztl]bZUMRztfdc\Šƒ}JHF\[[f]cƒƒ|Š}ƒ{||j]\tllkd\d\\…‹’ƒ||{ttttslks„„Šƒƒ|œ¤¦Šƒ}£œ¥Š}|lldllkultlddlld””‹{tt‚v{››”‹‹„“““rg]’…‹’ŒŒ{tt{ttlldf]c{{ttllllklddredƒƒ|{{t›¢›¤¤œ¤¦“““”š”””‹™š¤u{{…‹‹Œ”•…‹’„„Š…‹’™š¤œ¤¦Œ—£mtt™š¤‹…’”“›{{ƒlks›²œ§²œ§²œ¤¦”››£²{{ƒ{||lri‹‹„sre…‹’u{{…‹‹|„…|‚z|‚zŒ”•””‹‹…’ultœ¤¦“““ª³·”››ŒŒštts“Œ”™š¤„Š}„„Šƒ}ƒ‹„‹“Œ”Š}ƒu{{ztl{{t”“›ttsj]\š””uzt‚|ubVZmttŒ”•VZ[|‚z…‹‹tts{{ƒ‚|uf]c‹…’”“›””‹ŒŒštllekdUTSlks†~‘[[T{{tlks{{t¦§¨””‹¦§¨’ŒŒtllƒƒ|£››‘…„ldd„Š„tt{Œ”•‹‹‹£²‹„‹ƒ}ƒ›”›ult…‹‹“Œ”edk›”›tt{{{t‚|uƒƒ|„Š„|„…‹„„{||lldlksultb[Ulld{{t[[Trfkult’…‹ƒƒ|lld””‹”š”„Š„‹‹‹ekd‹‹„[TTtslddc²²¬FD;*)(ultddcSKJD;9JHFcbVf]cSKJ[TTldd\[[tslŒ”•[[Trfk„Š„Š}|lld{zm‹’Šuzt{{tlri„Š„ƒ„„’ŒŒŒ‹“„Š„{tt’ŒŒ\[[‹„„{{ƒf]c«²«„Š„…‹‹{||Š}ƒƒ„„‹‹‹ultŠ}ƒbVZ„„ŠbVU…‹’š””””‹{{t›¢›Ž¡›ult]bZultldd[[Tlddlld“““[TT‚|ub[Ulld‚|u{ttek]ddcddcVTLSKJFD;kk]ult{{tddcuztVTLtllbVZ{||[TTtslldd¦§¨lritllŠ}|ƒ„„{{tƒ||bVUttsredredzll‹‹‹{{t|‚z{{tztl|„…|‚z‚utœ¤¦kd\…‹‹ztl‹„‹edk|‚z…‹‹lld‹„„‹„‹‹„„”››Œ‹“uzt|„…{{ƒŒ”•}‡’¨©´œ¤¦™š¤›²œ¤¦™š¤ƒ}Š‹„‹„†™}|’{{ƒ{{ƒŒ—£œ¤¦|„……‹šf]ctt{ultŒ”•…‹’‹‹„‹’Š„„Š{||¨©´«²«‹’Š…‹‹mttŠ~‹…„’{{ƒŠƒ}””‹œ¤¦|„…Œ‹““Œ”‹„„Œ”•„Š}ƒ||„Š„…‹’{tt‹’Š{{ƒŒ‹“d\\{||f]c‚v{r]g{{ƒ‚wl{|||‚z]cd|‚z|‚z„Š„{{ƒ|‚z{||f]c™š¤tslƒƒ||„…lld‹‹„†~‘‹’Š£œ¥„Š„ƒ||{{ƒlld…‹‹‹„‹‹‹„ƒ||“““Šƒ}ƒ||Œ‹“tsl‹‹‹™š¤ldd„„Š’ŒŒrfk“Œ”ƒ}ƒldd…‹‹{u{|„…›”›ƒ„„tt{ƒ||«²«lriƒ}Š™š¤Œ”•{||{||Œ‹“d\\kd\tsl\UZlddultu{{uzt|‚z’…‹’…‹‹’Šƒ„„‹’ŠŠ}|f]cVZT\UZ¦§¨UMRlddVTLFD;FD;‹‹„[[T‚ut[TTfkkƒ}ƒ[TT[[T‹‹„lek[[Tƒ„„ztfVTLcbVdc\‹‹„tslfkk“““|‚zmttek]’…‹ƒ||tzl“““{{tttsœ››¤¤’…‹tt{ddc‹‹„ƒ}ƒš””’…‹‹„„Œ”•¦§¨VTL\UZ””‹”š”|„…‹‹‹”š”ª³·lriedkdc\|‚zztlttstllekd‹„„SKJ‹‹„ttskk]ƒƒ|uztlldSKJ‚|utsltlld\\f]ckjVƒƒ|SKJb[Uztluztulttsl‘Œ…‹’Š|‚zsle{tt‹‹‹‹‹„Š}ƒlks[[Tkd\red‹„„ƒƒ|kk]u{{‘Œ…lddllk{{ƒsledc\f]cƒ„„š””Š}ƒult”››‹’Štllztlƒ||llk{||{{ƒƒ„„ƒ}Šmtt™š¤}|’{{ƒŒŒš™š¤‹…’nv‚˜Ž£}‡’ult{{ƒ™š¤›²}|’{{ƒ}‡’Œ”•|„…Œ‹“Œ‹“™š¤|„…ŒŒš¦§¨”š”…‹‹Œ—£”š”|„…tzl|„…Œ”•|‚zultƒ||‹’Š””‹“Œ”„Š„¦§¨lks{tt…‹‹„Š„{||›”›Œ‹““Œ”o€w|„…{ttsle|„…‹’Š‹‹‹ult¦§¨‹’Šredekd…‹‹œ¤¦|‚z]cd|„…mtttslmttedkŒ‹“‹‹„uztcbV\[[››”œ§²|„…™š¤‹„„ƒ||f]cŠ}|œ››œ¤¦š””‚v{š””[TT{{ƒ””‹”››Œ”•tllŠƒ}{{ƒd\\ƒ}ƒŠƒ}{{t{||ddcddc…‹’“Œ”rfktsluztddcult¦§¨llk‹‹‹”š””“›‹‹‹dc\››”‚|uUMRƒ}ƒtsl{||tsld\\ttsddcu{{{u{{ttlekVZTddc²««D;9*)(dc\VTLFD;D;9ek]kk]bVUult{{tlksd\\lrilriVTLlks‚|uj]\cbVlldVZTuztMRKƒ„„u{{{ttŒ”•lriœ¤¦u{{ƒ‚u{tt“““‹‹‹mtt²²¬ttsƒƒ|mttf]c™š¤tsl‹„„ult„Š„Œ”•ŠŠ}”“›ƒƒ|ulttts]bZ„„Šƒ„„{ttultztl{{tztl]bZ“Œ”{zmlri\UZ„Š}{u{Š}|d\\uztƒ}Šƒƒ|Š}|sreœ››‘ˆ}f]c‚v‚{{tlddSKJ‹„„ddc‚v‚ek]VTL[TTdc\llkddc\[bƒ„„ƒ||”š”tsllldredUTSlldkd\ƒ„„redVTL{||[[TFD;llklddtsltsl{{ƒf]cfkktsl‹„‹ƒ||llkultlrifkk„„Šmtt|„…‹’Š|„…{{ƒ…„’Œ”•”“›œ§²¡¡mk…}|’Œ—£{{ƒlks{tt‹…š|„…¨©´Œ”•…‹‹”“›™š¤Œ—£¨©´‹„‹Œ”•‹„‹Œ‹“¦§¨|‚z‹‹‹lri|„…Œ‹“{u{}‡’’ŒŒ{{tƒƒ||‚z™š¤]cdlks…‹‹Šƒ}œ››{tt™š¤Œ‹“ŒŒš…‹‹lek››”…„’ª³·‹’Ф¤{{ƒ{u{ƒ„„›¢›mtt™š¤{||VTL|‚z]bZtsl„„Šult‹’Šdc\‹‹„”š”™š¤™š¤|„…‹…’”š”’ŒŒ‚v‚{{ƒult¦§¨‹’Šœ››{u{ƒ||tsllek¦§¨Šƒ}ƒ„„“Œ”{u{{ttƒ}ƒ„„Š{u{sle“Œ”‚v{f]c{{tƒ}ƒƒ„„ƒ||lriztledk{{ƒ|„…››”™š¤“““¦§¨sle‘Œ…{u{d\\{||‹‹„mtttslultdc\|‚z{{ƒkd\ldd\[[tt{\[[¦§¨SKJ&&j]\Šƒ}f]cVTLJHF]bZzlltll]bZllklld››”tzlsleuztultVTLtll]bZ[[Tu{{tzl”š”llk|‚z‹’Š|‚zŒ”•{{td\\²²¬{||Œ”•ekd‹’Šlld{{ƒf]cedkš””lldbVU“Œ”lddult[[Ttt{SKJ{ttlddu{{lriUTSdc\rfkƒƒ|tsl{{ttslzll|‚zƒ||{ttttslldddcMRKf]clkstsl‘Œ…ekdƒƒ|‘…„{{ƒldddc\{u{FD;Q?@ultƒ}Šdc\ƒƒ||‚z{{t†~‘„Š„mttlldultŠƒ}|‚z{zmf]cuztŠŠ}{||UTSylerfk{ttdc\sle{||VTLtzlbVUlddllkdc\lddƒ||ztfllklddƒ}ƒu{{mtttt{uzt…‹’nv‚ŒŒšedklkstt{¨©´œ¤¦Œ”•›²œ§²“Œ”¨©´lks}‡’}‡’|„…u{{¦§¨„„Š£œ¥™š¤™š¤£œ¥œ››|„…|„…œ››œ››œ¤¦›¢›{{ƒu{{ultyl„ttsµ¶·‹„‹Œ”•\[[lkstsl…‹‹llk‹‹‹lri…‹‹{{ƒ””‹{||›”›„Š„„„Š{{ƒ¦§¨“Œ”£œ¥„Š„ldd|‚zlksƒ}ƒmttlrirfk\UZd\\\[b‹’Š{{ƒ‹‹„››”tslmttlkslksƒ„„{tt{tt|„…¦§¨’ŒŒ’ŒŒœ¤¦Šƒ}Œ‹“””‹ƒ||™š¤£››””‹{||’…‹{{ƒultult{{ƒ|‚z‹„„œ››|‚z™š¤{{t{{ƒƒ||””‹|‚zƒ||{||œ››‹’Šœ¤¦‹’Šƒ}Š„„Š’ŒŒ{{tddc{tt{{ƒkd\lriƒƒ|lld{ttƒ„„ttsƒ„„ztlfkk]cdllk””‹bVU-1+ldd{{tF=CsletllSKJ{zmzllldd\UZslelldddcd\\ƒ„„‹„„r]ZŠƒ}„Š}|„…JHF{zmfkku{{‹’Š„Š}lriuztƒ}ƒƒƒ|“““”š”tt{kd\{||VZTlksllk“““‹’Š›¢›[TTƒƒ|uzt„Š„Šƒ}›”›lddtlllriUUYVZTVZTUTS‹‹„‹‹‹{{tslettskd\ƒ„„VTLkd\tsl‹’Š…‹‹[[T\UZ‹’Љ|vkd\ƒƒ|{{tsleƒ||SKJ””‹f]csre{tt{{ƒultƒƒ|rg]‹’Š„Š}lddtslbVUlri‹„„‚v{d\\UTSslekk]ƒ||”𔋋‹{{tŠ}|{ttttsek]{||ztlttslddjV[\[[\UZ{ttult‹‹‹ƒƒ|{{ƒ{||fkk“““£²„„Š…‹’{{ƒnv‚{||u{{{{ƒ„†™Œ—£œ¤¦}‡’Œ—£{{ƒ{{ƒyl„{{ƒ…‹’Œ”•™š¤™š¤ttsŠ~‹œ§²ŒŒšª³·™š¤£››‹’Štzl›¢›lldª³·ª³·lrimtt™š¤tll¦§¨ztlŒ‹“Œ”•ƒ}ƒ‹‹‹zllƒƒ|‹‹‹“Œ”™š¤{{ƒ””‹”“›‹‹‹bVZ|„…‹‹„‹„„{tt{{ƒ[[Ttll…‹’|‚zŒŒš„Š„[[Tƒ„„„„Š‹‹„ttsŒ”•|‚z]cduzt{{t{{ƒUMR|„…d\\{zmƒ}ƒ‹„„…‹‹ƒƒ|‹„„ƒ„„sleldd‹„„”“››”›””‹¦§¨ƒ}ƒ“Œ”¦§¨{u{{u{…‹‹Œ”•””‹ƒ}ƒ„Š„|‚z‹‹‹”“›‹„„ddc{||„Š„{{ƒult‹’Š’ŒŒ|‚z“““kd\“““››”„„Šš””redŠ}|tzl“““sle[[T|‚z]bZb[U[TT\[[UTSf]c¦§¨FD;*)(f]c‚|uSKJ]bZlddJHFddclldddc\[[“~ˆtzlekd{||ult“Œ”“Œ”tzlu{{Œ‹“llklldtt{ekd›¢›lkszlltt{uztƒ‚u‹’Š}|’””‹‹’ŠtsltllVTL{tt‹’Šztl…‹‹uztVTLlri‹‹„ƒƒ|‹‹‹‹„‹{tt]bZJHFb[U]cd]bZmtt{tt{zm‹‹‹[[Tlld{u{sreult{||]bZttslld[TTcbVVTLb[U””‹[TT{zmi\VbVZtllƒ}ƒsletlledkUMRek]kk]””‹VTLlddUTS“Œ”‹„‹‚utultkd\{||“Œ”cbV{tt|‚z‹‹‹””‹tllbVZuzttsl{||ƒƒ|lld‰ƒvtsllksbVZ{||ulttll{{ƒultmttfkk„Š„™š¤‹‹‹“““Œ—£{{ƒlksŽ¡›mtt‹…š…„’Œ”•…‹šŒ—£|„…„„Š…„’…‹š~’“ekdŒ”•ƒ}Š›”›ŒŒš…„’£››‹„‹™š¤›¢›“““›”›”š”ƒ||””‹ª³·ª³·‹‹‹{{ƒ‹’Š‹‹‹‘…„™š¤Œ”•{{ƒš””¦§¨“Œ”››”ldd‹‹‹£œ¥ŒŒš{{ƒ™š¤Šƒ}|‚zŒ”•ztlƒ„„{u{{||’…‹{{ƒŒ”•›”›‹’Š‚utf]c™š¤“Œ”ƒ„„lriUUYmttUTSdc\]cdtts{{ƒekdlek‹„‹lekŒ”•››”ttstzl‚wlŠ~‹›”›‹‹‹”“›lksœ§²|„…£œ¥{{ƒtsl{{ƒ™š¤‹‹„¦§¨Š~‹‹‹„u{{‹‹„ƒ}ƒƒ}ƒ‹‹‹ƒƒ|‚|u{||tt{fkk„Š„Š}|ultlri{{t‚|uƒ}ƒƒ„„ƒ}ƒƒƒ|ƒƒ|””‹‘Œ…ztlƒ„„tslVTL{ttultfkkUTS¦§¨MRK*)({tti\Vkd\FD;bVUPF=dc\UMRdc\sle„Š}tsl{u{ttstll›¢›jcV‚|utygƒ„„ƒƒ|u{{d\\mttekd„Š„ƒ}ƒŠƒ}|„…ƒ}Šuzt|„…|‚z””‹b[UddctllŠ}ƒŠŠ}\[[‹…’{zmj]\„Š„’ŒŒ‹„„[TT’ŒŒtlltts…‹‹Œ”•u{{lrillk›”›tllztld\\‚v{|„…ztlVTLttstzl{{ƒ{||„„Š[[Tb[U{{tŠŠ}\[[VTLJHFlddiq]d\\VTLlld]bZSKJJHFƒƒ|ƒƒ|ƒ||f]c„Š}ƒ}ƒddcd\\tll‚|u”“›“““lld£››‹’Š{u{’ŒŒŒ‹“ƒƒ|mtttsl{||Œ”•mttƒƒ|mwtts‹„‹[TTtll|‚z„Š„ƒƒ|ddcMSSlek™š¤Œ‹“lks|„…}‡’…„’|„…{{ƒ‹‹‹Œ”•Œ”•™š¤ƒ„„…‹’¨©´{{ƒŒ—£nv‚Œ”•…‹‹“““£²”››ŒŒš””‹{u{{{ƒ¦§¨ƒ}ƒ‹„„‹‹‹|‚zœ¤¦œ¤¦»ÂÇ‹„‹lks\[b›”›{tt„„ŠŒ”•Œ”•]bZ‹„‹‹„„””‹ult’ŒŒ„†™{{tœ¤¦””‹Œ”•„Š}tts„„Šultœ¤¦‹„„{||¦§¨”š”ª³·„„Šƒ„„£œ¥{{ƒ{{tŒ‹“JHF\[[LKRMRKVTL\[bJHFu{{u{{red£œ¥Š~‹|‚z“Œ”tts¦§¨›”›¨©´²««”“›””‹”“›Œ”•Œ”•‰v|ƒƒ|ª³·ttstt{…‹‹‹…’ultœ››“““ƒ}ƒ“““™š¤ƒ||ekd…‹‹ddcedk‹„‹ldd{zmmttultdc\ƒƒ|llk‹„‹‹„‹‹„„{{ƒ››”‹„„sle‹’Šdc\ƒ„„{tt]bZ]bZVZT£››b[U*)(f]ckk]Š}|FD;UMR{tt[[TVTLSKJVTLj]\VTL{u{ƒ||tlllldkk]ztl‹‹„‹‹‹”š”tslmtt\UZ„Š„Œ”•{u{‹‹‹™š¤{{ƒ«²«›¢›{||‹‹„{{tƒ„„‚utekdbVZUMR™š¤‹‹„{u{{||‚|u‹‹„lek‘Œ…””‹{{ƒuzt{{tekdJHFUMRldd|‚z‰|vf]c‹‹„{||ztl{ttVZ[‰‘~”››{{ttll{tt[[Tkd\ƒ}ƒFD;VZTd\\lddb[UtlllldlddJHFultekdƒ‚u””‹ƒ„„dc\tslƒ||dc\“Œ”¦§¨{{tkk]{ttƒƒ|‘Œ…››”ultredtt{|‚ztsl‹‹„Œ‹“š””{{tzllLKRmttƒ}ƒbVU{{ƒlri“““uztmtt{{ƒtt{}|’{||Œ”•{{ƒ|„……‹šŒ—£™š¤{{ƒ|„……‹’œ§²·¶Ñ¨©´”“›{{ƒœ¤¦œ¤¦|„…}‡’“““¦§¨œ¤¦Œ‹“¦§¨‹‹‹¨©´£›››¢›Œ”•™š¤””‹‹‹‹|‚zfkkf]clksŒ—£zll‹„‹‚v‚¬¶Ãš””lldredƒƒ|ƒ||„„Šœ››Œ‹“Œ”•Œ”•œ››Œ”•¦§¨lld|„…{tt”››‹’Š{u{„„ЄЄ{||uzt|‚z{tttt{JHF„„І~‘ƒ}ŠŒ”•…‹’zlluztlriVZTlrillkŠ}|llk„„Š{u{›”›‚|uztlƒ}ƒultƒƒ|™š¤¦§¨¦§¨‘Œ…”››™š¤”“›ƒ}Šf]clldƒ}ƒ{{ƒ‹„„‹‹‹„Š„ldd|„…llktts…‹’ekd£œ¥‚v‚tll‹„„ƒ||{ttleksletll‹„„‹„„ƒ||JHF{||zllkd\JHFUTSlek‚utfkk\[[ddc‘ˆ}JHFSKJbVZkk]b[UPF=3+*FD;[TTD;9JHFlddtsldc\{ttdc\‚ut{u{{||ƒƒ|¤¤ƒƒ|ttslddddcult[TT|„…™š¤“Œ”¬¶Ã¨©´œ¤¦Œ”•‰‘~iq]„Š„tllb[UddcUUYf]c{tt|‚zddc{u{dc\‚v{tslultƒ„„rg]Œ”•|‚zekd[TTlks‘…„{||lek”“›ƒ||b[Uš””›”›[[TŒ”•UTS{ttrfksresle”››j]\ttsUUYuzttllVTLleksre‚ut‚wl\[bƒƒ|“““ddcultlld‹‹„ƒ||\[[{{ƒ£œ¥””‹‹‹„‹„‹{{tš””{{tlksredultœ››Œ”•£››{||tllmttrg]ttstt{{u{ult{u{””‹…‹‹{{ƒ…‹‹…‹‹Œ—£Œ”•u{{{{ƒŒ”•Œ—£Œ‹“…‹šŒŒšŒ”•…‹šŒ”•™š¤Œ—£»ÂÇ”››™š¤œ¤¦…‹‹Œ”•‹„‹™š¤¦§¨š””™š¤¦§¨™š¤›¢››”›‹„‹tzlŒ”•”›››¢›Œ”•u{{yl„MSSuzt{{t”“›“““Œ”•„Š„ƒ}ƒƒ}ƒ‹’Š„Š}”“›™š¤tts™š¤”“››¢›|„…‹„‹|‚z\[b›”›u{{{{t“Œ”Œ—£|„…[TT„„Šmtt\[[{{ƒUTSultŒ”•“Œ”™š¤|‚zlddllk{{ƒŒ”•llk‚|u‚v{Œ”•ttstt{ultztl‚v{“Œ”ƒ„„›”›”››ª³·¦§¨‹…’›¢›ƒ„„|„…\UZƒ}Šrfk’ŒŒ‹„„ldd’ŒŒŒ”•„Š„‹„‹ƒ||”››llkmttƒ}ƒ„„Šmttu{{ultttsŒŒš‰|v{{ƒ‹„‹zllSKJd\\lriu{{ek]„Š„|‚zsleztl[TTVZTllk¦§¨:97*)(u{{SKJJHFSKJ3+*SKJD;9F=Cf]crfkVTLƒƒ|{tt‹„‹“~ˆddcsrejcVlldlld”››edk[TTƒ„„mttƒ„„‹u…‹„‹lriƒ„„ek]lri”𔫲«ƒƒ|ƒ„„ztl‹„„{ttƒ}ƒƒƒ|u{{[TTd\\VTL{{tult››”‹„„Œ‹“u{{u{{ttsfkkUMRb[Ulld{tt\UZŠŠ}VTL’ŒŒ‚v{„Š„‹‹„ultƒ||redlks”𔋒Ši\V[[T‹’Štyg‹’Šlddult‚|uƒ‚uƒ„„f]c|‚ztlltslVZ[„Š„tzl[[T{u{ult‹„‹“““‚|u¦§¨ƒƒ|tts””‹£œ¥£œ¥”››””‹”››{{t{u{VTLlri“Œ”{u{“Œ”…‹‹›”›ddc’ŒŒultkd\u{{Œ”•™š¤ŒŒš‹‹‹…‹š…‹šmtt{{ƒ|„…„„Š|„…ŒŒš{{ƒŒ”•™š¤œ§²…‹‹‹‹‹|„…¨©´™š¤™š¤Œ‹“{{tŠ}ƒ†~‘“Œ”‹‹‹|„…’ŒŒª³·š””œ¤¦œ¤¦‹‹‹‹’Š”››\[[tt{{||ƒ}Šƒƒ|Œ”•‹’ŠŒ”•Œ”•œ››™š¤‹‹‹‹„‹ddcƒ}Š›¢›}‡’™š¤Œ”•ƒ}ƒ„Š„‹’Š„„ŠUTSVTLb[UŒ”•lriuzttt{lri[TTultultult{{ƒ™š¤Œ”•tlllrilks|‚zlks“Œ”‚utf]c{{ƒultŠŠ}tts{||{ttŠ~‹ƒ||‚v{£››tzllkssreUTSddcnƒVZ[lksŒ‹“ƒ||lddƒ„„ƒ||ƒƒ|uztƒ„„›”›{{ƒ{u{Œ”•ƒ„„…„’”››ƒ„„ƒ}ƒ{||œ››‹’Š‹‹„‹‹‹sle[TT\[b]bZsletslVTLekdztl‹u…[TTu{{llk²««UMR*)(\[[rg]bVUVTLVTLkd\ttsƒƒ|rfkŠ~‹ƒ„„tzlƒƒ|ƒ||[TTtt{‹‹‹kd\VTL{{ƒ„Š„tsl‚|uƒ„„f]c[[T{{ƒ”“›ttsmttek]{{tuztlriVTLlek‹„„ttssle‹„‹„„Šttsuztkk]r]Z“Œ”¦§¨Š}|kd\f]cJHFddcfkkf]cUMR{u{lldult[TT””‹[TTrfk{{td\\‹‹‹ƒƒ|™‹†ult¨©´”š”lks‚|u“““|„…tlllldkd\{u{|‚z‚ut‹‹„‹…štslb[Uddctsluzt”š”‚|uƒ}Š‚v‚{{ƒš””tllœ››‹„„””‹tts“Œ”’ŒŒª³·››”{||‹„„tts‚ut‹’Šzllƒ}Š{{ƒldd{u{‹„‹‹‹‹ƒ}Šllk‚|u|„…Œ—£œ¤¦Œ”•™š¤}‡’{{ƒ{{ƒ}‡’|„…mtt…„’Œ”•}‡’™š¤ƒ„„”“›„„Š|„…Œ”•Œ”•Œ”•™š¤ddcŒ”•ttsŒ‹“ult¦§¨œ››‹…’‹‹‹|‚z””‹ƒƒ|”“›Œ”•£œ¥™š¤lkslks”››Œ”•‹’ŠŒ”•{{ƒ‹‹‹‹u…uzttll‹‹‹…„’Œ”•mtt\[b„„Šmttmtttt{ultlks‹’Š[TTuztVTLddcƒ„„fkk{tt†~‘™š¤„„Šlddyl„{{ƒttslri{{ƒ‹‹‹|„…œ¤¦ztlš””ult|‚zŠ}|£œ¥”š”{{t{u{{u{‹‹„Œ”•tts{||lriƒ„„tt{ddcu{{\UZ‹„‹tsl{ttŠŠ}ultƒ}ƒ¨©´ƒ}ƒ{ttŒ”•{{ƒtt{…‹‹llk{||ddcf]crfkƒ||’ŒŒ››”Š}|tslbVUf]c‚|u\UZ{zmƒƒ|tts[[Ttsld\\|„…{||¤¤MRK:97{ttdc\D;9SKJVTLVTLf]c\UZbVZ‚v{uzt{||slekd\ekdlkstzlŠƒ}uztlrifkkƒ„„ƒ||ttsƒ||\[[ekdtll\[[\[[mtt‰ƒv{ttVTLdc\rfklddtll‹„„{u{|„…ttsƒƒ|UTS{{t‚v{¤¤tllbVUVTL\[bttsult\[bllkŠ}ƒ{{ttllddc“““ƒƒ|UTS|‚zVTL|‚zultrfkult¦§¨„Š}¦§¨i\VŒ”•|„…{{ttt{‚utlriztllriu{{lddœ¤¦lj|„…‹„‹„Š„{||{ttƒ„„‹„‹{u{‹‹‹Šƒ}„Š}lddŠƒ}{{t‹…’ƒ}ƒƒ„„‚|uttskd\tts‹„‹Œ”•‹‹‹ƒ}ƒtts|‚z‹‹‹lks…‹‹{{ƒ|‚zƒƒ|edklri|„…„Š„…‹’|„……„’ŒŒš}‡’ŒŒš|„…Œ—£|„…”››œ¤¦”“›¬¶Ã¦§¨…‹š¦§¨œ§²œ§²›”›µ¶·¦§¨Œ”•œ¤¦“Œ”™š¤ƒ}Š£œ¥’ŒŒ›¢›”š”œ››“““lri“““ultttsd\\{||„„Š‹’Šœ¤¦¤¤f]c’ŒŒ|„…tt{¨©´ƒ}ƒœ¤¦Œ”•u{{Œ”•…‹’œ¤¦lks|„…mttlld[TTekd|„…”››ƒ||{{ƒ“““‹’Š“““{{tekd£›››”›„„Š‹‹„…‹šek]ddckd\ult›”›{u{ttsldd›”›¦§¨ƒƒ|“Œ”tlllek|‚zuzt|„…sre‹„‹{u{[TTtslultult{{tƒ|||‚z’ŒŒ“Œ”Œ”•ƒ}ƒ‹‹‹tt{lksmtt{{ƒ{{ƒ„„Šllk{{ƒtts‹‹„œ››””‹tsl{{tŠ}ƒrfkVTLtllVTL]bZ{||ƒ||tllf]c[[Tddcƒ„„MSS*)(tslb[U[[TaWMJHFSKJuztVTL[TTultddcdc\{zmlld„„ŠŒ”•cbVUTScbVŠ}|\UZ{ttultš””œ¤¦„Š}u{{tll|„…tts„Š„ztl{{tdc\tt{{tt{{tekd““““Œ”Œ‹“\[[srekd\ƒƒ|‰|v’ŒŒšŒ{u{r]g|‚zddc„„Šlks‹„‹‹„„lldyl„d\\tts„Š„tlltll[[T[[TŠ}|{ttlri|‚zVTLrfk‘Œ…tllŒ‹“sreldd{ttUTSkd\…‹‹UTS]bZ›¢›’ŒŒu{{‹„‹uzttlllld{{ƒsle\[[ƒƒ|„Š„‹’Šuzt””‹”𔋋‹f]c|„…ttsddclekœ››”››|„…‹„„{u{ttsttskd\edklldŒ‹“‹‹‹{||{{ƒ\[b|„……‹‹…‹’{{ƒtt{Œ—£Œ”•œ¤¦›²{{ƒŒ”•{{ƒŒ—£Œ—£™š¤lksœ§²…‹‹£œ¥›¢›Œ”•œ››ƒ„„Œ”•„Š„”“›Œ”•œ››ƒ}ƒ…‹‹Œ”•…‹‹¦§¨œ››™š¤“Œ”\UZ]cdldd|‚zŒ‹“ƒƒ|”š”tt{‹…’¦§¨ƒ||™š¤‹’Š›²¦§¨lriedk\UZ‹‹‹ttsttsmtt]bZlriƒƒ|u{{\[[›”›“Œ”|‚zkd\lddƒ‚u”š”ƒ||SKJtt{Œ”•u{{‹„‹“Œ”ult“““£œ¥ulttt{Œ”•ƒƒ|‹„„“““¦§¨¦§¨¤¤š””{|||„…ult]bZƒ}ƒUUY]cdldd{{ƒœ››{{t|‚z‹‹‹””‹‹…’”››„„Šlek…‹‹{{ƒ|„…lks|‚zuztulttt{ttsƒ}ƒ‚utƒ||dc\‚|urfk‚v{{||{tt|‚z]bZUTSsle[TTllkUTStt{£››LKRD;9lldkd\[TTVTLPF=VTLVTLf]cultf]cddc{{tdc\{u{kd\‹’Šlrilldtslkd\VZTred“Œ”{u{«²«uztu{{ƒƒ|lddŒ”•ldd{tt…‹‹]bZMSSlddkd\‹‹„ƒƒ|{u{…‹’lks|‚zdc\Šƒ}lddŠƒ}‹„‹Šƒ}lriUUY|‚z{{ƒ:97lksult|‚zultƒ„„››”{{td\\mtt{{tllk“Œ”rfk[[Tdc\Š}|‹„„Š}|‹‹‹{||ƒ„„‹‹„ƒ‚u{{tsle|„…|„…lek›¢›”š”””‹œ¤¦¦§¨ƒ||Œ”•ƒ}ƒtll{{t|‚z‚|u‹‹‹{{tlld|‚zuztlddŒ‹“„Š}‹‹„‹„„¨©´’ŒŒŒ”•‹‹„lks|„…]bZUTS{u{{||ttsƒ„„{||mtt\[b|„……‹’…‹‹|„……‹’Œ—£Œ—£™š¤¬¶Ã™š¤|„…~’“„†™|„…{u{{{ƒŒ—£”››¨©´|„…™š¤Œ”•™š¤¨©´|„…™š¤u{{‹…’’ŒŒekd|„…œ¤¦‹‹‹tllmttd\\lksŒ”•‹‹„£²rfk„Š„Œ”•ƒ„„‹„„“Œ”ƒ„„œ¤¦ƒ}ƒ…‹‹Œ”•{{ƒrfku{{llkekdldd‹‹‹¦§¨””‹ztltt{ekd„„Š{{tŠ}|tll|‚z|‚zmttrfkƒƒ||„…fkk{||ddcultult‹‹‹™š¤rfk™š¤{{ƒŠ}ƒƒ„„”š”””‹“Œ”„Š„Œ”•œ››‹’ŠŒ‹“ƒ„„”“›{{ƒƒ}Š[[T…‹’‹„„{u{ƒ‚u{||””‹edktzlult{tt|„…{{ƒtts{{ƒu{{|„…‹’Š“Œ”lldŠ}|{{tddc‚|uJHFJHFlddttsult‹‹„{{tlritsl[TTllkdc\ddc””‹FD;:97UTS]bZd\\VTLSKJrg]lriyle{{tekdlrilldkk]]bZ‹„„edktsl””‹uzt{||edkŠ}ƒ{u{ƒƒ|{tttslŒ”•ƒƒ|lld…‹‹‹‹‹{ttƒƒ|mtt{{t{||[[T››”tts‹‹‹\[[Œ”•|‚z£››‹’Š“““š”””››{{ƒœ››\[[”“›ekdUTSf]cUTS”š”|„…‚v‚[[Tlks{ttlks[[Tƒ}ŠSKJr]gSKJUMRkd\ŠŠ}b[Uultekdllk”š”aWMŠƒ}ƒ||›¢›…‹‹{{ƒŠƒ}¨©´œ¤¦¦§¨‹’Šœ››“Œ”{u{zll‹„„uztƒ}ƒ|‚zldd‹‹„tsl“““lddlekƒ||‹‹‹{ttuztƒ||uztƒ„„llktt{|‚z{{ƒ”“›ƒ„„…‹’{{t‹„‹mtt|„…œ§²”››œ§²Œ”•lks|„…œ§²™š¤··Äª³·…„’{{ƒŒ”•…‹’{{ƒ{{ƒ‰Š¡tts“Œ”{{ƒŠ~‹…‹’¦§¨Œ”•··Ä‹‹„\[[”“›tllf]cekd|„…››”|„…™š¤‹…’ƒ}Šu{{tt{{u{{{ƒtts{u{lritts“Œ”tt{mtt{{ƒmtt‹‹„™š¤lekrfk“““u{{\[[ƒƒ|ŒŒšztl‹’Šdc\lldkd\ƒƒ|lldu{{‹‹„d\\ƒ||“Œ”ult{{ƒŒ”•tllF=CŠ}ƒ‹…’’…‹‘}zŠ~‹ƒ}ƒ{tt‹‹‹‘Œ…ƒƒ|Šƒ}œ››„Š„{{ƒllk|‚zŒ‹“uzt{u{‹„‹œ¤¦‹‹„|„……‹‹‹„‹mtt…‹‹|„…”“›”››ƒ}Šllk{{ƒŒ‹“œ¤¦”››™š¤…‹’…‹‹ƒƒ|”››’ŒŒ“““rg]VTLFD;[TTUTSekdlddztlllkllkdc\[[TUMRztlUTS””‹:97:97sreb[UlddSKJsreD;9lddSKJldd{||lld‹‹„srezllf]cŒ”•sle‚utƒ‚uultlld{tt‹„„””‹ƒ||]bZlriƒ||tsl|„…Œ”•’ŒŒ‚ut‹’Š[[T[[T[[Ttsltsl™š¤Œ”•‹’Šœ››{{tlddƒ}ƒttsttsŠ~‹uzt|„…‹‹„MSS\[[[TT‹„‹]bZ[TTi\Vƒƒ|{u{{{tƒ„„ƒ||{ttsrej]\leklddcbV‹’Šrg]{{t{tttllƒ„„tyg‚|uttslldƒ„„mttdc\UTS‹‹‹›¢›²²¬‘Œ…£œ¥œ¤¦‹„‹‹’Š‹’Š””‹“““f]c‚ut|‚zƒ„„{tt‚|u„„Š“““{||{||ddcƒ„„ultedk{{ƒ|‚zlksŒŒš‹‹‹œ››|„…}‡’œ¤¦|„…™š¤|„…|„…Œ”•…„’œ§²^fs…„’·¶Ñ…‹’Œ‹“œ§²”“›„Š„ƒ„„{{ƒ{{ƒŒ”•”››{{ƒŒ”•›¢›™š¤£››¨©´ƒƒ|ultŠ}ƒ“Œ”™š¤tsllks…‹’”š”‹’ŠŒŒš„„Šu{{mttmttlksŒ”•Œ‹“ddc{||ƒ}ƒmttlks…‹’™š¤Œ”•‹‹‹lrimttŠ}|lritsl‹‹„lriƒƒ|‹„‹”“›Œ”•{{t›”›“““ƒ„„ƒ„„sre¦§¨{{tred„Š„lld]bZ\[bUMR{{ƒ{{ƒred‚v{“Œ”™š¤Šƒ}{u{‘Œ…ƒ||‹„‹uzt‹‹‹™š¤tsl|„…]bZŒ‹“ƒ||…‹‹tll¨©´‹’Š™š¤tt{‹’Šmtt‚v{uztƒ„„ƒ}ƒ›¢›lksƒ„„mttuztekd…‹‹llk‹‹„tlltzlek][[Tlldsletts„Š„‚v{ƒƒ|ddcekdtslztlultdc\,55ƒ||FD;74,{{tlrif]c{zmlriFD;\[[VTL{||‹„‹|‚zsle|‚zttsjV[tslrg]tslslej]\sleƒ||lekllk{{ttzl“““llddc\|„…{||“““ek]”››b[U{ttlri‰ƒvlri\[[¦§¨Œ”•ekd…‹‹uzt‚|u‹‹„tt{{{ƒƒ„„lri|„…kd\UTS\UZdc\[TTlldbVU{{t\[[„„ŠlldVZTultyle‹„„ƒ}ƒ„„ŠcbVkk]lri{zm‹„„zll[TTsreztlf]c]bZ|„…UTSlri„Š„]bZ‹„„‹‹„ztl{||«²«“Œ”““““““‹’Štslƒ||‹‹„d\\‹‹‹{ttmtt{u{””‹’…‹tt{‹‹‹œ››‹„‹ƒ}Š]cdtts{{ƒlksƒ||ƒ}ƒ{tt™š¤‰Š¡…‹‹Œ”•}‡’|„…}‡’Œ—£{{ƒ|„…Œ”•}‡’¨©´™š¤Œ—£›²‹‹‹‹„‹ƒ}Š…‹š­À¶œ¤¦™š¤Œ‹“™š¤µ¶·{{ƒ›”›|‚zŒŒš“Œ”ult”š”mtttts“““uzt„Š„}‡’edk|‚zmttUTS\[b]bZŒ”•dc\tsl{{ƒnv‚]cdŒ—£“““…‹’‹„„d\\\[[|‚z“““‹‹„„„Š{u{tllj]\”“›|„…£››ldddc\|„…mtt|‚zƒ}ƒ‚v{£œ¥lks™š¤Š}ƒ‚v‚{{ƒ‚wltt{‹‹‹yl„“Œ”‚v{ŠŠ}‚utŠƒ}ƒ„„œ¤¦‹’ЄЄ™š¤Œ”•™š¤””‹llktll…„’ulttt{‹‹„…‹’“~ˆtzlŠƒ}™š¤„Š„|„…ƒ}Šnv‚œ§²„Š„“Œ”ddcmttlksd\\lrilddd\\ekd{tt{{t‹„„ddc{||Š}ƒ{tttzltts{zmj]\\UZUTSUTS””‹JHF74,lridkVSKJVTLJHFbVZVTLbVUtllŒ‹“u{{d\\srelksztlƒ„„kk]tslztlddclri{ttƒ||””‹‹‹‹”š”Œ‹“ztlfkk{||tzlƒ}ƒ]bZmtt{u{llk|‚z‹’ŠFD;MSSlriœ››lri]bZ{{ƒtll‹„‹”››lkslddllkƒ„„ddctll\[bultuzt\[bƒ}ƒtslŠƒ}‹’Šlks]bZ„„ŠUMRƒ„„ƒ||ƒ„„b[Uƒ„„ult£››rg]LKR{ttkk]UTSlddVTL[TTUMR‹„‹lriœ››œ››ƒ‚u{u{”“›lld‹„‹Œ”•„Š„‹’Š‘Œ…{||{tt‹„„ª³·š””™š¤ƒƒ|‘Œ…‹„„kd\tzl…‹‹ƒ„„…„’\[bek]tt{“Œ”Œ‹“{{ƒu{{™š¤|„…ŒŒšmttŒ—£…‹’¬¶Ã™š¤Œ—£Œ—£Œ”•…‹‹™š¤ƒ}ŠŒ—£”“›ª³·”››ƒ}ƒ™š¤™š¤™š¤Œ‹“Œ‹“ª³·“Œ”“Œ”{{ƒ|‚z£œ¥‹…’ulttt{tt{Œ”•ƒ„„‹„„UTSultlksu{{}‡’|„…lksekd]bZ]bZtslƒ}ƒ””‹|„…mk…Œ”•”“›”“›\[b\[[kk]|‚zultztl‘…„tlllri|‚zddcultttsek]]cdMRK‹‹‹ƒ}ŠUMR‚v{œ¤¦Œ”•‹‹‹Š~‹{{ƒ‹„‹ult””‹£²‚v{llk‹„„£œ¥š””œ››„„Ц§¨‹‹‹¦§¨Œ”•Œ”•Œ”•|‚zmttmttf]c|„…ek]\[bultllktts£œ¥‹‹‹|„…{{ƒ…‹‹}‡’ƒ„„Œ”•{{ƒlksVZTJHF{ttultUTSu{{tlllld{{tedkŒ‹“ƒ||sletsl{||kk]SKJSKJaWM|„…š””ekd*)(kd\kk]bVUVTL:97D;9\UZbVU‹„„llk]bZtsl„Š}f]ckd\mttcbV‹„‹ldd\[[‹’Šztlztllldmtt’ŒŒŒ”•‹‹„cbVƒƒ|dc\„„Šb[Ulld‹‹„‹„„|„…]bZ]cdekdJHFu{{MRKVZ[llkkd\edk{||{{ƒŒ”•|„…„Š„lddldd{{ƒlks|‚zllk‘Œ…tslztl‚utUMRjcVƒ„„j]\lddbVZ{|||‚z‹‹„‹‹‹››”‚|uf]crfkrg]\[[ldddc\{||mtt”“›|‚z{{t‹„„[TT\[[\[btslttsƒƒ|ƒ||{||”š”lekƒƒ|‹„„™š¤red¦§¨‹„„lld£››mttu{{uzt{u{{{ƒlkstslƒ}Š{{ƒ”››u{{{{ƒfkkmttu{{|„…mttmtt}‡’†~‘œ§²Œ—£›²{||“Œ”†~‘†~‘‹’Š”››µ¶·{u{|„…nv‚{u{|„…“““{|||„…¨©´š””u{{²¬µ£œ¥›”›|„…Œ”•ttsult{u{mtt}|’mttfkkŒ”•|„…mtt|‚z|„…Œ”•“““ult”››œ¤¦mtt…‹‹„„ŠŒŒšleklldllk{||VTLŠƒ}UTS[TTlldVTL{||‚utJHFtllJHFtslkd\¦§¨lks¦§¨›¢›tslƒ‚uƒ}ŠJHFleksleŒ”•™š¤ƒ}ŠŒŒš“Œ”’…‹‹„‹‘Œ…“““”𔋄‹Œ”•¨©´ttsuztŒ”•lri\[blksu{{tsl\[bƒ}ƒf]cƒ||Š~‹tt{{||˜Ž£|„…”“›tts{tt{||mtt|„…uztlldf]clri‹’Šlld{{tztl]cd\[[redVTL[[T|‚zrg]FD;[[Tdc\SKJ””‹:97*)(UTSVTLaWMVTLSKJJHFf]ckk]‹„‹‹„‹llkSKJlrikd\zllrfkd\\lrilriVTLƒ}Šyle‚|ubVUmtt{zmŒ”•{{tkd\tts{{t{ttƒƒ||‚zƒ||ldd‹’Š‹‹‹„Š„lrilksekdmtttzlultƒ||{{ƒlri‹„‹mtt›”›…‹’ƒ„„‹‹‹ƒ}ƒtt{|‚z„Š„redrg]››”lrifkk{{t„„Šlddsle‚|utsllriŒ”•Š}|ƒ„„Š}|D;9ƒ||…‹‹lldulttt{[[TŒ‹“lddttslrid\\b[UJHFd\\lldtt{ƒ„„“““ƒ„„ƒ„„”››{tt”“›uztkd\{{ƒf]ctsl”“›{{t{u{{ttult{{ƒmttƒ||{{ƒtt{]bZ]cd{{ƒmttmttŒ”•mtt{{ƒnv‚…‹’…„’œ§²™š¤™š¤™š¤mtt{{ƒŒ—£|„…”››¨©´lksƒ„„{{ƒ”“›“Œ”¨©´„„Š”“›œ¤¦ƒ}ƒlrif]c‹„‹{u{[TT¨©´edklekuzt…‹‹lks]bZlrimttmttmtt~’“‹’ŠŒ”•Œ‹“u{{„„Šmtt„„ŠŒŒš{{ƒ{u{„„Šƒƒ||‚z‹’Štllkk]lddb[Uƒ||”š”{{tultlekdc\MRKllkrfkf]c’ŒŒ‹’Š“““‹‹‹œ››’ŒŒf]cUMRtll{{ƒ”“›™š¤¦§¨„Š„ƒ||‹„„Œ”•‹„„‹‹„‘…„¨©´”“›ultuztŒ”•ƒ||””‹ƒ}ƒmtt‹’ŠlksVTL\[[u{{tslultttsult{{ƒ{{ƒedkƒ}ƒmttVZ[„„Štts‹‹‹™š¤{{ƒuzt\[[tlltsl\[btts[TTztlVZTkd\VTLb[UyleUTS[TTµ¶·JHF>ECSKJVTLJHF74,[TTrfkŠƒ}b[Uƒ}ƒf]cllklld{||UMR\[[VZTi\V]bZlriekdVTL””‹|‚ztll|‚z‹’Šfkk‹‹„tzl‹‹„‹’Ц§¨””‹fkk[[Trg]ekd{{ƒ™š¤tll…‹’‹’Ц§¨ƒ„„ƒ||{u{g\rUTSedkkd\u{{Œ”•Œ”•‹‹„mttŒ‹“‹’ŠmttSKJult|‚z{u{£››ddcd\\{u{lddsleldd|‚z]cdred|„…cbVd\\f]c”“›Œ”•š””„Š„|‚zmttd\\\[[ƒ„„‚utttsu{{uztuzt“Œ”‹‹„‹’Ц§¨”š”Œ”•””‹Œ‹“ƒ„„Œ‹“ttsult|‚z{{t„„Šƒ||ƒƒ|lriƒ}ƒmtt|‚z“Œ”lkskd\{{ƒ‹„‹¨©´Œ”•Œ—£¬¶Ã…‹’|„…{{ƒœ§²Œ—£lks…„’„Š„™š¤¦§¨Œ”•|„…™š¤”“›ƒ}Š‹…’{{ƒœ§²™š¤”“›‹’Š{{ƒuztš””“““™š¤”“›£››tsl|„…Œ‹“llktt{„„Š|‚z[[Tmttu{{|„…Œ—£|„…Œ”•|„…‹‹„”“›…‹’Œ”•u{{lek|„…lkslrimttu{{lld‹„‹|‚z¨©´„Š}lrib[Uekdr]g\[[VTLf]cŠƒ}{||f]cmttult“““ƒƒ|{u{f]c™š¤Œ‹“ƒ||tyg{tt’…‹„Š}”š”lekrfk“Œ”’ŒŒœ››¦§¨{ttƒ}ƒ„„Š|‚zŒ”•„Š„¨©´“““|‚z„Š„”››{||llkllk{u{”“›tts{{ƒ{{ƒlksŒ”•ttstllŒ”•}‡’uzt{{ƒ’ŒŒ…‹‹\[[d\\ek]d\\edkllklddtsllri[[TVTLb[Uultlddu{{¦§¨UMR*)(aWMVTLd\\VTL[[TD;9[TTb[U{u{]bZ{{tttsztlSKJlld’ŒŒƒ||tsltsluztddc‚|u{zm‹‹‹ekdkd\ddc‹‹„\[[lldtts‹„„tygŒ”•b[UŠŠ}sle\[[|‚z”“›™š¤…‹‹¸Á¹lri››”Œ‹“|„…uzt]cdlri{{ƒ|‚z]bZf]c{{ƒlrimttŒ‹“b[Ud\\\[[ƒ||lldlld{{ƒlldtslsleekd|‚zldddc\tslj]\VTL‚v{u{{ƒ„„‘Œ……‹‹MRKVZTƒƒ|uztsreŠƒ}ƒ„„|‚z¦§¨‹’ŠŒ‹“‹„„¦§¨Œ”•ƒ„„|‚z””‹£œ¥{||ƒ||{{t‹„„tslƒƒ|œ››{{ƒ››”‹…’ultmttVZTtt{{{ƒ|„…™š¤ƒ}Š…‹‹}‡’™š¤Œ”•}‡’œ¤¦Œ—£‹…š}‡’†~‘|„…lri‹‹‹Œ—£¨©´‹‹‹œ§²|‚z“Œ”Œ”•ŒŒšƒ}Šƒ„„Œ‹“¤¤‹‹‹ª³·™š¤ultult|„…‹…’{{ƒ‹…’…‹‹‹„‹Œ”•lldu{{uzttsl}‡’|„…œ››™š¤œ¤¦nv‚Œ”•‹‹‹œ¤¦œ¤¦{{ƒ„„Šmtt{u{„Š„ttsekdƒ„„Šƒ}ldd„„Š“““””‹‹‹„ddckd\Œ”•uzt{{ƒSKJttsUMRdc\D;9{ttMRKsle{{ƒƒ}Š{{ƒtll{{tƒ}ƒ™š¤”š”lrid\\kd\ƒ„„{ttƒƒ|œ››…‹‹ƒ}Šƒ}ƒ‹„‹{{t“““¨©´™š¤{u{ª³·ƒ}Šƒƒ|u{{mttu{{tll…‹‹lks|„…ŒŒš{{ƒf]c{||{tt{{ƒ{{ƒlrilksƒ„„tsl{ttlld{{tmttultkd\rfk{{ƒ]bZkk]tllVTLUTS]bZ²²¬]bZ:97Šƒ}VTLtzli\VJHFi\VUMRVTL‹…’\[[\[[mttnƒ‰v|uzttll“Œ”Š}|bVU„Š„‹‹„¤¤ultlld]bZedk|„…sre{ttkd\bVUf]cŠƒ}œ¤¦”š”|‚z[TTtll‹„„œ¤¦‹’Š[[Tllkd\\ƒ||ƒ}ƒœ¤¦”š”u{{edk„Š„‹’ŠVTL\[b\[bVTLdc\{||ƒ||ztlttsred]bZek]cbV…‹’››”’ŒŒllk]cdedkd\\lld]bZkk]tslUTS[[Tedk{||lriddcu{{mttsrei\Vƒ„„„„ŠŒ‹“Œ‹“”››²²¬¦§¨{||uzt„„Š{||{{ƒ{{ƒ‹‹„‹’ŠŒ‹“UTSƒ||‹‹‹|„…|„…ttstt{tt{œ››…‹’ƒ}ƒtllŒ—£|„…u{{}‡’{{ƒ™š¤œ§²Œ—£Œ—£¨©´¬¶Ãœ§²…‹š‹„„mtt“Œ”Œ”•‹‹‹œ§²]cdœ¤¦‹…’|„…Š~‹‹‹‹{||™š¤„Š„™š¤µ¶·™š¤™š¤™š¤„„Šœ¤¦™š¤…‹š‹…’‹’Š”“›ŒŒšlriª³·]cdu{{]cd…‹š~’“|„…‹‹„„Š„u{{mttƒ}ƒ…„’mtt{u{“““cbV]cdf]cSKJtts‹’Š‹’Štllztlddcƒ„„ttsekdlrilksSKJ]cd|„…[TTlriddc[[T{u{lksyl„‹‹‹Œ”•Œ”•tts“““ƒ„„‹„„zll‹„‹“Œ”›¢›{||””‹|‚z™š¤¦§¨„Š„tslœ¤¦›¢›{{ƒ‹‹‹{{ƒ„Š„|„…‹„„ŒŒš{tt…‹‹}‡’“Œ”tt{ŒŒš‹‹‹›”›lri|„…]bZmtttt{tllƒ„„ddcuztbVU\[[…‹‹tsl|‚z‹‹‹srecbVyfdlddred[[T¦§¨JHF*)(kd\VTLek]VTLMRKD;9{{t[TTlddJHFVTL\[[tt{{u{{||zll‹‹„Šƒ}›”›”››ekd‹’Šƒƒ|“““””‹ttsƒ}ƒtsllekkd\VZT\[[{ttSKJ{{tzll’ŒŒ‚|u|‚ztsltlluzt{tt„Š}ƒ‚uƒ||Œ”•””‹Œ”•\[bcbVn…fkkbVZSKJz‚l„„Šttstllkd\Š}ƒVTL|‚zƒ„„lek[TTtsld\\]bZ‹’Ѝ©´ult¤¤”“›[TT„„ŠUMRultrfklri]bZUMR|„…lriVZT{tt‹‹‹‹‹‹{{ƒ|‚z™š¤›¢›‘Œ…Œ‹“|‚ztsl’ŒŒult…‹‹ƒ||[[Tfkkuztƒ}Štts„Š„‹„„ƒ„„{||Œ‹“”š”Œ‹“’ŒŒ‹‹‹…‹’{{ƒmtt{{ƒŒ‹“nv‚Œ”•…‹’…‹šœ§²|„…›²{{ƒ“““™š¤¦§¨u{{f]cŒ—£‹‹‹{u{”“›…‹‹£œ¥‹„„ƒ}Š‹„‹™š¤uzt™š¤edkŒ”•™š¤œ¤¦¦§¨…„’œ¤¦µ¶·Œ”•’ŒŒ…‹‹]cd|‚zVZ[mtt]cdœ§²‹’ŠŒ”•ddcuztŒ”•fkklksŒ”•Œ”•lksUTSSKJtsl‹’Š{{t]cd{{tuztŒ‹“’…‹|‚z’ŒŒŒ‹“Œ”•ttsƒ||fkktt{lrif]cttsƒ„„[TT[[TVTL{u{ttsmttœ¤¦Œ”•”š”tzl{ttƒ||‹„„Šƒ}”››„Š„‹‹‹Œ”•‹‹‹¦§¨“““‹’Š™š¤„Š„‹‹‹‹„‹‹„„™š¤Œ”•‹„‹{u{{u{{||u{{{{ƒlkslksttsf]c]cdlks|„…\[b|„…ttstsl{ttƒƒ|tll{||uztlld|‚z[[TVTLJHFlld[[T]bZult²²¬UTS*)(dc\[[TJHFaWMD;9D;9jV[FD;JHF\[[b[Uf]cult‹‹„d\\lekƒ}ƒtt{ultiq][[TŠŠ}z‚lŒ”•ƒƒ|ek]‹‹„u{{ƒ}ƒ‚uttzlƒƒ|Šƒ}rg]j]\Š}ƒ‘…„zlllddek]mtt{{t‹‹„ttslri{u{œ¤¦ƒƒ|tll{{ƒƒ||lldMRKSKJF=C„Š„{{trfk””‹r]Z’ŒŒtllbVU]bZekdsle{tttllƒ‚uekdtlltll››”…‹‹‚v{ult{u{\[[ultfkk>B9tll|„…‹’ŠcbVekd””‹u{{‹„„ƒ||{{ƒœ››ƒƒ|„Š„™š¤ttszlllddmtttslttstt{ƒ„„œ››››”{{t…‹‹tts|„…{tt™š¤mttlriuzt|„…\[b}‡’…‹’…„’…„’Œ”•Œ”•}‡’Œ—£…‹šœ¤¦™š¤{{ƒ¦§¨Œ—£…‹‹ƒ„„Œ”•ª³·‹‹‹™š¤Œ”•Œ‹““Œ”™š¤™š¤”››”››“Œ”™š¤›”›™š¤†~‘™š¤u{{lks“Œ”…‹‹‹’Škd\f]c|‚z|„…mttVZTnv‚|„……‹’llkƒ„„u{{…‹‹Œ”•ult…‹šƒ}ƒf]c¤¤{|||‚zllk|‚z{{t]bZsleƒ||ƒ„„””‹”“›dc\ƒ||\[[{tt\[b[TTŠ}ƒtzl|„…VTLek]JHF{u{”››Œ”•Œ”•¨©´{{ƒ¦§¨ƒ„„š””{ttœ››‹’Šuzt‹‹‹tslŠ}ƒŠ~‹tll|„…ztl|„…]bZ{||„„Š|„…‹’ŠŒ”•u{{‹„‹{{ƒŒ”•…‹’ŒŒš…„’“““{ttu{{mtt]cd…‹‹{{ƒƒ||‹’Šb[Uekd{ttfkkZbN|‚z\UZekdSKJVTLldd[[Tdc\VTL¦§¨:97*)(slejcVD;93+*JHF74,JHF[TTultƒ}ƒ‚|ulldttsŒ”•ult“Œ”ƒ||ult[[TttsUTS[[Tek]””‹„Š„„Š„Œ‹“„„Š“““š””ddc{{ƒ…‹‹|‚z‚|uult‹„‹‹„‹ultƒ„„”››ultlks“Œ”uzt\UZlritslek]{u{tsllri]cd?;C{tt[[T‹’Šsle{tt‚|ulriJHFddcdc\ddcd\\tllƒ‚uVTL[TTttsd\\ultttsb[Uult[TTUMR[TT‹’Šlri{||ttsekdfkk›¢›Š}|ƒ}ƒ““““““ƒ}ƒtll›¢›llk··Ä“““„„Š“Œ”mtt”š”uzt¦§¨‹‹‹ztl{|||‚zƒ‚uŒ”•{{ƒ‹„„…‹‹tslœ››™š¤mtt{{ƒ|„……‹’Œ—£™š¤ª³·Œ”•}‡’|„…œ§²ª³·¡¡ƒ}ƒƒ}ƒ‹…’™š¤„„Ь¶Ã£œ¥¦§¨ª³·œ¤¦œ§²›¢›™š¤Œ‹“œ§²|„…£œ¥‚v‚¦§¨™š¤™š¤lks…„’œ¤¦]cduztmttu{{{{ƒtts|„…Œ”•fkkmtt|„…Œ”•{{ƒ‹‹‹edk]bZlks}|’‹‹„ƒ}Šrfk{{t…‹’’ˆtsl‹’Š]bZ[[TUTSŠ~‹u{{‚|u„„Šekd[[Tdc\u{{VZ[lrilekuztuzttsllrilriultd\\|„…‹’Štt{”“›”››¦§¨Œ”•¦§¨mw””‹‹‹„tslVTL{{ƒ™š¤{||”››‹‹‹ƒ„„”“›ƒ}ƒtslllk„Š„“““”“›ƒ„„lriult™š¤{{ƒ‹„‹ƒ}ƒtt{ƒ„„lks]bZ{{ƒ{u{{||‹‹„f]cdc\SKJ„„Štslƒƒ|llk[TT[[TztlVTLsrett{d\\¤¤JHF*)(j]\cbVJHFSKJF=CF=C[[T[[TbVUƒ}ƒ{{tƒ||²««’ŒŒ{u{tlllekllktll{zmdc\kd\{{t{{tlri]bZ”“›‹‹‹™š¤ƒ„„“““‚wl””‹…‹’ƒ}ƒƒ||red|„…ƒ}Šsle‹’Š„„Š£œ¥…„’Œ”•œ¤¦”››SKJlektllŠ~‹‹’ŠŠƒ}\[bultleklritsld\\’ŒŒ{ttddc‚v{mttƒ„„“““tllb[U“Œ”d\\‹‹‹kd\b[UbVZdc\lddF=Cf]clekŒ”•mttf]cmttttsu{{…‹‹lri“Œ”Šƒ}ƒƒ|ƒ„„lldtsl…‹‹“Œ”„Š„Œ”•‹…š{u{²²¬fkkŒ‹“uzt››”ƒ„„‹’Š”š””š”f]cƒƒ|{ttlld”››„Š„…‹’{{ƒ|„…{{ƒ…‹šœ¤¦œ§²œ§²}‡’}‡’|„…Œ—£œ§²tt{™š¤{{t“““„Š„…‹‹¬¶Ãœ››‹‹„…„’£œ¥¨©´“Œ”lks„„Š…‹’lek£››™š¤Œ‹“Š~‹„„Šmttœ§²Œ”•“Œ”lddmttUTS”š”|„…mtt”“›|‚zœ¤¦Œ—£tt{{||…‹‹…‹‹{{ƒlks{{t‹…’tll‹‹‹“““¤¤kk]uztVZTddclekbVZtslkd\lksŒ”•VTL]bZtlluzt[TTtll‹’Š]bZekdu{{{{ƒ{{ƒ“““|‚zlri{{ƒ{u{lld››”{u{‚v{’ŒŒekd{{tzll„Š„ƒ||Š}|{{ƒœ››„Š„ttsŒ‹“}‡’f]cmttŒ”•f]clri{{ƒmtt]bZedk„†™ŒŒš‹…’mtt‹‹„tt{dc\]cdu{{tts‹’Š‹’Šllk{tt|‚zztl]cdlek[[T{{trg]VTL[[TSKJldd¦§¨\[[*)(sleJHFbVZJHFJHFVTLVTLkd\[TT’ŒŒ{{t„Š„ƒ||ttsrfk{{ƒ’…‹{{ttslllklri“““””‹llkttsu{{f]cŠŠ}ƒ}ƒ{{t””‹ek]lksfkkŠ}ƒƒ„„ttstzlƒ„„d\\uzt”“›]cdultttsœ››Œ”•d\\…‹‹UUYƒ|||‚zddcdc\UMRdc\mtt‹‹‹rg]lek““““Œ”lddlri{ttjcV¦§¨‹‹„[TTj]\ek][TT{ttƒ}Š|„…llk{tt‚v{ƒ}Š|‚ztt{\[[]cd\[[…‹’™š¤„„Šƒ||”“›{||Œ‹“{||tsl|‚ztt{{||ekd“Œ”ƒ}ƒœ››|‚z”››sle”“›“““ƒ„„„Š„›¢›|„…ekd]bZ|‚zƒ„„dc\…‹‹…‹š…‹’„†™™š¤œ¤¦™š¤Œ—£…‹šŒ—£Œ—£}|’|„…Œ”•{{ƒœ››{{ƒ{||‹‹‹{{ƒƒ„„œ››Œ”•Œ”•Œ”•™š¤œ§²œ¤¦|„…™š¤‹…š‹„„ultŒŒš··ÄŒ—£™š¤œ¤¦œ¤¦lks]cdlksmttlri\[b…‹šmttŒ”•mttƒ„„ult…‹‹œ§²{{t{{ƒ{{tƒ}ƒ‹„‹“Œ”tts{{t]bZ[[T|‚zuzt“Œ”“Œ”llk””‹f]c{{ƒ]bZek]tsl\[[JHFmttmtt”››|„…{||ddcztl[[T\[[’ŒŒ™š¤”“›Œ‹“¦§¨ƒ}ƒlld’ŒŒ„Š„¦§¨{{tlld‘…„›”›”››uztŠŠ}lkslld\[[tsl}‡’uzt|„…{{ƒlks{||VZ[{{ƒƒ||lekŒ‹“lddlri{{ƒ[[T{{ƒƒ„„tsl…‹‹{{t]bZƒƒ|{u{‹‹‹{zmedkddc[[Tdc\VTLztl\UZldd¦§¨LKR*)(ztf{{t{ttUMRVTLj]\|‚zrg]‚v{f]ckd\tts{u{fkk‚v{„„Štt{slekd\dc\ttsuzt””‹lks”š”{u{tt{’…‹‹‹‹‹„‹{||’ŒŒ”š”Œ”•{ttƒ„„\UZ‚|uf]ckk]{{t””‹{{ƒ\[buztœ¤¦”š”tslmttlkstsl‹’Š{||SKJ\[[[TT|„…[[Tdc\’ŒŒtllkd\lkskd\‚uttzl‚|u{zm¦§¨tsld\\š””kk]lld{{ƒultf]cƒ||ult]cdlkslks{||lek›¢›‘Œ……‹’ƒ}Šœ¤¦ƒ‚u··Ä‹‹‹¦§¨ekd‘…„{||ult£œ¥’ŒŒ””‹Œ”•‹‹‹””‹{{ƒƒ„„”››„„Š“Œ”|‚ztts‹‹‹™š¤{||{||Œ”•{tt„„Šlksœ¤¦}|’„„Š…‹’|„…Œ”•}|’…‹šŒ—£{{ƒ‹’ŠŒ”•™š¤ŒŒš|„…£œ¥{u{\[b“““·¶Ñ£œ¥¨©´Œ”•¦§¨ªÁř𤍩´{||‹…’¨©´œ¤¦œ§²Œ—£œ¤¦Œ”•u{{|„…mtt\[[tts}‡’|„…mtt]cdfkkddcŒ”•ƒ„„|„…‹‹„ultlri‚v‚{||d\\[TT”š”kd\kd\fkksre\UZJHFmtttts{{ƒ„„ŠVTLb[U‚utmtt\[b\[b|„…{||u{{ƒƒ|[[Tlldƒ}ƒ}‡’{{ƒŒ‹“”“›‹„‹‚|u{ttœ››{u{|„…‹‹„{tt’ŒŒœ››{ttmtt“Œ”ƒ‚u”š”ŒŒšnv‚mttmtttsl‚v‚Œ”•ultmtttt{…‹‹”“›‹„‹ƒ||uztu{{ultmttUUYult{{t{||œ››]bZsle\[[UTS[[Tllkdc\VTLVTLVTLd\\jV[SKJ¦§¨\[b74,red]bZlddekd[TTSKJ]bZSKJf]cb[Utslddcztl{{ƒrfk‚v‚ult‹’Šdc\kk]{{tkk]dc\ult„Š„{{t‚|ud\\ƒ}Š[TTtzllri[[Tekdtsl¦§¨tll„„Štts|‚z|‚zŒ”•fkkƒ}ƒu{{{||uzt]cdJHFlksdc\[[TtllSKJ“Œ”tsl|‚zmtt‘Œ…tll‹„‹VTLsretllƒƒ|{zmf]cllk{{t{ttUTS‹„„ztl{ttllkf]ctllf]cSKJJHFult„„Šu{{JHFtt{„Š}”››Œ‹“œ¤¦{tt{u{’…‹›”›mtt‚v‚ª³·dc\lek„Š„””‹lldkk]{||edk{{t|„…„Š„™š¤|„…ª³·ult{{ƒmtttts|‚ztt{uzt{{ƒª³·™š¤Œ”•mk…{{ƒ{{ƒ™š¤™š¤ƒ}Šœ¤¦lekƒ„„d\\‹’Š|„…ƒ}ƒ‹„„f]clksª³·‹…’‹„‹|‚zŒ”•”“›»ÂÇ|‚z{{t“Œ”„„Šœ››Œ”•¨©´ª³·œ¤¦Œ”•fkkVZ[„„Š|„…{{ƒ^fs]cdmtt\[b”“›Œ”•”š”ultœ¤¦{{ƒ™š¤f]cƒ||tsl‹’Šddc’…‹JHF|„…ƒ‚u‚utf]cult\[[lkstt{{ttult‹‹‹™š¤Œ—£nv‚\[[]bZekd]bZJHFddcult‹„‹™š¤…‹’…‹‹¨©´„Š„“Œ”‹„‹kk]|„…{||tllƒ||tslult\[[Œ‹“ƒƒ|SKJf]cŒ—£|„…Œ”•{||tslŒ”•”š”…‹‹mttlks{{ƒ“Œ”“““mtttslult”š”yl„\UZtsluztultuztƒ||ddcd\\kd\UTStslVTL[TTlld]bZrg]d\\œ¤¦LKR*)(bVUVTL74,JHFJHFf]clldUMR{tt|‚zƒƒ|uztb[Uƒ}Š“Œ”‹„‹{u{ztl{{tkk]b[U„Š„[[T{{tdc\‚v{Œ”•‚ut{{ƒ{tt{{tlricbV|‚zlekƒ||tts{tttslultƒ„„…‹‹{u{{u{tts|‚zmttUTS\[bUMRd\\ekdVTL[[TbVZult‹‹„{{ƒsrered[TTbVUf]cSKJ‘Œ…””‹sletsl{zm¦§¨u{{ƒ}ƒ[TTSKJƒ||bVZlddllk{u{SKJf]clkstt{MSS“““‹‹‹‹‹‹{u{„„Šƒƒ|”“›™š¤‚|u‹’Šddc”››lksƒ„„‹…’¦§¨tslult{{t£œ¥‹’Š“““…‹‹›¢›Œ‹“{||{{ƒ{{ƒ\[btt{Œ”•{{ƒ‹„‹™š¤™š¤™š¤Œ‹“mtt}‡’}‡’lksmk…†~‘tts„„Š{{tƒ}ƒttsu{{“Œ”‹…’™š¤œ¤¦|„…tsl‹„„]cdu{{œ¤¦…‹’{tt‹‹‹lks‹„‹™š¤…‹‹œ§²Œ”•‹…šœ¤¦]cdUTSƒ}Šnv‚mttVZ[\[b\[b|„…ƒ}ƒ\[[|„…ƒ}ŠŒ”•|„…‹…’{{ƒ{u{””‹MRK{{ƒ™š¤f]cllkkd\{{ƒlksŒ‹“ƒ„„lksmtt|‚z…‹’‹…’^fs\[[mttu{{{{t|‚zVTLtsltslVTLfkk…‹‹{{ƒœ››‹…’›”›ult‹‹„ƒ‚u¤¤‹’Š“Œ”„„Š‹„„j]\…‹‹u{{ƒƒ|Œ”•f]cultLKRƒ„„…‹‹ƒ}ƒlddttsŒ”•ƒ}ŠŒ‹“…‹’™š¤…‹‹lekuzt{u{|„…lksmttlri|„…lriuztlekultd\\dc\UMRek]sle[TT]bZSKJ\[b[TT¦§¨MSS-1+VTL[TTPF=UTSddc\[[lld‚utred|‚z|‚zƒ„„ƒ||u{{{ttbVZlek{zmj]\VTLmttdc\tzl|„…‹‹„{||lekƒ}ƒ‹…’{{t’ŒŒ{{t\[[Šƒ}UMRƒ}ƒtt{|‚z{{ƒfkkš””ƒ„„™š¤‹…’{{ƒ™š¤|‚z“““ŒŒš‚wlVTLtsl[TTlks„vŒSKJ|‚z„„Šddc{||ƒ}ƒlddj]\tts‰|vJHF[TT‹‹„‚|urfk{{tult’ŒŒsleƒ„„ttstll{tt…„’MSSf]cult„„Š\[bldd{ttŒ‹“ultf]clekœ¤¦Œ‹“‹’Š|‚z™š¤”››‹…’{||Œ‹“‹‹„„Š„ƒ||™š¤ƒ}ƒŒ”•…‹‹lld|„……„’uzt{||mttedk|‚zœ§²™š¤œ¤¦™š¤™š¤¦§¨¦§¨›²‰Š¡|„…‰Š¡{{ƒmttŒ”•‹„„uztŒ”•“““›”›œ››£œ¥Œ—£‹‹„llk‹‹„”š”ult|„…™š¤œ¤¦|‚zf]cf]c{{ƒ™š¤}‡’¨©´”››ŒŒšmtt]cd\[[ldd|„…Œ”•mtt{{ƒVZ[lks{{ƒlksmtt{{ƒlek\[blks{u{Œ‹“{ttSKJ{u{tll{u{VZ[‹‹„tt{llkddclddrfk|„…ƒ„„{{ƒtt{edk|„……‹šmtt‹‹‹]cd]cdlld{||{ttultŒ”•„„ЄЄ{{ƒ]cd{{t{tt¤¤ƒ„„‹‹„œ››u{{u{{‹„‹Œ‹“|‚z[TTtt{{{ƒ|„…u{{‹‹‹ekd{{t{||tllfkk{u{VZT|„…‹…š{||ddc|„…ult…‹‹ldd{tt|‚zekdddcUMRztlfkk‘Œ…‹„„SKJVTLdc\D;9JHFlldVTLldd¦§¨JHF,55sled\\:97JHFredbVUlri{u{tllUTSVTLlriultf]cult‹„‹ult‹‹„“Œ”]bZ{{ƒ„Š„tsl]bZ„Š„‚|uf]clekultdc\””‹llk…‹‹VTLVZTlek{{ƒ¦§¨›”›UTSd\\…‹‹{||tt{ƒ}Š™š¤”š”‹„„Œ”•ult‘Œ…‹‹„{{tJHFƒ„„f]c„Š„ult{tt›”›sleztl‹„„rfk£››redrr]slettsšŒ›¢›“Œ”™š¤{||‘Œ…{{ƒrfk{zm\UZJHFddc{{ƒ\UZLKRŠ}ƒƒ„„£œ¥‹„‹{u{ldd’…‹Œ”•‹’Š|‚zmtt‹‹‹ƒ||™š¤lks”››‹‹‹‚ut‚|u‹„„{||{ttŒ”•‹’ŠŒ”•“““[[Tmk…uzt“Œ”lks{{ƒ…‹šœ§²··ÄŒ—£¨©´™š¤™š¤™š¤}‡’†~‘mtt‹„‹{{t{{tŒ”•{{ƒ“““¨©´¨©´™š¤µ¶·ƒ}Šš””™š¤]cd{||Œ”•{{ƒ„„Šult{{ƒ‹…’Œ”•…‹‹{{ƒttstt{{||]cd…‹‹tts]cd|‚zŒ”•n…mttlkslks™š¤”››ŒŒšultu{{ƒ}ƒƒ}ŠŠ}ƒ‹‹„‹„‹uztg\rŒ”•Œ”•š””ƒ}ƒ”“›edkƒ||f]c|„…{{ƒ|„…lks\[blksŒ—£nv‚›¢›|‚z{{ƒ“Œ”‹„‹Š}|tll…‹’“Œ””“›”“›…„’tsl‘…„tslult…‹‹œ¤¦’ŒŒtt{ƒ}ŠŒ”•mtt„Š„…‹’“~ˆ™š¤mttfkk‹„‹ƒ}ƒ‹…’ttsfkkttsu{{{{ƒ{{ƒ\[[mttmttUMRllkƒ}ŠmttuztUTSfkkUTSSKJ|‚ztsl[TTSKJ[[Trg]aWMlrilddcbVult¦§¨LKR,55‚wl[TT\UZddcJHFtll[[Tultllk]bZtzl{ttult[TT”“›tsl„„Š‹’Šƒ||SKJmttŒ”•|‚zttsek]Œ”•lddœ››llkd\\{||d\\mttJHFVZTbVZlks’…‹mtt|„…„Š}Œ‹“„„Šƒ}Š{{ƒ‹’Šu{{lks™š¤{ttsle[[TUMR?;Cf]cSKJ„Š}lekttstt{„„Šf]cƒƒ|UMRkk]ztlŠ}|VTLuzt…„’”š”f]cƒ||VTL‹„„…‹‹lddldd[[Tekdd\\mttlks\[b{|||„…lksldd{{ƒ‹„‹ttsŠ}ƒ|‚zu{{{{ƒ‹’Š‹„‹ƒ||…‹‹››”|„…ƒƒ|ƒ}ƒtll‹‹„Šƒ}Œ”•‹’Šƒ||„Š„tll{{ƒ‹„‹”“›{{ƒœ¤¦…‹‹Œ‹“…„’œ§²¨©´Œ—£·¶Ñ™š¤…„’‰Š¡„†™u{{b[Ulld{{ƒƒ||£››£œ¥”››‹„‹¦§¨ultŠ~‹¦§¨|‚z|„…™š¤¦§¨œ¤¦ƒ„„¨©´£²mtt™š¤lks”“›lddŒ”•mttœ¤¦“““Œ—£|„…{{ƒnv‚œ¤¦]cd|„…\[b|‚zlek\UZlks‹„‹ŒŒšlek‹’Šƒ„„’‘~ƒ}ƒƒ„„…‹‹Š}ƒlks„„Š„„ŠŠ}ƒ…„’lks{||{{ƒLKR…‹š{{ƒ\[b~’“|„…Œ”•mtt„„Šd\\…‹‹£œ¥Œ”•”“›”𔋅’Œ”•lriŠŠ}‹‹„”“›’ŒŒ¦§¨š””{{t‹…’|„…|„…lks{u{™š¤œ¤¦Œ—£|„…tllf]cfkk“Œ”lriu{{ultu{{{{ƒƒ|||„…mttlksŒ‹“lks…‹’ƒ„„…‹‹lks]cddc\\[[dc\[TTultddcsre{ttlrikd\ztlVTL¦§¨MSS:97tzlŠŠ}ultSKJVTLVZTVTL[TT[[Tf]c‚utllkŒ‹“dc\lekb[Uttsƒ}ƒtt{ƒ|||„…mtt|‚zuztlldƒƒ|f]clksult‹„„ultœ››œ¤¦|‚zddc“Œ”Œ”•{ttJHFtsl‚|u|„…u{{ƒ„„|„…ttstt{…‹’ƒ}ƒtlld\\iq]lriUMR|„…d\\llktlllri\UZ[TTsleŠƒ}\[[ultŠƒ}’ŒŒztl¦§¨‹„„”š”\[[ƒ||]cdJHF[TTVZTVTL\[[ekdSKJ^fsmttSKJdc\ldd„„Š“Œ”„„Š™š¤ult‹‹‹“Œ””š”ƒ}ƒƒƒ|ƒ}ƒ„„Šƒ„„{||’ŒŒ…‹‹uztllklldtll›¢›{||{{tzlltts\[bƒ}ƒult˜Ž£u{{Œ”•ulttt{™š¤„†™„„Š‹…š…‹’ŒŒš™š¤Œ—£“Œ”lek{u{›”›ƒ}ƒ“Œ”{u{µ¶·›¢›‹„„“Œ”™š¤¨©´ª³·œ§²›¢›|„…œ¤¦‚v{£œ¥ƒ}ƒŒ—£Œ”•…„’…‹‹”“›|„…œ¤¦lri¨©´{{ƒ|„…Œ—£œ¤¦}‡’mttlektt{‹’Š‚v‚”››ŒŒš„„Š„„Š[TT„Š„{{t‹‹‹{{t{{t„Š„ztl]bZ‹…’{{ƒƒ||ŒŒštts{||JHFVZ[lksn…MSSmttmtt{||fkk\[[™š¤œ¤¦Œ‹“‹‹‹›”›|„…“Œ”‹’Šlddƒ„„‹‹‹‹…’Œ”•””‹“““Š}|‹„‹nv‚ultdc\™š¤tt{edkUUY{||ƒ„„ŒŒš{{ƒmtt]cd\[b^fs‹’Š…„’mttmttmttf]cmtttsl„Š„ekduztUTSƒƒ|‚utleklrid\\f]ccbVlddSKJlldUMRr]ZVTLµ¶·OS`)+2‹’Šƒƒ|llkFD;[[TSKJFD;SKJVZTUMRJHFJHFtsllldredSKJ{||‹„‹UTS\[b¨©´ekd›¢›|‚z|„…tts{||ƒ„„mtt‹…’{||lri™š¤œ››]cd‚v‚uzt‹’Šztl[TTztltts™š¤\[btsl{{ƒ…‹‹{u{UTS‹‹„ƒ„„|„…]bZ{{ƒJHFddcultŠ}|\[[d\\srelri{ttŠ}|rfksrebVZdc\edksleddcu{{\[[ekdf]c\UZ|„…d\\|‚z[[T\[[\[b™š¤d\\{{td\\£œ¥‹„‹¨©´Œ”•¦§¨ƒ||lritts‹„‹…‹‹ƒ}ƒ‹‹‹ƒ„„{tt¦§¨œ¤¦ƒ||ƒƒ||„…””‹›¢›‹‹‹…‹’’ŒŒttsUUY{{ƒŒŒš™š¤œ¤¦Œ”•}‡’ŒŒš¬¶Ã†~‘„„ŠŒ—£œ››¨©´…„’Œ—£uzt¦§¨…‹’›”›tt{†~‘‹„‹{tt{||‹„‹™š¤™š¤{tt…‹‹}‡’Œ”•ƒ„„’ŒŒ“““‹…’™š¤˜Ž£Œ”•lksœ¤¦Œ”•…‹‹]cdlriddcult|„…uztŒ”•|„…¬¶ÃŒ‹“™š¤ƒ„„“““‹„‹ddcultult[TTtllekdiq]]bZ„Š„ekdkd\{{ƒ\[[ekdf]c™š¤ƒ„„{u{lksmtttt{|„…|„…n…Ž¡›ek]|„…„Š„lksuzt“Œ””››“Œ”mtt{{ƒlks{{ƒš””œ››†~‘‘Œ…“““‹‹„“““tllŒ”•„„Š’ŒŒƒ}Š|„…{{ƒlksŒ”•ddc{u{{{tult|„…mtt|„…{{ƒlksfkk\[b]cd\[b]cdfkkddcuzt]cdlri|‚z{||[TTb[Ukd\sleb[UyleyfdllkJHFaWMlriœ¤¦OS`*)(ttsƒ}ƒ{ttd\\sre{{tb[UVTL74,JHFFD;UTSVZTkd\redjV[{u{ekdmtt{{tult{{t‹’Š|‚zu{{lkslri\UZuztƒ}ƒ[TTƒ„„Œ‹“lri]cdddc{||UTStt{„„Š›¢›|„…tts{u{|„…››”uztultUTSlddztl|‚zek]{{ƒ:97f]c\[[{ttlld”“›{u{|‚z“Œ”{ttƒ„„rfk{tt‹„„sref]cUMR[[TlriJHFƒ||\[b{{ƒƒ„„™š¤Œ”•ult]bZultƒ}ƒƒ||mtt’ŒŒ„„ŠŒŒšekdtt{£œ¥”“›ª³·“Œ”„Š„{||{||œ¤¦‹„„ŠŠ}{{tª³·‹„‹”š”ƒ}ƒu{{„„Š|„…’ŒŒ{{ƒultmk…ƒ}Šœ§²œ¤¦~’“œ¤¦ult›²œ¤¦Œ—£Œ—£…‹šŒ—£„„Š|„…“Œ”tllœ¤¦œ››ŒŒš}‡’š””µ¶·“Œ”“““›”›‹…’›”›œ¤¦|„…«²«Œ—£Œ‹“¦§¨™š¤lks™š¤™š¤Œ—£Œ”•…‹’¨©´¡¡…‹‹“““{ttŸ±¯VZ[{{ƒ]cdmttUUY…‹‹„Š„ult”“›yl„Œ‹“f]cf]c‚wlddcJHF[[Tƒƒ|edk’ŒŒ„Š„ulttt{š””edkmttŠƒ}]cdMRK{{ƒ|„…OS`lriŒ”•]bZLKR{{ƒlksuztyl„™š¤“Œ”“Œ”™š¤…‹‹…‹‹‘Œ…‹‹‹ƒ}ƒ‹’Šš””››”‹„„Œ‹“…‹’edkttslekmttfkkƒ„„Œ‹“{||…‹’|„…ƒ„„\[[f]c\[b]cd{{ƒlks|„…Œ”•}‡’‹„„…‹‹ƒƒ||„…lksVZT…‹‹‹’Šf]ckd\b[Uf]c[[Trg]red{{tekd]bZtsl¨©´JHF,55mttlldbVUFD;b[Uz‚lekd[[Tekdlri›¢›SKJlld„Š„ƒ}ƒ{u{{u{d\\UTS…„’lks|‚zlrimttu{{mttllk\[[llk\[[ldd{tt{||lri{{ƒ„„Šulttsl{{ƒmttƒƒ|{||ƒ}ƒƒ}ƒult„„Š{{ƒttsdc\{{t{{t„Š„[[TlksJHFJHFd\\„„Š|‚z{{ƒ‚|uŒ‹“tsl[TTrfkVTLrfkdc\FD;sleekd[TTkk]|„…lldƒ}ƒ{u{JHF{{ƒ\[[UUY]bZ{u{SKJllk„Š„zlllek{||„„Š‹‹‹ƒƒ||„……‹‹…„’‹’Šƒ}ƒ‹„„Œ”•lld›”›‹‹„“Œ”lriŠƒ}ldd|‚z{{ƒŒ”•llk“Œ”lks‹’Šlekmtt“Œ”œ¤¦Œ‹“{{ƒ|„…Œ—£Œ”•œ§²‰Š¡™š¤{{ƒ™š¤ \ No newline at end of file diff --git a/Extras/ode/drawstuff/textures/sky.ppm b/Extras/ode/drawstuff/textures/sky.ppm deleted file mode 100644 index 38f68a9a0..000000000 --- a/Extras/ode/drawstuff/textures/sky.ppm +++ /dev/null @@ -1,5 +0,0 @@ -P6 -# Created by Paint Shop Pro -128 128 -255 -¾çýÃéþËîÿÎïÿÆéÿÂçÿºçÿ·åÿ²àÿ°Ýþµàÿ¹åþÃëÿÍðÿÏðÿÐíûÑîüÏïþÇìÿ½æü´àù´âü¹åÿºæÿ¹åÿµâÿ±Þý«Ùú¦×ø§ÙüªÜÿ¶âýÉîÿÐñÿÚõüâúþëýýíýüïÿþìþÿìþÿãüÿÛøÿÊíÿÄéÿ­Ûÿ£Ôü£Øÿ¤Úþ§Üü±ãþ°ãÿ¤Ûÿ ÕýŸÔþ ÕÿŸÔþŸÕÿ›ÔÿšÕÿ™×þ˜×ÿ”Ñý™ÒÿšÓþ›Õý¡Ùþ¥Úü­Þü°ßù»åû½èû½æü»çÿ¸åÿ®Þÿ§ÛÿÓÿšÓÿ•Ðü•Ðü—Òþ“Òþ‘Ðû›Óø§Ùú¾èÿÄêÿÌðÿÆîÿºæÿ¦×ø Öú“Óÿ‹Íý„Çü€Äÿ}Ãÿ}Ãÿ~ÄÿÆþ€ÇýƒÉýƒÈÿÆÿƒÈÿÆÿ€ÄÿÅÿÅÿÆÿ€Åþ~Äÿ}ÄÿÆÿ…ÈÿŒËÿÌÿ„Çü…ÊÿˆÍÿ‹ÌÿŽÍÿ‘ÐÿÎÿ™Ôÿ ×þ±âÿ´áþ¸äÿÂêÿÃèÿ»ãý·àü®Üý©Ùý¥Ö÷©Ö÷¯ÛøÂëÿÊðÿÇëÿÆéýËîÿÉîÿÌðÿÆïÿ¿éÿºæÿ»çÿ¼èÿ»çÿ¹åÿµäÿ²àÿ¨Ùú£Õø Ôù¢Öý²ßüÄêÿËðÿØöÿÞùÿéþÿêþýìþþíÿÿêþÿ×õÿÎðü½ãö·áù®Ûú¬Ùú³àÿ½çÿÂëÿÐôÿÏôÿ¼éÿ³àÿ­Ûü®Üþ¨Úÿ£ØÿŸÕÿ‘ÎúŽÍùÏû‘Îû•Ïý–Ñý˜Óý×ý ØýªÜý¬Ýû¸æÿ»çÿ¶âý²áÿ¬Ýþ ÔûÒü˜Ðÿ•ÏýÍú‘Îû”Ñþ‘Ñÿ‘Ñý˜Òø Ôù·äÿÀéÿÇïÿÀìÿ¸æÿ¥ÙþŸÖý‘ÑÿŠÌþ…Èÿ}Áþy¿ý{Àÿ}Ãÿ€ÆÿÈÿÆý‚ÉÿÇÿ}ÃÿzÀüÅÿÅÿÅÿ~Äÿ|ÂýzÀûzÂýÆÿ…ÈÿŠÉþŠÉþ…Æþ†ÉÿŒÏÿÎÿÍþÍþÍþ”Ïû˜Òú¨Ýÿ°Þÿ²àÿ·ãÿ¸áý±Ýú®Ûú¤Öù Òõ¤Ö÷­Ûü³ßüÃéÿÆìÿ¼âùºà÷ÃéÿÅíÿÈðÿÃíÿ¼æÿºäý½çÿ½çÿ¼æÿ·ãþ³âÿ®ßÿ¨Úý¢ÖûŸÕûŸÔü±ÞýÀèÿÇíÿÔôÿÛøÿåýÿèþüìÿÿíÿÿëÿþ×øÿÍóÿ¾ä÷¹ãùµáüµáüÁëÿÍòÿÒóÿÚ÷ýØöÿÆïÿÁéÿ¸âû³ßü®Üþ¥Ùÿ ×ÿ‘ÎûËúŽÎþÎý”Ñÿ•Òÿ–Óÿ›ÖÿœÖü¥Ûÿ¨Ýý³äÿ·æÿ³âÿªÛü¦ØûŸÔü˜Ñü•Ïý’ÏþŽÌû‘Ïþ”Òÿ‘Ñÿ’Òÿ˜ÒúÓù²àÿºçÿ½éÿ¸æÿ³ãÿ¥Ùÿ ×ÿŽÎþ‰Ëý…Èÿ~ÂÿzÀþz¿ÿ|ÂÿÅÿÆþ€Åþ€Çÿ~Äÿ{Áÿy¿ý~Äÿ~Äÿ~Äÿ~Äÿ|Âý{ÁüxÀûÆÿ…Èÿ‰ÈýŠÉþŠËÿŠÍÿŒÏÿÎÿÌûÍü‘Îý“Îú—Ðû¤Úÿ£Øÿ¥Úÿ®àÿ±ßÿªÚÿ¥ÙþšÑø—Îõ¢Öû´âÿ»çÿÉíÿÈîÿ¹áû³Üø³àý·äÿºçÿ·ãÿ²Þû¹ãü»ãý¼æÿ½çÿ¶ãÿ®ßÿªÜÿ¡×ýÔûšÔü›Õý«Ýÿ¸åÿÀêÿÍòÿÓõÿÚ÷ýßûþéÿÿçÿýéÿýáÿÿØúÿÉíûÆëûÉîÿÊïÿÔõÿÚ÷ÿÙõùàõöß÷÷Úöÿ×õÿÏðÿÉìÿ¹âþªÜÿ¡Öÿ’ÐÿÎÿ‹ÌÿŽÍÿÏÿÏÿÐþ”Óÿ‘Ðû›ÖþžØþ¨Þÿªßÿ¥Ùþ¡×ýŸÖý˜Óÿ“ÐýÍþŽÍÿŽÍÿÎÿÎÿÏÿÏÿ’Ïü–Ïú£×þ¨Úÿ¨Øü¤Øý¥ÙÿžÕþ—Òþ‹Êý†ÈüƒÅÿÃÿ|Âÿy¾ÿz¿ÿ}Ãÿ~Äÿ‚ÇÿÇÿx¿ýv½ýu¼üw¾þzÁÿzÁÿzÁÿzÂýyÁüw¿ù€Åþ„ÇüˆÇüŠËÿŒÏÿŠÍÿˆÊþ‘Îû•Îù”Íø–Ïú“Éõ“ÊóÔý›ÑÿžÔÿ©Ýÿ¬Ýÿ£×ÿ Õý˜Ñü•ÐúŸÕû±âÿ¼éÿÌðÿËðÿ¼åÿ´àý°ßý±ßÿ´âÿ´ßÿ±Ýúºäý¹áû»åþºæÿ´ãÿ¬Þÿ¨ÜÿžÕü˜Òú˜Ñü›Ôÿ¥Ùþ²áÿ¸åÿÆìÿËïÿÕóýÜùÿçÿÿäþýæÿüæÿÿßþÿÐñúÎîùÐòþÒóÿÚúÿÝøÿÝöúåûùæûüßøýÚõüÚøÿÕöÿÂêÿ¯ßÿ£Øÿ‘Ïÿ‹Íÿ…Èý‹ÍÿŽÍÿÌÿÍýÐþÍü—ÔÿšÕý¡Ûÿ¤ÜÿžÕü¡Øÿ×ÿ“Ðý‘ÏþÏÿÏÿÏÿÎÿŽÍÿŒÎÿŒÎÿÍü”ÏûžÓý Õý¡ÕüŸÔü¡Öÿ™Òý”ÏûŒËÿ…Æü‚Äþ~Âÿ{Áÿz¿ÿz¿ÿ}ÃÿÅÿ‚ÈÿƒÉÿw¾üu¼üt»ût»ûyÀÿzÁÿyÀÿx¿ýw¿ú{Ãý‚Çþ„Çü†ÅúˆÉÿŒÏÿ‰Ìÿ‡Éû•ÐúœÓúÒúŸÔü™Îö™Îö¡Øÿ”Ìû–ÏüšÐüžÓý™Òý“Îú“Óÿ”ÒÿšÕÿªÞÿ²ãÿÃèÿÅíÿ¾êÿ¸äÿ®Üý¬Úû®Üý²Þû±Ýú³Üø·ßù¸äÿ´áþ®ßÿ£Ùÿ ×ÿœÕÿ›Ôÿ›ÖÿÖÿŸÔü¨Úý­Þÿµáü½åþËïÿÐòþÚ÷ýÛ÷ûàúûíÿÿíÿÿæûüåýÿãþÿßüÿÛùÿÛøþßûÿäÿÿäþÿãøûàøüÞùÿÚøÿÍóÿ±âÿ¡ÕüÎýÎÿ†Éÿ‡ÉýŒÎÿŠÌÿ‰ËÿŠÌÿ‹ÍÿÏÿ‘Ïþ“Ðü’Ïû•Ðü”Ïû’ÏüÏýÏÿŒÎÿŒÎÿŒÎÿŒÎÿŽÍÿÏÿÏÿÏÿ‘Ïÿ”Îü•Îû–Ïü•Îû—Ðý˜Óÿ•ÒÿŽÍÿŠËÿ‚Äþ~Âÿ~ÄÿzÀþy¿ý~Äÿ|Âÿ|ÀýÅÿ{Âÿx¿ÿw¾þv½ýw¾þv½ýw¾üzÂýÇÿÈÿ†Éþ…Èý…Äù„ÅûŠÍÿŠÍÿÐÿ¢Ùÿªßÿµãÿ¸çÿ²ãÿ¬Þÿ Ôû•Îû•Îû–Ìø™Ïû—Òþ‘ÎûÒÿ’Òÿ–Óÿ£Øÿ©Ûþ¸âû¿èÿ»çÿµáþ®Ûú±Þû³àý³ßú²Þùµáü´Ýùµáþ²ßþªÜÿÔû×ÿ™Ôÿ›ÖÿŸØÿž×ÿÔû¢Øü§Üþ¯Þü¶âýÈìÿÌïÿ×õÿÛøÿÝùüêýûîþûëþüêÿÿèÿÿãÿÿÞûÿÚ÷ýÞûÿæÿÿåÿÿãøýß÷ûÜ÷ÿÚøÿÎôÿ³äÿ¢ÖýÍüŽÍÿ†ÉþˆÊþ‰Ëÿ‡Êþ†Éý„ÇûŠÍÿÏÿŽÎþÍüÍüÍúÍúÍüÏÿÎÿ‹Íÿ‰Ìÿ‰Ëÿ‹ÌÿÎÿÏÿÏÿÏÿÎÿ‘Îý“Íý’Ìú‘Ëù”ÎüšÔÿš×ÿÎÿ‹ÌÿƒÅÿÄÿ~Äÿ|Âþ{Áý~Äÿ}Ãÿ}ÁþÅÿ~Äÿ|ÂÿzÀþw½ûy¿ýx¾üx¾ü|ÂþÇÿÈþˆËÿ†Éþ‚Ãù„Åý‹ÎÿŠÍÿ‘Ïþ¨Þÿ´çÿÁíÿÄðÿ¾ëÿµäÿ¤Öû§Ýÿ¦ÝÿœÑû˜Ïø”ÑþÐÿŠÐÿŒÏÿÌÿ“Ìù˜Íõ¬Ýý¸çÿ½éÿ¼æÿ¼äý¿åüÂêÿ½çÿ½çÿ¸äÿ¸äÿ°Þÿ«Üý¢ØþšÓþ–Ñý•Ðü˜ÓÿŸØÿŸÕÿ×ÿ ×þ¤Úÿ©Ûþ¯Ýÿ¾çÿÃèÿÒóÿÙöÿÝøÿãøûçûúéþÿéþÿäýÿáúþÝùýÞúþàüÿáýÿßøÿÚõþÛöÿÛùÿÕöÿÅîÿµäÿ«ßÿ“ÐýŒÌüŒÍÿÎÿ‰ËýŠÍÿ‰Ìÿ„ÇüƒÆû†Çý…Çû‡ÆùŠÉüÍÿÎÿÎÿÏÿŒÎÿ…Çù†Èú‰ËÿÌÿŽËÿÌÿÍÿÎÿÎÿ‘Ïÿ‘Ïÿ‘Ïÿ“Ðÿ–Ðÿ™Ñÿ™ÓÿÎÿŒÎÿ…ÈýÆÿ€Çÿ~Äÿ~ÄÿÇÿÅÿ‚Çÿ‚ÈÿÅÿ|Âþ{Áý|Âÿ|ÂÿzÀüzÀü~ÄÿƒÊÿ†ÍÿŽÑÿÐÿ‹ÌÿŒÍÿÐÿÎÿ’Ïü«Ýÿ¸çÿÌñÿÒøÿÏøÿÈðÿµâÿ©Þÿ¨Þÿ›Ðø—Î÷“ÐýÐÿˆÍÿ†ÍÿˆÉÿÌþ•Îû£Ùû¬ßþºæÿ¿èþÇêýËïÿÌïÿÃìÿÅïÿºèÿ¹æÿ«Üý§ÛÿÔý”ÏûÍú”Ïû–ÑýÓÿžÓýœÖþ×ÿ¢Ùÿ¤Øÿ§×ÿ®ÙûµÞüÇêÿÎíÿ×óÿÛöÿÞùÿÜ÷þÛ÷ûÛ÷ûÛ÷ûßøüäüþéþÿåúýÝôú×ôÿÖóÿÒóÿËïÿ»æù«Üú¥Úü•ÐüÎý‘ÐÿÎÿŽÍÿÏÿÏÿŒÏÿ‡Êÿ†Éþ‡ÊÿŠÌÿŒËÿÍÿÏÿÏÿÏÿŒÎÿ‹Íÿ‹ÍÿŽÍÿÌÿÌÿÌÿÌþÍÿÎÿÎÿÎÿ‘Ïÿ“Ïÿ”Îþ—Ïþ˜ÒÿÏÿŽÐÿˆËÿ‚ÇþÈþ~Åý~Äÿ}Ãþy¿ú}Âý‚ÇÿÆÿÆÿÆÿ€Äÿ~ÂÿÃÿÄÿÆÿ‚Çþ„Ëÿ‡ÊþˆËÿ‰Êÿ‡Èÿ†Èÿ‡Èþ“Îú©Úú´àùÆèòÍîõÒôÿÌñÿ¼äþªàÿ©ßÿ›Òù–Íö‘ÎýŽÎþ†Ëÿ…Êÿ†ÇýËý•Îû£ØúªÝü¹åþÀéýÈìüËïÿÉìÿ¿èþÂìÿ¹çÿ¸çÿ«Ýÿ©ÝÿœÕÿ‘ÎúÌù”Îü–Ñý›ÑýžÓý×ýžØÿ¤Ûÿ¤Ùÿ¦×ÿªÖù±ÜüÄèÿÊêÿÖóÿÛ÷ÿÝùÿÙ÷ÿØöþÛøÿÛøþÛ÷ûâúþçüÿåúûÞöúÓòÿÐñÿÉîÿÄêýµâù¨ÙùŸÔö•Îù”Îü’ÏþÍüÍþŽÍÿÏÿÐÿ…Èý…Èý‡ÊÿŽÏÿÏÿŒËþÎÿÏÿÏÿŒÎÿÒÿÑÿŽÍÿÍÿ‘ÎÿÎÿÎÿŽÍÿŽÍÿŽÍÿŽÍÿÎÿÌþ’Ìü™Ñÿ›ÕÿÏÿŽÐÿˆËÿƒÈÿ‚Éÿ€Æÿ€Æÿ}Ãþz¿ú{Àù€ÅþƒÈÿ„Éÿ…ÇÿƒÅÿÃÿ‚ÄþÆÿÆÿÆý…Ëÿ†ÉýˆËÿŒÏÿŠÌÿ„Æÿ…ÈýÌù¡ÖøªÛù½ãðÆèòÍòÿÌòÿ¿çÿ°äÿ©Þÿ˜Ñü”ÎüŽÍÿÌÿ‡ÉýŠÉü‹Éú–ÐÿžÔÿ°Þÿ´áÿºäú¿êûÇîÿÄíÿÃëÿ¾èÿ¾èÿ»éÿ³äÿ¥Ùþ¢Øþ—Òü“Òþ’Ñý™Öÿ›ÖÿœÒþÔý¡×ý¤Úÿ¤Üÿ£Ùý£×üªÛü°ßý¼äþÀåÿÉìÿÔôÿÓóþÐòþÎïþÍîÿÍîýÔôÿÜùÿßúÿäüþÞúþÍóÿÅîÿ¸âû²ßü¬Üÿ¥ÖþÑùžÓû¡Öþ¢×ÿœÒÿ•Íü’Ïþ‘ÏÿÌÿ‰Èû‡Éý‰Ëý‹ÏÿŠÍÿŽÎþÏÿÏÿÏÿÎÿÌÿŽÍÿÎÿÎÿÎÿŽÐÿŽÐÿÑÿ‘Ðÿ‘ÎÿÍÿ•Îÿ•Íþ–Ïü›Ôÿ™ÔÿŽÍÿŠÉþˆËÿÆÿ€ÄÿÇÿ‚Çÿ€ÂüÂù‚Åü„Éÿ‡Éÿ…Æþ…ÆüŠÉþŠÉþ…ÆüƒÆý‚ÇÿƒÈÿ„Åû‡Èþ…Èý‡Ìÿ‡Îÿ€Çý„ÊþÏÿ–Õÿ›Øÿ©Ûü°ßýµäÿ´ãÿ·æÿªßÿ¤Ùÿ•Ðü“ÐýÌÿˆÊþ‰ËÿŒËÿŽÌý˜ÒÿžÔÿ²àÿ¶ãÿ¹æû¿êûÂëýÆïÿÆîÿ¿éÿ»çÿ»éÿ´âÿ¦Øý¢Öý™Óû—Ôÿ•Òþœ×ÿž×ÿžÕü Öü¤Øý§Ûÿ¦Üÿ¤Øý¤Øý®ßÿ³àÿ¼äþ¿äþÆéÿÑñÿÑñþÍîÿÌíÿÈëþÈëþÑñÿÚöÿÜ÷ÿàùþÜùÿËñÿ¿èü³Ýö¯Üù¬Üÿ©Úÿ¤Øÿ¥Ùÿ¦Úÿ¦Ûÿ Öÿ—Ïþ”Îþ“ÐÿÍþËü‹ÊýÍýÏÿŽÍÿÍüŽÎüŽÎüŽÎþ‹ÍÿŽÍÿŽÍÿÎÿ‘ÏÿÎÿÌÿŽÍÿ‘Ðÿ’Ðÿ‘Íÿ‘Íÿ”Îþ–Ìú™ÏûŸÖýœÖþÍþŽÌÿÎÿ„ÆÿÆÿ‚Çÿ‚ÇÿÃýÄûƒÆý†Ëÿ†Èÿ„Åý†ÇýŽÍÿŽÍÿ‰Êÿ†ÉÿƒÈÿ„Éÿ…Æü†ÈüƒÆúˆËÿ‡Íÿ‚Èü†ÉýÍý’Ïû–Ñý¢Øü¤Ùû¥Úü¥Úü«àÿ•Îû•Ïý‘ÎýŒÊû‡Éý‡Êÿ‡Êÿ‹ÍÿÎÿ–Óÿ›Ôÿ­Ýÿ±âÿºêÿ¾ìÿ¼éÿ¼èÿ¾êÿ¶âý³ßø³ßø·äÿªØü¦ÖüŸÓúŸÖýžÕü¢Øþ£Ùý§Ùú¨Ûú¨ÙúªÛüªÛü«Üý­Þÿ±ßÿµâÿ¿èÿÂêÿÃèÿÈëÿÇêþÅèþÅçÿÃçÿÃçÿÉéÿÑðÿÒïÿÕñýÕõÿÄêý¹âø²Üõ±Þû¯Ýÿ­ßÿ¯áÿ­ßÿ¬Þÿ«ßÿ Õÿ™Íü›ÑÿžÔÿ Öÿ ÖÿŸÕÿŸÕÿ›Ñý˜Îú“Íû‘Ïþ‘ÏþÐÿŽÐÿ‹Íÿ‹ÍÿŽÍÿÍþÌþÎÿÎý‘ÎýÍü™ÑÿžÔÿ Õÿ¤ØÿªÜÿ«Üý¥×úœÓü—Ðû”ÎþÊÿŒËÿ…Èÿ…Èÿ…Èÿ…Èý„Çü†Éþ‡Êÿ†Çý‡ÉýÌÿÌÿÎÿŒÍÿ„Æÿ‚ÄþƒÄúŠÉþŠÉþˆÊþ‰ÈýŒËþŽÌý‘Îý”Íú•Îù™Ôÿ—Ôÿ”Ñý’Ïû’ÏûÉùÍüÍþŠÉü†Éþ‰Ìÿ‡ÊÿŒÎÿÎÿ“Ðÿ—Ñÿ¦×ÿ¬Þÿ·éÿ¼ìÿ¸æþ¶âý·ãÿ´àû²Þ÷³ßø¹äÿ®Úý«Ùý¤Öù£×ü£×ü§Ùú¨Ûú«Üú®Ýù°Ýü±Þý±Þý²ßÿ´áÿ²ßþµáþ¾çÿÁèÿÁæÿÇëÿÇêÿÆèÿÅéÿÅéÿÅéÿÅèþÎïÿÏîÿÑîþÑòÿÅëÿ»äú²Üõ¯Ûø«Ùû®Þÿ®Þÿ¬Üÿ«Ýÿ«Ýÿ¦ÚÿŸÒý¢Öþ¥Ùÿ¦Úÿ«Üÿ¬ÝÿªÞÿ¥Ùÿ¡Òú“Ì÷‘ÎûÎýÏÿŒÎÿ‹Íÿ‹ÍÿŽÍÿÍþÌþ‘Îý’Ïþ’Ìú’ÌúÓÿ£Øÿ§Øÿ®ßÿ³áÿ³àý­Üú£×üŸÓú—ÍûËýÎÿŠËÿ‰Êÿ‰Ìÿ‰Ìÿ†ÉþˆËÿŠÍÿŠÌÿ‰ËÿÌÿŒËÿÎÿ‹ÌÿƒÅÿƒÄþ‚Ãù‹ÊÿÌÿÎÿŽÍÿŽÌýÍþ‘Îý”Íú•Îû‘ÏþÐÿ‘ÑÿÐÿŽÎþ‡Æû†Åú…Æü†Çý…Èý…Èý‹ÎÿÑÿÏÿŒÊùÊ÷™Îø Öü®ãÿ±æÿ¬Ýý­Ûý®Üþ¶âÿ¹åÿ»çÿ½æÿ¶ßÿ´ßÿ±Þý°ßýµäÿ¶äþ¸æþ½êÿ½êÿÁëÿÁéÿ¿çÿ½äÿ¿æÿ¿çÿ½çÿ¼äþ½äÿ¿çÿÃéþÄèþÄèþÅéÿÆêÿÇëÿÆêÿÍðÿÏóÿÎïþÎòÿÅîÿÀèÿ³ßú²Þû´áÿµãÿ±ßÿ¯Ýþ°ßý°ßý±ßÿ¯Üûµáþ¸äÿ»åý¼æþÁëÿÃíÿ½çÿ¶àøŸÕûšÕÿ–Óÿ‘ÑÿÏÿŒÎÿŒÎÿÎÿÎÿ‘Îý”Îü—ÒþœÒþœÓü¦×ÿ«Ûÿµâÿ½çÿÂèÿÈìÿÆìÿ¹åþ´àý¨ÙúÒü›ÔÿÍþŽÌÿŽÍÿ‹Íÿ†ÈúŠÎÿ‰ÍþˆÊþˆÊþ‹ÍÿŒÍÿ‹Ìÿ‡ÈÿƒÄüŠËÿ†Éÿ‰Ìÿ‰ÌÿÏÿÏÿ‘Ïÿ’Ðÿ’ÎÿÍþÎÿÏÿŒÏÿŒÏÿŒÏÿ‰Ìÿ†Çý‡Èþ…Èÿ„Çþ‰ÌÿÐÿŒÎÿÌÿÍþŠÈ÷ˆÅò˜ÎúžÕþ¦Üÿ¦Üþ¤Ùû¦ÖúªØü¹æÿ»éÿ¾êÿ¿èÿ¹âÿ¶ßý³ßü·ãþ¼èÿÀíÿ¼éþÄïÿÆñÿÃìÿÂçÿÀåÿÀåÿÅêÿÂçÿ¿çÿ¾æÿ¾æÿ¿çÿÉïÿÈîÿÇíÿÈíÿÉíÿÈíÿÉîÿËðÿÍòÿÎòÿÌòÿÃìÿÀèÿ´àû²Þû´áÿ±Þÿ±Þÿ¶ãÿ¹æÿ»éÿ»éÿ¼éÿ¼åû¾çûÊïÿÉîÿÏôÿÐõÿÇìüÁèù«àÿ›Öÿ˜Õÿ‘ÑÿŠÌþŒÏÿŒÏÿÏÿ’Ðÿ’Ïþ–ÎýœÕÿžÕþŸÕû«Ûÿ¯Ýþ¹ãüÈîÿÎñÿÎïÿÊíÿÆìÿÂëÿ²Þû£ÕúŸÔü“ÍûŽÌýŽÍÿÌÿŽÐÿ‹ÍÿŠÎÿˆÌý‡Ëü†Èü‡Èþ‹Êÿ‰Èþ‡ÆüŒÍÿŠÍÿŒÏÿÐÿÏÿÎÿÌþ’Îÿ‘ÏÿŽÍÿÏÿÏÿ‹Íÿ‹ÍÿŽÐÿÎÿˆÍÿ„Éÿ‚Çÿ‰ÌÿŽÏÿŒÍÿÎÿ‘Ïÿ“ÐÿÍúÌù‘Îû•Ðü˜ÓûšÔúœÓú Ôü§×ÿµâÿ¸åÿÁîÿ¾æÿÁéÿÂêÿÄìÿÇðÿÉïÿËñÿÆìÿÉðÿÊïÿÇìÿÄèþÅèüÈëÿÉìÿÍðÿÉîÿÁåûÁåûÆìÿÆíþÆíüÇîýÊïÿÊíÿÈìüÊîüËñþËóÿÆîøÄìøÃìÿÃíÿºæÿ¶âý³àÿ´áÿ²Þû¶âý»åþ¼åûÅïÿÎóÿÑóýÐòûÕôùØõûÝüÿÞýÿÕöýÎðù²ãÿ™Óû•ÐúÍýŒËþ†Éþ‡Êþ‹Íÿ‘Ïÿ”Îþ˜ÑþšÓþ Õý¥Ùþ·äÿ¹åþÄêýÖöÿÙ÷ÿÜ÷ÿÝøÿÛøÿ×÷ÿÇìÿ±Þû«ÜýšÐü“ÍûÍþÍýÏÿŽÐÿŠÌþˆËÿ‰Ìÿ‹Îÿ†ÇýˆÇü‰ÈýÎÿ’Ðÿ‘ÓÿÎÿŽÌý’Ìú–Ïü•Îû”ÎüÎÿ‹Íÿ‹ÎÿÏÿ‹Êý‡ÆùˆÇüŠÉþ‚ÈÿÇÿƒÈÿ†Éÿ‹ÌÿŽÍÿ‘Ïþ”Ñÿ˜Óÿ—Òü•ÒþÏÿÍüŽÍù‘Îú–ÑýÓÿ¢Õÿ®Üþ°ÝúºçüÁêÿÄíÿÃìÿÄêýÊïÿÍòÿÊïÿÉìÿÉìÿÇìþÉîÿÈëþÊîþÏðÿÏïþÍíüÍîýËïýÉíýÆëýÆìÿÆíþÊïÿÌïÿÍîÿËìýËïÿÎóÿÎõÿÅïýÂìü¿èþ½çÿµáü¶âý¼èÿµáþ´Ýùºâû¿èþÃéüÈìüÖöÿßüÿàûÿåþÿäýÿæÿÿäÿÿÛùÿÒóü°ßý˜Ïö’ËöŠÊú†Èú…Èý‡ÊÿŽÍÿ‘Îý”Îþ›Ôÿ›Ôÿ¤Øÿ¬ÞÿºèÿÀêÿÎòÿÝúÿàùÿâúþæûþéÿýçÿÿØøÿÀæýµáþ¡Õü˜ÏøÍüÍûŠÌü‰ËýŠÌÿŠÍÿŠÍÿ‰ÌÿŒÎÿŠÉþŒËþ˜Õÿ™Ôÿ˜ÑüÔû Öú¦Öú¦×ø£Ó÷ Ò÷–ÏúÎÿÏÿŽÐÿŠÍÿƒÆúƒÄú…Æü€Æÿ‚Èÿ„Éÿ…Çÿ‹ÊÿÎÿ’Ñý–Óÿ™Ôþ™Ôþ—ÔÿÏÿŽÎþŽÌûÏû–ÓÿžÔÿ¢Õÿ«Ûÿ®Ýù·äù¿èüÄíÿÃìþÅëþÍòÿÍòÿÊíÿÊíÿËîÿÉîÿÉîÿËïÿÌðþÐòþÑñþÖöÿÖöÿÐòþÌíüËïÿÆìÿÆìÿÉîÿËîÿÌíÿËìÿÌíÿÌñÿÌñÿÃìþÀéû¿çÿ¾èÿ·ãþµáü¶âÿ·ãþ¸âû½æüÁêþÉîÿÌíþØõÿÞùÿâûÿèÿÿàøüßøýÞùÿÚøÿÔòü·äÿÒú•ÎùŠÊú…Çù†Ìÿ‰ÏÿÏÿÍü•Íü™Òÿ™Òÿ¦Úÿ­ßÿ¹çÿÀëþÑóÿßúÿãüÿéþÿìÿÿíÿüìÿÿàüÿÇëÿ¼æÿ£×üšÑú“ÐýÏý‹ÍýˆÊü‹Íÿ‹ÎÿŠÍÿ‡ÊÿÏÿŠÉüËüšÔÿžÕþžÔú¬Þÿ³äÿ¹åÿ·ãÿ¯ÛøªØùœÑù’ÏüÏÿÐÿ‰Ïÿ„Êþ„Çü‚Åü~ÄÿÅÿ€ÅÿÃý„ÅûˆÇü•Óÿš×ÿœ×ÿÖÿØÿÏÿŒÎÿŽÎþ‘Ñÿ™ÖÿŸÕÿ¡Ôÿ¯Ýÿ²ßü¸âøºã÷ÅîÿÉïÿÅêúÊîþÊîþÆéüÉìÿÐñÿÎïÿÑóÿÔöÿÖöÿ×õÿÙ÷ÿÞûÿáþÿàþÿ×÷ÿÇëùÈìÿÅëÿÅéÿÇêÿÉéþÉéþÌïÿËîÿÉîÿÁçú¾äù½çÿ»åþ¶ßûµáü½éÿÁëÿÄìÿÇíÿÈîÿÒöÿÖöÿ×ôÿÔðüÖñüàøÿáøÿÝõÿÛöÿÚöÿÕòÿ»èÿžÒù–ÍôÎúÐÿÓÿ’Õÿ•Ôÿ‘Îý“Íý‘Éø”Íú¦Ûÿ­ßÿ¸äýÂëÿÒôÿÞúþäýÿëÿÿìÿýîÿùìÿýåþÿÎïÿÃéÿ«Üü¡Õúš×ÿ–ÕÿÏÿÎÿŽÍÿ‹Íÿ‹Íÿ‹ÎÿÐÿŒËþŽÌûœÖþ¨Üÿ©Øô½çýÊðÿÔõÿÓóÿÏðÿÆêÿ°ßýŸÖÿ–ÓÿŠÍÿ‰Ïÿ‡Ìÿ„Éÿ|Ãû|Äÿ}ÅÿÅÿ}Ãþ~Ãü€ÅüÐÿ—Öÿ™×ÿ™Óÿ’ÏþŠÎÿŠÎÿŽÎþŽÎü™Óÿ£Øÿ¨Ùÿ´àýºäý¼åû½åþÄêÿÆëþÊëúÎïÿÍñÿÄéüÇêþÑðÿÓðÿÚõþÜ÷þØõûÛøþÜùýçÿÿçÿÿàýÿÛùÿÉíýÃçÿÄèÿÁçþÀäúÇìÿÌñÿÍòÿËïÿÊîüËìûÆéü¾åÿ¾åÿºâüºäýÁëÿÈñÿÆïÿÆíþÊñÿÎòÿÖ÷ÿÏïúÐñÿÏóÿ×÷ÿàüÿÞùÿÞùÿÚöÿÖôþ¹åÿ£Õú™Íô’Í÷‘Îú’ÒÿŽÐÿ‘ÑÿŽÌýŽÌý’Ìü”Îü¡Øÿ¥Ùþ¶ãÿÂìÿÔõÿßúÿåýÿìÿÿéüúðÿüðÿÿèýÿØôÿÑòÿ»äÿ«Üü›Õýš×ÿÐÿÎÿÍþÎÿÏÿŽÑÿŠÐÿ‹ÍÿÏûŸÕû·æÿ¶âûÇîÿÓ÷ÿâýÿãüÿÝøÿÓðþ·áù¦ÜÿšÕÿŒÌü‹ÍÿˆËÿ„Çü~Ãü|Äÿ|Äÿ|Äÿ|ÃÿyÁüw¿ùÄýƒÆý†Åû‹Èþ‹Éü‰ÍüŒÎþÐÿÎý—Ðý¥Ùÿ­Þÿ¶âý»åýÅëÿÉïÿÈëÿËìýÒðûÒòÿÎïÿËîÿÌïÿÓòÿ×ôÿÞõûåýÿãÿÿåÿÿæÿÿèÿÿçÿÿäýÿÞûÿÎïÿ¿äþ½äÿ¾èÿ¿éÿ¿éÿ¾èþÄíÿÃéüÅêüÌðþËðÿÅêÿÄéÿÁçþÂèÿÉïÿÆìÿÂèûÃìþÈòÿÉðÿÐòþËïÿÃìÿÁêÿÊïÿÎïÿ×óþÛöÿÛøþÙöþÊóÿµâÿªÛûŸÕùœÔù‘ÏøŽÍø‘ÏþÍþËýÍü’ÏüœÕÿ¡Öþ²áÿ»çÿÎòÿÖóûÝöûéþÿëÿþíÿÿíÿÿéüÿÞöÿØõÿÇíÿ¹åÿ£Ùý×ÿŽÍù“Ðÿ‘Ëù–Ðþ—ÑÿŽÎüÌÿ‘Ñÿ”ÑýŸÓø»çÿÇíÿØúÿàþÿæÿÿèÿÿäýÿÛ÷ÿÄêÿ¬Þÿ¢Øþ“ÑÿÏÿ‡Éý†ÉþƒÈÿ|Äÿ{Ãþ{Ãþ|Ãÿw¿út¼÷zÀû}ÂûÂúˆÇý‰ÈýˆÌûŠÌüŽÎþÍü˜Ñþ§Ûÿ°áÿ»äÿ¿çÿÊðÿÊðÿÍîÿÐðýÙõÿ×õÿÎîýÎïÿËïÿÏïþÔñÿãúÿèÿÿæÿÿâÿÿâþÿêÿÿêÿÿæþÿßúÿÐðÿ¾æÿ¹åÿ¹åÿ¼èÿ»çÿ·ãþ¼æÿ¿èüÄêýËðÿÊïÿÇëÿÇëÿÃèûÃéüÉïÿÅëþÀæùÂëýÈñÿÅïÿÈíýÇíÿ¾èÿ»åþÆêÿËìÿÖòýÜ÷ÿßúÿÝøÿÎóÿ¾èÿ¶äþ«Þý¥ÚúœÖü™Ôü—Ôÿ‘ÍÿŽÊüËýÌû™ÒýžÓû¯Ýþ¹åÿÊïÿÔòüÙôûæþÿêÿÿìÿÿíÿÿèýÿß÷ÿÛ÷ÿÊïÿ¾èÿ©Þþ¢Úý”Ïù”Ñþ“ÎúÓÿŸÕÿ•Ðü‘Îû—Ôÿ™ÔþžÒ÷½éÿËðÿÝûÿàýÿâûÿäýÿÜøÿÕõÿÄìÿ²ãÿªÞÿ˜ÖÿÑÿ‡ÉýˆËÿ…Êÿ|Àý|Âþ~Äÿ~Äÿv½ûsºøu¼úzÀþ€ÄÿÃÿ„ÇþŠÌü‹ËûËúÌùžÔÿ©Ûþ±ßÿ½åÿÃéÿÌïÿËïÿÚöÿáüÿèÿÿâûÿÞúÿÖöÿÐòþÎîûÔòýàùþæÿÿåÿÿÝùüßøüìÿÿëÿþêþÿäûÿÕñýÀéýµãû­Ú÷°Ýü°Üÿ­Ùü¶áÿÂìÿÈñÿÍôÿÌòÿÔôÿÕõÿÐñÿÌðÿÌñÿÆìÿ¾çû¼åû¿éÿ½çÿ·ãþ³àÿ®ßÿ¯Ýþ½åÿÃçýÓïûÛöÿáúÿÜøüÏí÷ÎðüÌòÿÄïÿ»èÿ¯àþ§ÜþŸÖÿ•Ïý‘ËûŽÍÿŒÌü“ÐüšÔüªÜÿ´ãÿÀéýÒôÿØöÿßûÿåþÿèÿÿêÿÿæþÿßøýÚ÷ÿÊîüÅëþ»éÿ²äÿ¦ÜþŸÙÿ Õý«Ýÿ®ÞÿªÜÿ¥Ùþ¤Ûÿ¡ØÿŸÓø½éÿÑòÿÙ÷ÿÓñüÐðýÏðÿÆìÿÀéÿµâÿ¯ßÿ«Ýÿ”ÒÿŒÍÿƒÄú„Çþ€Åþ}¿û€ÂþƒÇÿÅÿx¿ÿw¾þv½ýw¾ü}Ãÿ~ÄÿƒÈÿŽÎþÏý”Ñþ–ÑýŸÖÿ­Þÿ³àÿÄêÿÉîÿÏðÿÖôþäýÿèÿÿìÿÿìÿÿëÿÿÚöÿÓñûÓñûØöþÚóøàùþáýÿÛ÷úàøüêþýìÿýìÿÿëþÿß÷ÿÎóÿÅîÿ½åþ¼åÿ¹âÿ¶ßÿ»âÿÅéÿÊîþÓõÿÓôýÚ÷ÿÛùÿÕõÿÐòþÊîþÇíÿÁçþ³Ýö´Þ÷²ßü¯Ýÿ Ôû¡Õü£×ü±Þý¿äþÑíûÙôÿâûÿàùþÛ÷ûÚ÷ûÚùþÔöÿÍñÿ¾èþ³áû¥×üšÐþ”Ìû“ÓÿÐÿ“Ðý—Òü¤Ùû­ÞþºäüÌðÿÑóÿÚøÿâÿÿæÿÿèÿÿæþÿÝöúÚóøÔòüÐòþÉïÿ¾èþ³âþ¬àÿ®Þÿ²Þû³ßúµáþ´âÿ©Ûÿ¡ÕüœÒø¸æÿÆìÿÅèþºà÷µãû²áýªßÿ¢Øü›Óø¡ØÿžÕþÊÿˆÉÿ„Åý„Æÿ‚Çÿ…Æÿ„Æÿ€Åÿ~ÄÿzÁÿx¿ýw¾üzÁÿÅÿÅÿƒÈÿ‘Ïþ”Òÿ•Òÿ—Òþ¡Öþ°Þÿ¶áÿÄêÿÊïÿÖøÿÖôüæþÿéþÿîÿÿëÿÿçüÿÛöÿÖóûÕòø×ôúßøüÛôùÜøüäÿÿçÿÿëÿþìÿýìÿÿìÿÿàøÿÎðüËïÿÆëþÄèÿÂåÿÁäÿÆèÿËìÿÑñþÖôüÑï÷ÙöüÛùÿÑñüÏñýÊîþÇíÿÅëÿ¹ãüµÞú±ÞýªÚþ¡ÕüŸÔü Ôû°Ýþ½âýÒïÿ×óÿÛöýÝøÿÝöúâþÿßûÿÙ÷ÿÖöÿÉïÿÁëÿ¬ÝþÓÿ–Îý‘Ïÿ“Óÿ˜Õÿ˜Óû¢×ù©ÚúºäüÉíýÎïþØöÿÜùÿäÿÿèÿÿèÿÿáùûÝöúÚ÷ÿÓóþÈíýÆìÿ²àø¨Úû®Üþ¼åÿ¹ãü¶ßû¼éÿ¥×üžÒùÓù¯áÿ½æÿ¹âþ±Þû¨Ýý¡ÙüžÙÿšØÿ’Ïû•Òÿ—Ñÿ‰Èþ†Çÿ‰ÊÿˆËÿ†Éÿ„Åý„Åý‚ÄþÄý}Ãþ}Ãþ€Æÿ‚Èÿ…ÊÿƒÈÿ‰Êÿ’Ïþ•Òÿ˜Òÿ™Òý Ôû¯Üý¶ßûÃèûÉíýÔõþÛúÿëÿÿíÿÿóÿýîüýìûÿâùÿßøýáúþäþÿçÿÿåþÿáýÿàüÿäýÿéýüêþýëÿÿåüÿÙõÿ×õÿ×õÿÖóÿÔôÿÔóÿÔôÿÖóÿÚôÿÝõÿßöþÜõüÔòüÔòüÊê÷ÈéøÄçúÇíÿÅîÿÀéÿºæÿ¶ãÿ¶äÿ«Ýÿ£×þ¢Öý°Ýþ¿çÿÑòÿÙöÿÛùÿÜúÿÞùÿáúÿàùþàûÿÝúÿÒóÿÉïÿ´ãÿ¢×ÿ›Ôÿ‘Îû”Ñý˜Óû›Òù¨Úû°ßû½æüÉíýÎðüØöÿÜùÿàüýãýþæþþêÿÿèÿÿäÿÿàýÿÔöÿÌðÿºàõ±Ýø¯Ûö·ßø¸àú¶ãÿ®ßÿ ÕýŸÖýŸÔüÑø¡Õü¢Ùÿž×ÿ•Ôÿ‘ÑÿŒÐÿÓÿŽÑÿ‹Íÿ‹Êÿ„Åý…Æÿ‹ÌÿŠÍÿ„Çü†Çý†ÇýƒÆý‚Åü€ÅþÆþÈÿƒÊÿ†Ëÿ‡Êÿ‹Ìÿ“Ðÿ–ÓÿšÓÿ›Ñý Ôû°Ýü·áúÅèûËìûÖôþÝúÿëÿÿîÿÿôÿþòüýïýÿéüÿåýÿçÿÿéÿÿèÿÿçÿÿâþÿÝúþáýÿéþÿëÿþèýÿàùþÕòÿÚöÿÚöÿÚöÿØöÿ×õÿ×õÿÚöÿÜ÷ÿßöþáõþÝôüÔôÿÓóÿÊëúÆêúÅêýÃìÿÂìÿ½éÿ»çÿºæÿ¹æÿ¯àÿªÜÿªÜÿµâÿ¿çÿÐñÿÖõÿ×÷ÿ×÷ÿÜøÿÜ÷þßøÿàûÿÞùÿÒóÿËðÿ¶ãÿ¢×ÿ›Ôÿ™ÔÿšÕÿ›ÕûžÔø«Üü²áû¾çûËìýÎîûØôÿÛøþàüýáûüãûûèýþéþÿåþÿàûÿÕõÿÏðÿÁæù¹ãû¶àù¸âú¸âû³áÿ¨ÜÿœÖþ×ÿŸÖý˜Íõ™Ïû™Óÿ•ÒÿÏÿÏÿ‡Íÿ‹ÑÿŠÐÿ‡Êÿ†Çý…Æþ…Æþ‹ÌÿŠÍÿ„ÇüÏÿÏÿˆÊþ„ÇüƒÉý…ËÿƒÉý†ÉþŠÌÿÌÿ‘Ïÿ•Ïý˜ÒÿÓÿŸÔÿ§Øÿ·ãÿ½åÿÈìüÎðüÙ÷ÿÛøþêÿÿíÿÿ÷ÿÿøÿÿöÿÿòÿÿïÿÿìÿÿìÿþèýþæþÿàüÿÛøüàüÿèÿÿçÿÿßøý×ôüÍîÿÓðÿÕñÿÙ÷ÿÛùÿÝüÿÝüþÜúüÞúþàùÿã÷ÿÝôÿÒöÿÑòÿÊíÿÄéûÂèûÃìÿÀêÿ¹åþºæÿ¾ëÿ½çý¸äý²áÿ­Þü´áþ»ãýÄçûÉêýÊíÿÉîÿÐðÿÓñüØôÿÚõþØóüÒòÿËîÿ´áþ¢×ÿž×ÿœÖþžÕü¡×û§Ùú¶ãÿ»çÿÇìÿÐðýÔðüÛöýáúÿäþÿåýÿçüýéýþêþÿäûÿßøÿ×õÿÒòÿÐóÿÈîÿÄíÿºæÿµâÿ¢ØüŸÙÿ–Õÿ”Óÿ ×ÿœÓü“Ñÿ‹Êÿ‰Èý†Èú‰ËýŒÎÿŒÎÿ‡ÊþˆËÿ†Éÿ‡Èÿ†ÇÿˆËÿ‰ÌÿˆÌýÏÿÏÿˆÊþ„Çû†ÉýŠÍÿˆËÿŠÌÿÍýÍþ“Ðÿ–Ðþ™ÑÿÓÿ Õÿ¬Üÿ¸äÿ¿çÿÉíýÏñýÙ÷ÿÚùþèÿÿíÿÿ÷ÿÿøÿÿöÿÿóÿÿïÿÿíÿÿëþúêþÿåýÿßûþÛøüßûþçÿÿäüþÚõüÕóýÌïÿÏîÿÓðÿÙ÷ÿÛùÿÛýþÜþýÚúùÜøüáùÿâøÿÛõÿÎóÿÍðÿÈíÿÁçú¾äùÁêÿ¿éÿ¸åü¸åü¼æü½æø»åû¶åÿ²áý¶âý¸âû¿âøÁäøÄéüÅêýËìÿÒïÿØôÿÖñüÕðûÒïýÉìÿ±Þû ÖüÖÿ¡Øÿ£Ùÿ§Üþ¬ßþ¼èÿÁëÿÌïÿÕóþ×óþàùÿåüÿéÿÿëÿÿéýþåùúäøùÞõûÜõüÙ÷ÿÕõÿ×úÿÌñÿÈîÿ¸äý±àþšÔú—Ôÿ“ÓÿÐþœÖþžÕþ—ÕÿŠËÿ‰Ëÿ‰Èû‹ËûÏÿŽÎþˆÊüÏÿ‰Êÿ„Çþ„ÇþŠÍÿŒÏÿŠÎÿ‘ÏÿÎÿŽÎþŽÍÿŒÎÿŒÎÿÏÿŒÎÿŽÍÿÏÿ‘Ïÿ•Ðú˜ÑüŸÖý Öü«Üý¾çÿÇíÿÒñÿÕòÿÛöÿáúÿëÿÿïÿÿ÷ÿÿöÿüôÿûñÿÿîÿÿèÿÿçÿÿâþÿÞúûÜøùßùúãûýâúþÞ÷üØôÿÒñÿÉìÿÐñÿÑóÿÒôÿÕ÷ÿØúÿÕ÷ÿÕöÿ×õÿØöþÜùÿÛùÿÎóÿÈïÿÁçú¼åùÁëÿ¼èÿºæÿ·äÿµâÿ°ßý«Þû¶éÿ´åÿ²áý´àûºãÿºâüºâü»åþ»äÿÈìÿÍðÿÐóÿÎõÿÉòÿÀïÿ¹éÿªÜý¡Öþ¤Ùÿ©ÝÿªÝü°ßû·ãüÇíÿÌðÿØöÿÜõüßøýèÿÿéþÿèýþéþÿêÿÿæûþáùýÝöýÛöÿÛ÷ÿÚöÿÒòÿÏñýÃêû¶âý¯ÝþŸÔþšÐþ”Îü•ÏýžÕþžÕü™Òÿ•Ïý’ÏþÎÿÌÿÌÿÌÿÌÿÎÿ‘ÍÿŠÊú‰ËûÏÿŽÐÿÏÿ’Îÿ‘ÍÿÍþÍý‹Íÿ‹ÍÿÏÿŒÎÿÌÿÎÿÎÿ”Ïù—ÐûžÓû Ôù°Þÿ¼æÿÆêÿÐïÿÕòÿÞöÿåýÿìþþïÿþöÿÿøÿüõÿüñÿÿíÿþæþþäýÿáÿÿßûüÝúøâúúçüýåýÿàùÿ×ôÿÑðÿÆéÿÊëúÍïûÑòÿÔõÿÑòÿÉíýËïÿÎðüÒòýÖ÷ÿÕ÷ÿËòÿÆìÿ¾çû»åû½éÿºçÿ¸åÿµáÿ´àÿ®ßÿ©ßÿ¬âÿ¬ßþ¬Ýý´àýµÞü¶ßý¸áý¹åÿ»çÿÅéÿËîÿËñÿÃðÿÀïÿ¸êÿ±äÿ¥Úü¢×ÿ¤ÙÿªÜÿ«Þýµãý½çÿÊïÿÏðÿÚõþÝöúáùûêÿÿéþÿêþÿêþÿêÿÿæþÿäýÿÙôýØóüÙõÿØöÿÒòÿÎòþÄêý¶ãÿ±ßÿ£Öÿ›Ïþ”Ìû•ÎûžÕþ ÖüŸÔüšÐü–Ïü’ÎÿÌÿÎÿÎÿÍÿ‘Îý“ÍûÌøÎú’Òÿ‘ÑÿÎÿ’Îÿ’ÎÿÎÿÎÿÏÿŽÐÿÏÿŒÎÿÌÿÌÿÎÿ•Ðü™ÒÿŸÔþ¢ÖýµãÿÀêÿÈìÿÒòÿ×õÿãüÿìÿÿîþþïýýôþýøÿþ÷ÿýôÿÿïÿþçüýãûÿàüÿßûüâüýçÿÿéþÿãûÿÞ÷üÕóþÏïþÆéýÐñÿÏñýÉíýÈíÿÇíÿÃéÿ»äú¿åüÃéþÈîÿÆïÿ¾èÿ¸äý³ßú¯Ý÷¯Þü¯àÿ¬ÝþªÚþ©Ùý£×üžÔøÕú£Ùÿ¥Ùÿ¤Öû£Ó÷¬Ùú±Üüºãÿ½çÿÊëþÎïÿÈíÿ»åû¹åþ¯àþ¥×øœÐõ£×ÿ¤×ÿ¦Ûý«Ýþ»èÿÁíÿÍòÿÒóÿÛöÿäüþèýÿëÿþêþýíÿÿìþÿëÿÿåþÿáüÿÕñýÐíûÍîÿÎïÿÇìÿÁêþ¶âý­ÞÿªÜÿ ÕÿžÔÿšÐüÒú©Þÿ¯áÿ¬Ýþ¤Øý ÕýšÓÿ–ÐÿËýËýÍü•Îû˜Ñþ›Õý×ÿØÿšÕÿ“Ðÿ”Îÿ”Îÿ’Îÿ’Ðÿ“Óÿ”ÔÿŽÐÿÎÿÎÿ’Ðÿ“Ñÿ˜ÒÿÕÿ¨Ýÿ©Ýÿ³áÿ¿éÿÈíÿÑñüÖôüãüÿêýÿñÿÿõÿÿöÿÿöÿü÷ÿÿõÿÿñÿÿìÿÿêÿÿâûÿßøüáúþçÿÿéþÿäüÿßøýÖóûÒðûÊëúÍïûÍîýÈíÿÄíÿºæÿ³àÿ¬Úü©Úû«Üý¯Ýþ¯Ýþ¬ÝþªÛü­ÞÿªÜý¨Úýªßÿ©Þÿ§Ýÿ¥ÛÿžÖûÔû•Ï÷—ÒþšÔÿœÖÿÓÿ«Ýÿ³áÿ¾èÿÅêÿÏðÿÍðÿÇíÿ·ãÿ´áÿ¦×ÿÑùšÏùŸÖÿœÓú Öú¥Úü´ãÿºæÿÌñÿÔõÿÜ÷ÿèýÿëÿÿëþüíÿþïÿþîÿÿëÿÿÜ÷ÿ×óþÍîÿÄçû½åþ»åþ°Üù®Üý£×ü¡Öþ ×ÿÓÿ Öÿ¢Öý¨Úý¸çÿ½ëÿºæÿ´áþ®ßÿ¨Üÿ¤ÙÿÖÿÖÿÓÿžÓû£Øÿ«Ýÿ¬Üÿ¨Üÿ¤ÙÿœÒþ”Îþ”Îþ’Ïþ‘Ïÿ‘Ñÿ’ÒÿÏÿŽÍÿÎÿ“Ñÿ“Ñÿ–Ðþ™Ñÿ§ÜÿªÞÿ³áÿ½çÿÆëþÒòýØöþåþÿêþÿñÿÿõÿÿöÿÿ÷ÿÿ÷ÿÿõÿÿòÿÿìÿÿêÿÿäüÿàøüáùýéþÿéþÿåýÿàùþØõýÕóûÎðúÐòþÐñÿÇíÿÃíÿ¶åÿ®ßÿ¤Õý Öü¡×ý£×þ£×þ¢Öý¢ÖýªÞÿ«ßÿ©Ýÿ©ßÿªàÿ¨àÿ¥ÝÿÔûžÕþ—Ðý“Ðÿ”Ðÿ•Óÿ—Ñÿ§Üÿ±áÿ¾èÿÆìÿÎòÿÊðÿÄìÿ¶âÿ±ÞÿŸÒÿ˜Îü˜ÑþšÕÿ—ÒúœÔù¢×ù±âÿ¸æÿÊïÿÒóÿÜ÷ÿèýÿëÿÿëþüîÿÿïÿþíÿÿêÿÿÛ÷ÿ×ôÿÊíÿÁçþ¹åÿ¶ãÿ©Úû¤ØýÔûžÔÿž×ÿžÔÿ ×ÿ§Ùü­Þþ¿ìÿÄïÿÄíÿ½çÿ¶äþ®ßÿªÜÿ Õÿ ×ÿŸÔü£×ü¨Üÿ´âÿ³àÿ­Þÿ«Ýÿ Õý–Ðÿ•Ïÿ‘ÎýÍüÏÿÏÿŽÎþÍýŽÌÿÎÿ‘Ïÿ“Íý—ÏþŸÔþ¥Ùÿ²àÿºäúÃèúÑòûÙøýëÿÿîÿÿôÿÿôÿÿöÿÿ÷ÿÿ÷ÿÿòÿÿðÿÿëÿÿêþÿãøýãøýåúÿèýÿçüÿåýÿãüÿÜøüÙöüÚøÿÔöÿÎòÿÀéý¹åþªÜÿ¤Øÿž×ÿ˜Òÿ—Ñÿ”Ïû‘Ìø˜Ñþ›Ôÿ£Úÿ¨Ýÿ­ãÿ¦Üÿ¡Øÿ¡Ûÿ¡Ýÿ“ÎöÓÿÓÿÌÿÊÿÏÿÍÿšÓþ¥Ùÿ´áþ½åÿ¿éÿ¶ãÿ³áÿ§Ûÿ Ôÿ–Ðÿ“Ïÿ’Ðÿ•Ôÿ”ÓþœÔù¡Öø²àÿ¹åÿÈíÿÎïÿÜ÷ÿèýÿéüÿîÿÿðÿÿíÿÿíÿÿãüÿÚ÷ÿÔõÿÁéÿ¹åÿ±ãÿªÞÿ—Íù”Ìû•Ïÿ—Ñÿ™Óÿ¡Øÿ¥Ûÿ¬Û÷³áùÈïþÌðüÎðüÊîþÄêý´àû¯Þü¤Öù Ôù¥×ü«Ýÿ²âÿºæÿ¼èÿ´áÿ°Þÿ¨Üÿ•Ïÿ•Ïÿ‘ÎýÍüÎÿÏÿŽÎþŽÎþÍÿÎÿ‘Íÿ“Íû–ÏüÒü¢Öý®Ýû¹ãùÂçùÐñúØ÷üéÿÿíÿÿôÿÿôÿÿõÿÿôÿÿõÿÿñÿÿïÿÿëÿÿêÿÿäùüäùþåúýçüÿæûþäýÿäýÿßûÿÜùÿÛøÿØøÿÑõÿÀéÿ·ãþ¦ØýžÓý”Ñþ’Ïþ“ÐÿÍúÊ÷”Îü—Ðý Öÿ¢Ùÿ¦Ûÿ¥Ûÿ¢Ùÿ×ýœØý”Ï÷šÐüžÔÿ”ÐÿÎÿÏÿÍÿšÓÿ£Øÿ¯Ýþµáþµãý±ßÿ­Ýÿ£ØÿÓÿšÓÿ—Óÿ“Ñÿ“Óÿ“ÒýžÔú¥×ú³âÿºæÿÈíÿÎïÿÛöÿâùÿçüÿìÿÿíÿÿìÿÿêýÿßøÿÔôÿÌñÿºæÿ²àÿ©Þÿ¤Ûÿ“ËúÍü’Îÿ”Ñÿ–Óÿ ×þ§Ýÿ°ßùºäúÌòÿÒóüÑòûÎïþÉîþ½çÿ¶äþ§Øù¤Öù§Ùü¬Þÿ±âÿ¼èÿ½éÿµâÿ°Þÿ§Ùþ”Ìý”Ìý’ÌüÍüÍüÍüŽÎþÍþÍþÌþÍü–Ñû™Òý Õý¤Øý¯Þü½çýÆëýÑñü×õýåþÿëýýñÿÿòÿÿñÿÿîüüïýþëýýêþýêÿþêÿþíÿÿìÿÿíÿÿíÿÿêÿÿçÿÿçÿÿäÿÿãþÿÝúÿØõÿÑòÿÀåÿ¶âÿ¢ØþšÓþ’Ïþ–Ôÿ˜Öÿ—Ôÿ”ÑþÍú’ÍùÔý¡ÖþŸÓú ÖüŸÔü˜Òú˜Óû—Òü˜ÏøÓÿ™Ñÿ–Ðþ“Íý“Íû–ÏüœÓüžÒùžÒ÷¦Öú¦Öú¥×üžÓý™ÏûšÕÿ™Ôÿ—Òþ˜Óÿ˜Óý¡Õú§Øù³àý»äÿÈíÿÎïÿÚöÿÞ÷þâùÿèýÿèýÿçüÿÞöúÓïúÈëþ¿èþ¯Ýþ¥×ü›Ôÿ™ÓÿÌÿ‘Ïÿ’Ðÿ”Ñÿ˜Óÿ¡Ùþ©Þþ¹æûÇîÿØøÿÛøþÜ÷þ×õÿÓõÿÇíÿ¼æÿ­Úû«Ùû­Ýÿ¯àÿ¯àÿµâÿ¶ãÿ³áÿ®Þÿ¤Øÿ”Ìû”Ìû“ÍýÍüÍüŽÌûŽÎüÍþÎÿ’Îÿ’Ïþ—Òü›Ôÿ£Ùÿ¨Üÿ³âÿ¾èþÇìÿÑñüÖôüãüÿëýýðÿÿñÿÿïÿþìüüíýýëýýêþýêÿþëÿÿëÿþëýýëÿþìÿÿéÿÿåþÿãüÿßøýÞùÿÝøÿ×ôÿÏðÿÀåÿ¶âÿ£Ùÿ›Ôÿ“Ðý–Õÿ™Öÿ—Òü”ÏùÍú“ÎúŸÖÿ£Øÿ£Õú ÔùžÒù›ÕýØÿ™ÔüŸÖýŸÖýÓÿšÓþ™Òÿ•Îû—ÍùšÐü™Ðù™Ðù£Óù¦Öú¥×úžÒ÷›ÏöžÕüžÕüœÓúÒúžÓû§×û¬Úû¶âý½åÿÊíÿÏðÿÚöÿßøÿßøÿæýÿèÿÿãûÿÝöýÒðûÇëÿ¾èÿªÚþ Ôû–Ðþ“ÏÿÍÿÎÿ‘Ïÿ“Ðý—Òü¢Øü¬ßþ¾èþÊïÿÚøÿÜøüßøýØöþÕõÿÉíÿ½åÿ®Ûü¬Úü®Þÿ®Þÿ¯ßÿ²àÿ±ßÿ¯ßÿ«Ýÿ¡×ýšÒÿšÒÿ˜Òÿ•Òÿ‘ÏþÎýÍüÍþ‘Íÿ–Òÿ˜Õÿ™ÔüžØÿ¨Þÿ¬áÿ·æÿÀêÿÈíÿÏïüÔòüÞ÷üêþýìÿûíÿüíÿþíÿÿëýýêþýéÿýèÿþéÿÿïÿÿíÿþìÿýéþÿçüÿâûÿÞ÷üÛôûÞ÷þâûÿÚöÿÒñÿÁæÿ¶âÿ£×þœÓü˜Õÿ™×ÿØÿ™Óø•Ñö—Òþ›Ôÿ¥Úÿ§ÛÿªÚþ¨Úÿ¨Ùÿ¢×ÿ ÚÿÖÿ¢Úÿ¡×û Öü¢Öý¢Öý¤ØÿœÒþ›Ôÿ—Ôÿ—Ôÿ¨Øÿ²Þÿ³áÿ®ßý¬Þù°âý±ãþ´ãÿ±Þÿ²Ýÿ¸åÿ¹æÿ¾èÿ¿çÿÇêþËìýÑïú×ôüÚõþÞùÿßúÿßúÿÞùÿÓóÿÆìÿ¼èÿ¦ØýÒü“ÍÿÌÿŽËÿ‘Ïÿ‘Îý”Ïû˜Òú£Øú³äÿÄíÿÎòÿÚ÷ÿß÷ûàøüÞùÿÛùÿÌñÿÃëÿ¶ãÿ±ßÿªÚÿ¨ØþªÚþ¬Üÿ¨Úÿ¤Øÿ¢Öý›ÒùŸÔüÔûœÖþÖÿ–Ñý‘ÎúÍùÍù•ÐüšÕÿœÕÿ ×ÿ¥Úÿ­ßÿ±ßÿ¿èÿÈîÿËðÿÐñÿÕõÿÙ÷ÿåþÿéþÿéþÿêÿþéÿýèþüêþüëÿýëÿýëÿýðÿÿíÿÿéýþàøüÜøüÔòüÒðúÍíúÏïüÐðÿÍðÿÉîÿ½çÿ·ãþªÝü¥Úü¡×ýŸ×ü£Ùÿ¡×ûžÔøŸ×ú¢Úý©ßÿ©ßÿ¨Üÿ¦Úÿ¤Øÿ£×ü£Ùý¥Úú©Ûü²áÿ³áû´àû»çÿµáüªÛû¦Øû£Ûÿ¤Þÿ³áÿÄìÿÈîÿÊîþÊëüÅêúÆëûÉîþÍîýËëøÉðÿÆïÿÆïÿÅîÿ¿èþ¿åüÃçýÍîÿÒòÿØöÿØöÿÓõÿÓóÿÑðÿÁéÿ¸åÿ¡Ýÿ™ØÿÏÿÍþ“Íý’Ïü•ÐüšÑøŸÕû¯Þü¹åÿÉîÿÏðÿÚ÷ÿÚöúÝøÿÚöÿÙ÷ÿÑòÿÈíÿ½æÿ¶áÿ¦Öü¡Ôÿ£ÖÿŸÕÿ ÖÿŸÕÿÓÿšÓþ Öü ÖüŸÖý×ÿ–Ñû”ÏùÍù“Îø–ÑûœÖþ×ÿ¡Øÿ¦Úÿ­Ýÿ°Ýþ½çÿÅëþÉìÿÎïþÒóÿ×÷ÿßûÿäüÿåýÿçÿÿèÿþæÿüéÿýêþýëÿþìþþïÿÿíÿÿéüÿÞ÷üÛöýÖöÿÓóþÎïþÌðÿÍîÿÌñÿÈîÿ½çý·ãü­Þü©Üû©Ûü¦ÛýªÜÿ©Ûþ¤Ùûž×õ¢Øú¨Þÿ©Þÿ¨Ýÿ¤Øÿ£×þ¤Øý¥ÚüªÝü¯Þüµãýºäü½æüÂëÿ½æü°Þø«Úø¥Ûý¨àÿµâÿÈîÿÌïÿÕóþÕóþÏïüÍïûÐòüÔòúÒï÷ÎðúÊðûÈïÿÉïÿÁêÿ¾æÿ½æüÆëþÊîþÏñýÏñýÍóÿÐñÿÍìÿ»âÿ±ßÿ›Ùÿ“ÖÿŽÎþÍþ•Íþ”Îü•ÐúœÓú¢Öû²ßþ»åþÉìÿÏðÿÚùþÚõüÜøÿÛ÷ÿÙ÷ÿÏðÿÈëþ¾æÿ¶âÿ¨Øþ¡Ôÿ¡Õÿ¡×ÿŸØÿ›Ôÿ›ÑÿœÒÿ¢Øþ¢Øþ ×þžØÿšÕÿ™Ôþ–Óÿ™Ôþ›Öÿ×ÿ×ÿ¥Úÿ§Ûÿ­Þÿ±Þý¾èÿÇíÿÉìÿÉêûÌíüÏïüÖóûÚõüÝùýáýÿãÿÿçÿÿæÿÿåÿÿçÿÿèÿÿåøþéüÿçûÿÞùÿÚøÿÕ÷ÿÓõÿÎïþËïÿÍîÿËîÿÆëý¾äùºãù¶ãúµáú¸æÿ½éÿ¾êÿºãÿ´âü¬ÞÿªÜÿ¨Üÿ¨Ûÿ¤×ÿ¡Ôÿ¡Ôÿ¥Öþ©Ûÿ¯àÿ¶âÿ¼æþÈîÿÌñÿÎñÿËðÿÀéÿºäý°áÿ°áÿ¼èÿÍòÿÓôÿÛùÿÜøÿÛùÿ×÷ÿ×ùÿßýÿÞùÿÞúþÛ÷û×õÿÖöÿÎñÿÉíÿ¿èþÁêÿÄíÿÆïÿÆðÿÄëüÆëýÃçÿ°Ûû§Ùú™×ÿ‘ÔÿÍýŽÌý’Ìü•ÏýšÔü¢Øþ¨Üÿ·äÿ¼æÿÊíÿÐðÿÚ÷ýÛ÷ûÚõþÜøÿÙõÿÎîûÌíþÁçþ¹ãüªØú ÔüžÑþšÏû›Ðü›ÐúœÑû¡Öÿ¡Öþ¡Öþ ×ÿÖÿœ×ÿœ×ÿš×ÿ›Öÿ›ÖÿœÖþœÖþ¤Ùÿ§Ûÿ®ßÿ²ßþ¿éÿÉïÿËîÿÊëüÌíþÏïüÔòýØõýÚ÷ÿÞûÿßüÿåÿÿâþÿáýÿâýÿåþÿÞõûáøÿàùÿØôÿÕóýÔöÿÒôÿËïýÉíýÊíÿÍñÿËîÿÄéüÃèûÀéýÀéÿÂëÿÌòÿÍóÿÄèþ½åþ±âÿ­Ýÿ©Úÿ¨Ùÿ¡Ôÿ¡Ôÿ¢Óþ¦Öþ©Ùÿ±ßÿ»äÿÃéþÏòÿÓôÿÔôÿÐñÿÉîÿÂëÿ¸æÿµâÿºäüÌïÿÒóÿÜøÿÛöÿÚøÿÖöÿ×ùÿàþÿáüÿäüÿâúüÛöýÚöÿÑòÿËîÿÃéþ¿èþ¿èþ¾éü¾éü¾çù¿èü»ãý­Ûü¥Úü—Öÿ“ÔþÏÿÍþ”Îÿ—ÒþœÖþ¥Ûÿ¬Þÿ¸äÿ¿éÿÌïÿÑñþÚ÷ýÚöúÙôýÛøÿÙõÿÑñüÐñÿÊîÿÀèÿ¬Úû¤Øÿ¢Õÿ˜ËöšÍøžÒúŸÓû¢ÖþŸÔü ÕýžÕþšÓþœ×ÿžÙÿ™Öÿ™Ôÿ—Òü›Ôÿ×ÿ¡×ý¦Úÿ­Þþ¯Üù¹ãûÅëÿÉîÿÉìÿËîÿÊîþÌíþÏðÿÑòÿÖöÿØùÿÚøÿÓóþÑñüÒòÿÓôÿÙöÿÚ÷ÿØõÿÒòÿÑñþÒóÿÑòÿÉíýÆéüÈëþÏðÿÎïþÍîýÎïþÏðÿÏðÿÕõÿÝûÿÝùÿ×óÿÒòÿ½æÿ³ßüªÚþ¨Ùÿ ÓÿŸÒÿ¡Òý§×ý¯Ýÿ¹åÿÁêÿÏóÿÙöÿÛ÷ÿÝøÿÛöÿØõÿÒóÿÇíÿÃéþ¾äùÉêûÎîûÛöÿÛöÿ×óÿ×ôÿÕõÿØöÿÜ÷ÿß÷ûàøüÝöûØóüÔòýÒòÿÍñÿÇìÿÆëþÅëÿÃìÿ½êÿ¹æý­Úù£Õú Öü”Òù’Ñú‘Ïþ“Ñÿ–Òÿ–Ñý ×þªÞÿ±âÿ»çÿÁéÿÍñÿÒòÿÝúÿßûÿàùÿÝöýÛöýÚ÷ÿÙ÷ÿÏóÿÆíþ³ßúªÜý¥ÙþÒúÔýžÕþÒüœÑûŸÔü ÕýÔý™ÒýšÕÿœ×ÿ–Óÿ–Ñý•Ðú›ÔÿŸÖÿ¤ØýªÜÿ°Þÿ¯Üù·áùÆìÿÉíÿÈëþÉìÿÆéüÆëþÉîÿÍñÿÔöÿÖøÿÓóÿÍïûÉíûÊîþÌïÿÎïÿÏðÿÏðÿÎïþÎïþÎïþÎïþÉíýÇêýÌïÿÔôÿÔôÿÔôÿÖöÿÙ÷ÿØöÿÚöÿÝøÿÞ÷þÜõüÙõÿÄíÿºäý®ÜþªÚÿŸÒýŸÒý¡Òû«Ùû±ßÿ¼èÿÂèûÒóÿÙõÿÚõþÞ÷þàùÿÚöÿ×õÿÌðþÈíÿÅëþËìýÏìúÙôÿÚõþÖôÿÕõÿÕõÿÕóþÙõÿÜõüÞ÷þÜ÷þØóüÕóý×õÿÎîýÊëüÊíÿÎñÿÌóÿÂïÿ¼èÿªØúŸÓúžÖû—Óø“Ñø’Ïû’Ïþ–Ðÿ–Ïú¡×ý­ßÿ²ãÿ½éÿÀèÿÎïÿÒòÿßüÿâþÿãüÿÞ÷üÝöûÝùýÛøþÕõÿÌðÿ¼æþ²ãÿ¬ÞÿÔûÔýœÓü›ÒûÔýœÑù›ÐøœÓü›ÔÿšÕÿ™Ôÿ•Òÿ–Ñý•ÐüšÓþ¡Øÿªßÿ­ßÿ±àþ¶ãÿ»åýÄêÿÇëÿËîÿÉìÿÂæü¾äûÀæýÂèýÉîÿÍñÿÍñÿÇìþÂèû¼åû¼äþ¾æÿ¿èþÀéýÅêüÇìþËïÿËïÿËïÿËîÿÎñÿÐñÿÓóÿÕõÿØôÿÙôýÙôûåþÿèÿÿèýÿæûþâûÿÍñýÄëü´âü¬ÝýžÔú¦Üÿ©Ýÿ³äÿ½ëÿÃîÿÊïÿÏïüÔñùÙò÷ãøýäùþáøþßøÿÖôþÑñüÊïÿÎïÿÑñþÚõÿÚõÿÖóÿÐñÿÌíþÑñÿÕòÿÑñþÑóÿÕõÿÖöÿØöÿÙ÷ÿ×óþÖòþÔðüÒîüÒòÿÄîÿ»çÿ¬Üÿ¤Ùÿ¤ÚÿŸÕ÷Óõ™Ð÷—Ðû—ÐýÔû¤Øý­Þÿ²àÿ½æÿÂèÿÎïÿÓóÿÜùÿçÿÿçÿÿéþÿêýÿéþÿçÿÿÝøÿØöÿÉïÿºèÿ²áÿ¦Üÿ¥ßÿ¡ÛÿœÕÿ—Òü˜Í÷›ÐúžÔÿ›Ôÿ—Ñÿ–Ðþ”Ñþ•Ïý”Ïû™ÒýŸÖÿªßÿ­ßÿ³âÿ¸åÿ¼æþÄêÿÆêÿÈìÿÇëÿÀæý½åþ½åþ¾çýÄêýÉîþÍòÿÅëÿÀéÿ·ãüµáþ²Þûµßø·áù¿èüÄêýÈíÿÊïÿÌïÿÌïÿÌïÿÍîÿÏñýÓóþ×óþÙôýÜõüèÿÿêÿÿèýÿçÿÿæÿÿÔöÿËðÿ¶äü¬ÝûÓù£Ûÿ§Ýÿ²äÿ»éÿÅîÿÉîþÐðýÒï÷ØñöæûþéüÿæþÿäýÿÚ÷ÿÕóýÊïÿÐñÿÔôÿÚöÿØôÿÑñÿÍîÿÆéüÍìþÏïþÍñÿÎòÿÒóÿÕõÿÙ÷ÿÚøÿÚõþØóþÕðûÑëøÒïýÅîÿ¼èÿ®àÿ©ßÿ©ßÿ¥Úù¦Ùø ÔùÒú™ÏûŸÔü©Ýÿ¬Ýþ°ßýÁéÿÂèÿÍîýÑñüÚ÷ýçÿÿêÿÿëþÿìþÿìþþëÿÿåýÿßúÿÎòÿ¾èÿ³àý¦Üÿ§Þÿ¥Üÿ¢ÙÿœÖþÒüŸÔþÓÿ˜Ñþ”Îü•Ïý‘Îû’Ìú“Îú™Òÿ ×ÿ«Ýþ­Þþ¶ãÿ»éÿ¼æþÃéÿÄèþÅéÿÅéÿÀåÿ½æÿ¼åÿ½åÿÃéþÉîÿÊïÿÅëÿÀêÿ¸åÿ±ßÿ©ÛüªÛû¯Þú»èÿÁêþÇìþÊïÿÏòÿÍðÿÊíÿÌïÿÍñÿÔôÿØöÿÞùÿàüÿãüÿâûÿáúþæÿÿåÿÿÙúÿÎòÿ´àû©Úû›ÔÿœÕÿ ×þªÝü²áûÂíÿÌóÿÒôÿÓðøÖòöçÿÿêÿÿéÿÿçÿÿÚ÷ýÕòúÄéûÌïÿÔôÿØöÿÕòÿÎïÿÊíÿÃçýÆéýËëÿÕöÿÔõÿÖôÿØöÿÚ÷ÿÙöü×ôüÖôÿÒòÿÍîÿÏðÿÆìÿ¼æÿ¨Úÿ¬àÿ²äÿ¾ìÿÀìÿ¶ãÿ­Þÿ£×ÿ§ÛÿªÚþ°Þÿ´áþ¾æÿÃéþÌíüÏïúÙöúèÿÿíÿÿòÿÿòÿÿôÿþôÿþìþÿçüÿÔñÿ¿åüµßø­Ûü¬Ýý¬Ýþ¨ÚûŸÔö§Üÿ¥ÚÿŸÕÿ›Ôÿ–Ðþ”Îü’Ïü“Íû“Îú˜ÑþŸÖÿ¨Ûú­Þþ´áþ¸æÿ½çÿÂèÿÁçþÅéÿÅéÿÃèÿ¼èÿ½æÿ½çÿÁçüÃèûÂæüÀèÿ½æÿ±ßÿ®Üþ¦Üÿ¨Ýÿ®áÿ»éÿ¾èÿÄéüÈíÿÌïÿÈëÿÅèþÉîÿÊïÿÏñýÑñüØõýÚ÷ýÙõùÙõùÙõùÞûÿßüÿÔñÿÊëþ´áÿªÜÿ•Íþ–Ðÿ˜Ðÿ£Õú©×ø½çÿÆïÿÏóÿØöÿÝøÿæþÿêÿÿèÿÿäýÿØõûÓðøÅêüÉîÿÐñÿÕòÿÑñÿÎñÿÌðÿÂêÿÅéÿËîÿÕñÿÕðûÚõüÞùÿáýÿÞûÿÚøÿÏóÿÈîÿ¿éÿÂêÿÅèû»ãü¨Øü®ÞÿµãÿÁêÿÅëþ¼æÿ´áþ¬Þÿ­ßÿªÛü´áÿºæÿ¾æÿÄèþÎïþÑñüÛøüéÿÿïþÿõÿÿ÷ÿÿøÿü÷ÿûñÿÿìþÿÛõÿÇêþÀåÿ¸âû¹ãû½çÿ»çÿµáþªÞÿ¦Ûÿ¡×ÿž×ÿ–Ðþ‘Îû”Ñþ’Ïþ“Íû—ÐýÔý§Ùú­Þþ³àý¶äþ½çÿÂèÿÁçþÄêÿÅëÿÅêÿÀéÿÀêÿÀèÿÁçþÁçüÀæýÀêÿ¼èÿ±Þÿ­Ûý¨Ýÿ©Þþ°ãÿ½ëÿ¿éÿÁçúÆëþÈíÿÅèþÃæüÈîÿÉðÿËðÿÍñÿÔôÿØöÿÙöþÛøþÚ÷ýàýÿàÿÿÐñÿÃçý­Ýÿ¦Ûÿ˜Òÿ—Ñÿ™Ñÿ£Õú¦×ø»çÿÄïÿÏóÿÜúÿáüÿêÿÿëÿÿèÿÿäýÿØõûÒðøÅêüÇìþÍîÿÏïþÎîýÌïÿÊîÿÀèÿÂçÿÇíÿÒîüÓîùÞ÷þåüÿéÿÿæÿÿÛùÿËðÿÂëÿµäÿ·äÿ·ßù°Ûû¡Òú¥ÖþªÛü¸äý¿èþ¹ãü³ßü¯Ýÿ®Þÿ®Üþ´áÿºæÿÃéÿÆéýÐðýÕóýÝùýìÿÿðþÿõÿþøÿÿøÿü÷ÿûõÿÿðÿÿàøÿÍîÿÇêþÆìÿÇíÿÆïÿÄìÿ¹ãü²äÿ«ÝÿŸÔüÔý–Ðþ”Ñþ“Ñÿ’ÐÿÍü”Îü˜Ñþ£Ôü¨Øþ²àÿ³àý¹æý¾çý¿èüÁêÿÂëÿÂëÿÆìÿÃéþÂèýÀéÿ¾èÿ¾êÿ»éÿ¹çÿ±ßù®Ýù¨Ù÷´ãÿ»éÿ¾èÿ¿çÿÀæýÂèÿÀæýÀæýÁæÿÃîÿÃîÿÅîÿÄíÿÉíÿÎñÿÑòÿÖôþÛøþßûüÚùþ¸åú«Ýøœ×ÿ•ÓÿÌÿ–Îÿ™Íü¡Óø§ÙúµäÿÀêÿÌïÿÞùÿâùÿëÿþíÿþëÿÿåþÿÜúÿÔôÿÁåûÉìÿËîÿÈëÿÇêþÉìÿÉîÿÁêÿ·ãü»çÿÍîÿÕòÿçýÿíÿÿîþþíýýà÷ýÎñÿÃíÿ¥ÙþŸÖÿ—Ñÿ–Ðÿ•Ïý—Ðû—Ñù­ãÿ²æÿ²âÿ°Þÿ°Ýþ°Ýþ´ßÿ»äÿ¿çÿÅêýÌíþÓðøÛôùèýþïÿþôþýöüü÷ýýøÿþøÿÿöÿÿïÿÿèýÿÜõüØóüÏïüÐñÿËïÿÊíÿÈîÿ¶èÿ­ßÿŸÔüžÕþ–Ðþ’Ïü‘Ïÿ‘ÏÿÍü•Ïý˜Ñþ Ôû¦Øý²àÿ³àýºçþ¾çý¿èüÅëÿÆìÿÇíÿÅëÿÅëÿÄêÿ¿èþ¿éÿÀìÿ¹çÿ¶äþ²áý±àþ¬Û÷¶ãÿ»éÿ½çÿ¿çÿÃéÿÃéþÃçýÄêÿÄêÿÀéû¿èúÃéüÂèûÇìÿÍðÿÎïÿÑòûÖôüÙöúÒóú²àø§Øø—Òþ‘ÏÿÌÿ–ÐÿšÐþŸÓú¤Ùû³âÿÀêÿÉìÿØôÿÞ÷üëÿþíÿþíÿÿçÿÿÝúÿÖôÿÄéüÉíÿÊîÿÆêÿÃçýÅéÿÆìÿ½åþ²Þù¹åÿÈëþÓðþåýÿìÿÿðÿÿïÿÿâùÿÍðÿÂêÿ¤ØýžÕþ”Îÿ‘ÍÿÍú“Îø–Ðø§Þÿ¬ãÿ¬àÿ«Ýÿ«Ûÿ¬Úü±Þÿ¹åÿ¾èÿÅéÿÊëüÕñüÞ÷þëÿÿðÿÿóÿýôýüõþýøÿÿøÿÿôÿÿïÿÿéþÿàùÿÜ÷þÕñÿÖóÿÍîÿÊëþËðÿ³åÿ¯áÿ§Üÿ¢Ùÿ”Îü‘ÎûÍþÍþ’Ïþ—Ñÿ™Òÿ Õý¥Ùÿ°áÿ³âÿ¼éÿÀéÿÃéþÆìÿÆìÿÇíÿÃéþÆìÿÅëÿÀéÿÂìÿ»çÿ¶ãÿ´ãÿ²ãÿ¯àþµäÿÂîÿÆòÿÁêÿÃéþÈíÿÉìÿÉíýÌðÿÊïÿÅèûÀãöÄèøÊîüÉë÷ÇéõÔôÿÔõþÕöÿÏïúÆêúªÜý Öü’ÒÿŒÐÿŽÑÿÎý•Îû›Ðú Õý¬Þÿ¹åÿÈíÿ×õÿÛ÷ûêþýëþüîÿÿëÿÿâùÿÛóýÈíÿÃéÿÁçþÀæýÁçþ¼äþ¸áý¬Øõ®Üý´âÿÁåûÌìûßúÿåýÿìþþîÿÿæýÿÏóÿÃìÿªÛûŸÕû“Ïÿ’ÎÿŽÌýËúÌø’Ïü–Ñý•Îù•ÎùŸÔþ¥Öþ«ÛÿµäÿºçÿÅëÿÈëþÚöÿäýÿîÿÿðÿýòÿÿóÿÿóÿÿôÿÿôÿÿñÿÿïÿÿéüÿâúþÝõùØòÿÖòÿÐíýÏîÿËîÿ¯áÿ­ßÿ¦Ûÿ¡Øÿ”Îü’ÏüÍþÍþ“Ðÿ—Ñÿ—ÒþžÕþ¢×ÿ­ßÿ±àþºæÿÀéÿÃéþÅëÿÅëÿÅëÿÅëÿÆìÿÅëÿ¿çÿ»çÿ¹åÿ·æÿ·æÿ³äÿ°áÿ³àýÀìÿÆðÿÃéþÄêýÊîþËïýËïûÏñýÍñýÍîÿÉèúÍíüÓóÿÎïøÊëôÙúÿÙúÿÙùÿÐðýÄéü¦ÚÿœÓúŽÐÿŠÐÿŠÐÿŽÍù’Íù™ÏûÒþ§Ûÿ³áûÅìý×õÿÙõùèüûëþüñÿÿíÿÿæûÿÞõýÉîÿÀæý½ãú¾æÿÀèÿ¹âþ²Þû©Ö÷«Ûÿ¯ßÿ¿åúÊëúÜùÿâùÿéýþìÿÿåþÿÐôÿÅîÿ¬Ýû Ôù’ÐÿÎÿÍýŠÊúˆÈøÍûÎýŽËøÌùšÓÿ¡Öþ¨Úÿ²ãÿ¹æÿÃéÿÈëÿÛ÷ÿåþÿîÿÿðÿýñÿÿðþþïÿþðÿÿðþþîþýìþþêþÿéþÿâúüÖñüÔðþÑîþÒñÿÉìÿ®àÿ¦Øû›Ðø›Òû•Ïý’ÏüÍþŽÌý“Ðÿ—Ñÿ–Ñý ×ÿ¤Ùÿ­ßÿ¯àÿ¹çÿ½çý¿èüÄêýÄêýÅëÿÁçþ½æü¾çý¿çÿ¹ãü¹åÿºèÿ·æÿ²áý²áýÀêÿÇíÿÈîÿÄèøËìûØöÿÚøÿÙøýØ÷üÜûÿÜøÿÛ÷ÿÜøÿÚ÷ÿØõùÚùüØúüÙùÿØøÿÌíÿÁåÿ¢Öþ–ÌøŒÎþ‰Ïÿ†ÍûÏû‘Îú•ÎûšÐþ¡Öÿ¯ÞüÁêþÒòý×ôúêÿÿíÿÿõÿÿõÿÿðÿÿèùÿÌíþ¾çû½æü¿çÿ¾èÿµâÿ´áÿ­Ûÿ¦Öþ¨Ùÿ¾æÿÈíýÙúÿÞùÿçüÿéþÿâûÿÒóÿÈîÿ¯ÞøŸÔô“ÑÿÍþ‘ÐÿŠÌÿ„ÇûˆËÿŽÐÿŽÐÿŒÎÿ“ÑÿšÓþ¢Øþ­ßÿ³áÿ½åþÃèûÙõÿãüÿðÿÿóÿÿîÿÿìþþëÿþëÿþêþýéýþêÿÿêÿÿìÿÿçüýÓïúÒòÿÐôÿÏòÿÇíÿ­ßÿ§ÙüœÑùšÑú’ÌúÍú‘Ïÿ‘Ïÿ’Ïþ•Ïý–Ïü ×ÿ¥Úÿ­ßÿ°áÿ·åý»åû¾çýÀéÿÁêÿÂêÿ¿çÿ¼æþ»åý¸âú·áùºäü¹ãû¹ãû½çÿÀêÿËðÿÒóÿÍïûÍëõÖóûæÿÿåþÿáûüãýþãýþâûÿâúÿãüÿäýÿßûüÞúûØõùÚøÿÚ÷ÿËêþÄæÿ§ÙþžÓûÐþŒÐÿŠÐÿÏýÏû”Îü—ÏþŸÔÿ®ßÿÁëÿÌíüÖôþåýÿëÿÿñÿÿóÿÿðÿÿìûÿØõÿÈíÿÂèû¿èþÀêÿºæÿ´áÿ®ÜþªÚþ­Ýÿ¾èÿÆìÿÓõÿ×õÿàùþãüÿÝøÿÓôÿÎôÿºæÿ«Üü–Óÿ“Ðý‘ÏÿÌÿ‹ÍÿÏÿŽÐÿŒÎÿŽÍÿ–Ôÿ×ÿ¢ØþªÛü°ßýºäúÁæùØóþâùÿïÿÿñÿýìþþèýþéþÿçÿÿåýÿÞöúßùúèÿÿçÿÿãûÿÕ÷ÿÍõÿÅïÿ¾éúµâù®àÿ¨ÚýžÓû›Òû’ÌúÌùÎÿÎÿ‘Îý”Îü•Îû¡Öÿ¦Úÿ®àÿ±âÿ¸æþ¹æý¼æþ¾èÿ¾èÿ¿éÿ¿éÿ»åþ¹ãü¸âú¹áú¼äý½æü¼åû¿èþÆìÿÕöÿ×ôÿÓñûÕð÷Þ÷üçÿÿçÿÿçüýæþþåýýâúþâùÿäûÿåýÿãüÿßûþÙöúÙ÷ÿÚøÿÏìüÉéþ¬Úû£Õú‘ÐüÏÿ‹ÏÿÏý‘Ðü“Îú”Ïû›ÑýªÛü¼æÿÊíÿÓóÿÞ÷üçüÿíÿÿñÿÿîþþìûþÜøÿÍîÿÆéüÂèýÀêÿ¾êÿ¸åÿ°Þÿ®Üþ±ßÿÀêÿÄíÿÎòÿÓóþÞùÿáýÿÜùÿÒóÿÏôÿÁëÿµäÿšÕÿ–Ñý‘ÏþÎÿ‘ÐÿÎÿÎÿŽÎþ‘Ïþš×ÿÔû¡Õú§Øø¬Û÷ºãùÄçûÙôÿãúÿïÿÿñÿýíÿÿçüýèýþèÿÿäüÿÜõúÛ÷úãüÿäýÿáúÿÕùÿÌöÿÀëû·ä÷°Þõ¨Úý¥×úžÓûœÓü–Ðþ–ÓÿÎÿÎÿ‘Îý”Îü•Îû¥Öþ©Ûÿ¯àÿ³âÿ¸æÿ»çÿ¹åþ¶âûµãýµãý·åÿµáüµáú¼æþÃéÿÃéþÈëþÇêýËìýÒòÿÜøÿßøÿâùÿèýÿêþÿíýýïÿþîþýïÿþìÿýéýüèýþéþÿçÿÿáøþÞ÷þÜ÷ÿÞùÿàûÿÚõþÒðûÀéÿ²ßü—Î÷ÌûÎÿ‘Ïÿ“Ðÿ—Òþ˜ÓýŸÖý¨Øü·àþÌðÿÔõÿÛöýãúÿëÿÿíÿÿíÿÿíÿÿäüÿÓñüÎîûÃæù¿åøÆðÿÅïÿ½éÿ·ãü¶âûµáú»åýÈïÿÑòÿÛ÷ÿÜùÿÚöÿÎïÿÊíÿÀèÿ¶ãÿ¡ÛÿžØþšÕÿ•Ïÿ“Ðÿ‘Îý•Ïÿ˜ÑþšÓþ Õý¢Öû¬Þÿ´ãÿ·åÿÃéþÏðÿÞùÿæýÿïÿÿðþþíÿÿëÿÿêÿÿâûÿÞùÿ×ôü×ôüÚ÷ÿÝøÿÛöÿÏóÿÇðÿ¿êý¸åú°Þö¨Úý¤ÖùÒú›Òû—Ñÿ˜ÕÿÎÿÎÿ’Ïþ•Ïý—Ðý¤Öû©Ùý±ßÿ³âþ¸æÿ»çÿ¸äý²àú²àú³àý²ßü´àûµáú¼æþÇíÿÉîÿÎïÿÏïþÓðþ×óÿáúÿåüÿéþÿîÿÿîÿÿñÿÿóÿÿòÿÿòÿÿòÿÿëÿýéÿýéþÿæþÿßöþÜòýÞöÿÜ÷ÿàûÿÞùÿØõýËðÿ¼æþœÑù“ÍûÍÿ’Îÿ•Ïÿ—ÒþšÕý¢Úÿ¬Üÿ¸áÿÊîÿÐñÿÙöþáúÿéþÿìÿÿîÿÿíÿÿæÿÿ×óþÕóþÅéùÂçùÇðÿÆðÿÀêÿ»åû¸âø±Ýø´àùÅëþÌðÿ×õÿÙõÿÙ÷ÿÏðÿÊíÿÀåÿ´àý¢Úÿ ØýœÕÿ–Îý•Ïý—Ïþ™Ñÿ Õÿ¡Öÿ£×ü§Ùú±âÿµãý¶âûÀæûÍîÿÝøÿåüÿðÿÿòÿÿìþþëÿÿæþÿÝùýÜ÷ÿÖôþÖôþÙõÿÛ÷ÿÚõÿÎñÿÇíÿÀéÿ½çÿ²Þùºçÿ³âÿ§Ùü Ôû›ÔÿžØÿ’Îÿ’Îÿ–ÐÿšÒÿÓÿ¥Õû¨Øü®ßÿ²áÿ¶åÿ¶åÿ´áþ¯Þü°ßý±âÿ°ßû»éÿ¼èÿÃéþÑôÿØ÷ÿÚöÿÛ÷ÿÞùÿß÷ÿéþÿêþÿëýÿíýýïýþôÿÿöÿÿõÿþôþÿ÷ÿÿòÿýïÿýïÿÿíÿÿãùÿàöÿÝõÿÔïøÙôûäÿÿàýÿÔöÿÊðÿ¬ÞÿžÔÿÌÿÍÿ‘Íÿ’Ïû•ÓüŸÙþ¨Úÿ°Ûý¿çÿÅêýÖöÿÙöþáúÿåýÿêÿÿêÿÿâûÿÙôýÚöÿÍíúÈéøÌïÿÌñÿÃéüÁêüÂëý±Ýö²Þù»äúÂèûÐñÿÕóþÚöÿÒòÿÍîÿ½âü°Ü÷¡×ûŸÕû¡Öþ Õÿ¡Öÿ¤Øÿ¤Õý¨ØüªÛü°ßýµâÿ½éÿ¾èÿÀéÿÎòÿÕõÿåüÿëþÿðÿÿñÿÿïÿÿáùûÞõûÛöÿ×óÿ×õÿ×õÿØùÿ×÷ÿÖóÿÇêþ¾âú¼âùÂçÿ¿çÿÍòÿÇíÿ³Üø«Øù¤Õÿ¢ÕÿšÏÿ›ÐÿœÔÿžÔÿÒþ£Ôü¥Öþ©Ûþ¬Ýþ°áÿ±âÿ³áÿ¬Ýþ«Ûÿ°Þÿ³àýÀêÿÅîÿÍñÿÔòýÜøÿÜôþÞ÷þäýÿäýÿçüÿëýÿìþÿðÿÿòÿÿõÿÿõÿÿöÿÿöÿÿõýÿöÿþòÿüðÿÿïÿÿçûÿáøÿÖñüÏëöÐîöÚûÿàÿÿ×õÿÊïÿ¬ÞÿÖÿŽÍÿŽÍÿÍÿÍüÏûØÿ£×þ­Ûý¸äýÀêÿÍóÿÕ÷ÿßüÿâýÿçþÿçÿÿÞúþÝúÿÝúÿ×õÿÓñüÍíüËìýÃèûÄíÿÀëþ¶àöµß÷µâù»åýÌñÿÖøÿÚõüÙöþÕõÿ¼åû­Ûõ¡×ý£Ùÿ£×ü¨Úý¬Ýþ²áÿ¶ãÿ²àú°ÞøµáúÁçþÄêÿÊðÿÍòÿÕóýßúÿêüþðþÿòÿÿñÿÿæþþÛöýÖðýÓîÿÕðÿ×õýÙøûØûýÓõÿÍñÿ½ãú»äúÀæûÂèûÈíýÙ÷ÿÒòýÉìÿÈîÿ¹äÿ²Þÿ©Úÿ¦×ÿ¢Öþ¢Öþ¢Öþ ÕýŸÔü¡Õü£×ü¦Ûû­ßÿ®ßÿ§×û§×û²àÿ¼èÿÈñÿÐõÿ×÷ÿÜ÷ÿàùþàøüâúþéÿÿèÿÿèýÿêþÿêþÿíÿÿïÿÿòþþóÿÿõÿÿ÷ÿÿ÷ÿÿ÷ÿýõÿúôÿÿóÿÿìýÿéüÿÜóûÓîõÔïøÚ÷ýÜùÿÔòúÉíýªÜý›ÕýŠÉü†Èü‹Êÿ‘ÏÿÍü“ÐüžÕþ¢Öû­Üú³áû¿êýÇîÿÒôÿÕõÿØôÿÙôÿÚøÿÚ÷ýÜùÿáüÿáüÿÙ÷ÿÒòýÂæöÃìþÃîÿ¾èÿ·àü±Þû¸åÿÈñÿÏòÿÞùÿÖòþÎíÿ»åþ²áÿ¬Þÿ®àÿ±ßÿ¹åÿ¾èÿÄíÿÅîÿÃìÿÂëÿÂèûÈéüÊíÿÐóÿÕöÿÝúÿåýÿïýýóÿýôÿÿîÿÿäþûØõýÓîÿÐêÿÐìÿÙ÷ÿÚùüØüüÏóÿËîÿÆëþÇìþÍñÿÒôÿÛùÿßüÿÚøÿÐòþÎòÿÆïÿÁíÿ´âÿ­Þÿ¦Øû¤Öû¢ÖýŸÔþžÓýžÓûŸÕû¤ÙûªÜÿªÜý¤Ôø§Õù´áÿ¿éÿÌòÿÒ÷ÿÛùÿßøÿäüÿãûÿäüþçÿÿæÿÿéþÿêþÿëÿÿíÿÿïÿÿðþþòþþõÿÿ÷ÿÿ÷ÿÿöÿüöÿüöÿÿöÿÿðÿÿìþÿèûÿà÷ýà÷ýâûÿãüÿ×õýÉíý¨Úû™ÓûŠÉü†Èü‹Êÿ‘ÏÿÎý“ÐýœÕÿ Õý¨Ùú®Ýû¹æý¿èüÉîþÍñÿÐðýÒïý×õÿÚ÷ÿÝúÿäÿÿäÿÿÜùÿÖôþÃç÷ÅëÿÃìÿ¼åÿ´ßÿ±Þÿ¶ãÿÃëÿÊîÿÚ÷ÿÔñÿÈëÿ¸äÿ²áÿ°áÿ³áÿµâÿ¿éÿÄíÿÉïÿÊïÿËðÿÊïÿÇëûËìýÍîÿÐôÿÕ÷ÿÞúþéþÿñÿÿôÿþòÿÿíÿÿæÿýÚ÷ÿÕñÿÐêÿÏëÿ×õÿØ÷üÙûýÓõÿÎñÿÏðÿÐñÿÔôÿÙ÷ÿàûÿáùýäýÿäÿÿßþÿÖøÿÓùÿÅðÿ¾éü°Þö¬Ùø©ÚûžÔÿ›Ñý—Ðû™Óû ×þ Öü¡Õú¦Ôö«ØùºãÿÁçüÎòÿÖøÿÝúÿâúüäùúæûüèýþçÿÿçÿÿæþþéþÿêÿÿìÿÿîÿÿïÿþñÿÿôÿþõÿþôþýöÿüöÿü÷ÿÿ÷ÿÿöÿÿöÿÿõÿÿòÿÿñÿÿîþýêþÿÜúÿÌïÿ§Ùú›ÒûŽÍÿŒËÿŒÊýÍþÍþ“Ñÿ”Ñÿ™ÒÿžÓý¡ÕüªÛû¯Þú¹ãü½åþÃéþÇëÿÑîÿÙõÿÞúÿäÿÿâþÿÚøú×öûÉíûÄêÿ¿äÿ¯Úý®Úÿ²àÿ²àÿ¶âÿ½åÿÇëÿÅéÿ½äÿ´áÿ±ßÿ·ãü¼æÿ¿èþÈíÿÌðþÓóÿÕõÿ×øÿÖ÷ÿÔõþ×õÿÔôÿÔöÿÖöÿÜøüêÿÿðÿýòÿüðÿÿêÿÿèÿÿÝúÿØôÿÑíÿÐíÿÔôÿÕöÿ×øÿÒôÿÏðÿÐíûÒîùÙôûÞ÷þèýÿéýÿæûÿàøüßùúÚùû×ùûÎóûÈîû½æüºáþµâÿž×ÿ™Òý‘Îú’Ïû˜ÓÿžÕþŸÕû­Ûýµàÿ¿çÿÆêúÖ÷ÿÞüÿçÿÿêÿÿèüûêÿþêÿþæþþäþýâüýãýþåýÿéþÿêÿÿëýýëþüñÿýòÿþõÿýõÿþ÷ÿÿ÷ÿÿøþþøþþùÿÿûÿÿùÿÿùÿÿ÷ÿþñÿÿÖöÿËðÿ­ßÿ¡Øÿ‘ÏÿŽÍÿŽÌÿ’ÐÿÏÿÏÿÍÿ”Ðÿ™Óÿ›Ôÿ Õý¦Úÿ­Ûý­Üú³àý¸äÿËëÿÒïÿØôÿÞûÿàüÿÜúüÙøýËïýÄéÿ¼ãÿ²Þÿ«Ùý¬Úü±Þÿµáþ¶âý¶âû±Ýú°Ýü²ãÿ³âÿÃéþÇíÿÌðÿÒòÿÖôþÜùÿàýÿÝúÿÚ÷ýÛøþÖôüÓôýÓôýÖôüÜõùèýþíÿþîÿÿìÿÿæÿÿãÿÿÚ÷ýÔòüÍìþÌëÿÌìûÍíúÑñüÑñÿÐïÿØõÿÙõÿÚõþÝöýà÷ýáõþáõþßöüÞ÷ûÛ÷úÙöúÔõüÏñýÅéÿÁæÿ½æÿ¡Øÿ—Ðû‘ÎúÌùš×ÿ™ÒýŸÔü¯Üý·âÿÉïÿÊëüÙúÿßþÿèÿÿèýþêþýêÿþêÿþåýýâüýÜøûßûþãýþçÿÿêÿÿêþýíÿþñÿÿðÿýñÿýôþÿôþÿ÷ÿÿúÿÿüÿÿüÿÿüÿýûÿýûÿýõþùðþþÏïüÀåø¨Úû ×ÿÎÿÍÿÍÿŽÍÿŽÍÿÌÿŽÌÿ‘ÏÿšÔÿœÔÿÓÿŸÔþ¥×ü«Üý°Þÿ´áÿÁåÿÌëÿÒòÿÛúÿÜùýØ÷úÓôûÉíýÁæÿºáÿ¯Ýÿ­Ýÿ°ßý²ßü³áû³áû°Þø®Ýù°ßý´åÿ¸çÿÄêÿÉîÿËïÿÔôÿÚøÿÜ÷þÞùÿÞúþÝùýÜùýÙøýÕöÿÔõþ×õýÝöûçüÿîÿÿíÿÿéÿÿâþÿÛùûÚøÿ×õÿÌíþËìÿÊëþÍîÿÔõÿ×÷ÿ×öÿÚúÿÛùÿÚøÿÙõÿÜôþÜóÿÝõÿÞöÿÞöÿÞ÷þÜ÷þÛ÷ÿÛ÷ÿÕôÿÐðÿÊïÿ®àÿ¢Øþ–ÑýÍú”Òÿ–Ñý™Ðù°Ýþ½æÿÍðÿÏðÿÛùÿÝúÿäýÿçüýéþÿéþÿçÿÿáýÿßûþÛøþÛøþÛøüáúþâûÿæûþèýþìÿþíÿþíÿþñÿÿóÿÿõÿÿ÷ÿÿûÿþûÿþûÿüûÿýøÿþôÿûîþýÓôÿÆëþªÜÿ ×ÿ“ÏÿÍÿ‘ÏÿŒËÿ‹ÊÿŒÎÿÎÿ’Îÿ–Ðÿ—Ñÿ™ÒÿžÔÿ£×ÿ¦ÚÿªÜý¬Þÿ¸áýÂæþÇìÿÐôÿÒôÿÏóÿÌñÿÃìÿ»æÿ·ãÿ²ãÿ²ãÿ·äÿ¸äý·åü¶æý¬âþªßþ«àÿ´åÿ¹çÿÁçþÄêÿËîÿÑñþÓñü×ôüÙöþÚ÷ýÚ÷ýÛøþØöþÔõþÓóþÖôÿÚõþáøþëÿÿêÿÿßüÿÓõþÕöÿÒòÿÒóÿÍòÿÉíÿÅéÿÆêÿÌïÿÑòÿÒòÿÏóÿÎòÿÓôÿÒóÿÔñÿÕñýÖòþÚõÿÛöÿÞöÿÞöÿÜ÷ÿÜøÿÙöÿÒñÿÌðÿ±âÿ¨Úý˜Ñü”Îü“Ñÿ˜ÒÿšÑú°Ýþ¼åÿÉìÿÏðÿÛ÷ÿÜùÿåþÿêÿÿéþÿçÿÿåþÿßüÿÝúþÚ÷ÿÙöþÙöüÜøüßøýâúþæûþëÿþìþþìÿýðÿÿñÿÿôÿÿõÿÿùÿÿùÿýùÿûøÿþöÿýðÿüìþþ×øÿÉïÿ©ÛþÔýÌþÍÿ‘ÏÿŠÉþ‡ÉýŠÌÿŽÎþ’Îÿ”Îþ•Ïÿ™ÒÿŸÕÿ£×ÿ¦Úÿ¨ÚýªÜý¶âý¾æÿÂëÿÊðÿÊïÿÈíÿÅëþ½çÿµâÿ³áÿ±áÿ²ãÿ¸äÿºäý¸åü¶åÿ¬ãÿ¨Þÿ©àÿ²ãÿ¸åÿ¾æÿÁêÿÊïÿÏðÿÐðýÔòü×óþ×ôü×õýØöþÖôüÒôþÒòÿÓóÿ×óþßøÿéÿÿæÿÿ×øÿËïûÎðüÎïþÍñÿÈîÿÄêÿÀèÿÃéÿÈìÿÏðÿÐðýÍñÿËðÿÏóÿÑòÿÐðÿÑóýÑóýÕõÿÙ÷ÿÛ÷ÿÜ÷ÿÝøÿÞùÿÝúÿ×ôüÑóÿ·ãþ¬ÛùšÏ÷•Ðü”ÒÿšÔÿŸÕÿµâÿÀéÿÌïÿÒóÿÛ÷ÿÚöÿàùÿãûÿåýÿâûÿÞùÿÙ÷ÿØöÿÕóþÖôÿ×õÿÙöþÛöÿÞ÷üáùýéþÿëþÿìþÿíÿÿîÿÿðÿÿñÿÿôþýõþýôÿûòÿÿñÿÿëÿþçÿÿÏóÿÂèý§×ûŸÔþ–ÐÿÌÿŽÊþŠÇý†Èü‡ÉýŽÌû–Ðþ–Ðþ–ÐþžÔÿ Õÿ£×ÿ¥Ùþ¥Úú©Üû°âýµãý¹åÿ¿èÿ¾èÿºãÿ·ãÿ²ßþ©Ûü©Ûþ¬Üÿ°Ýÿ¸áÿºáþ¹âþµäÿ¨àÿ Úÿ¡Ùþ­Ûý°Ýü·ãÿ»äÿÂêÿÊïÿÌïÿÏïþÐðÿÐðýÑñþÓóÿÕõÿÓôÿÓôÿÓôÿØôÿÛöÿáüÿÜøÿÉïüÁçúÂåùÈíÿÇíÿ½çýºæÿ¹åÿºãÿ¿èþÌðþÏñûÍñÿËïÿÏðÿÐñÿÏîÿÑöþÒ÷ÿÔöÿÕõÿØôÿØôÿÜ÷ÿÞùÿßûÿÚøúÕöý¾èÿ°Ýú™Îö•Îù’Ðÿ—Ôÿ Öÿ´áÿ½æÿÉìÿÏðÿÙõÿØôÿÞ÷þà÷ýáøþÞ÷þÚõüÕóýÔòüÐðýÕòÿ×õÿÛøÿÜ÷ÿÝöûàùýçÿÿêÿÿëÿÿìÿÿìÿÿðÿÿñÿÿôþýôþýòþüñÿÿîÿÿêÿÿæÿÿÌðÿ½ãø¦Öú Õÿ™ÓÿËÿ‹ÇûŒÉÿŠÌÿ‰ËÿÎú™Òÿ™Òÿ˜ÑþžÔÿ Õÿ£×ÿ¥Ùþ§Ùú©Üû©Ü÷­ßú²áýºæÿºåÿ´ßÿ²ßÿ­Ûý¢×ù£Øú¦×ÿ«ØÿµÞþ·Þý·àÿ³áÿ¤Ûÿ›ÔÿœÓü§ÕùªÖù²ßþµáþ¼äþÆêÿËîÿÎïÿÏðÿÎïþÎïþÑòÿÒôÿÑòÿÏòÿÑòÿÖñÿÙóÿÞøÿÕóþÂéø½æú¾âøÂæüÂèÿ½çýºæÿµâÿµáþ¼åûËïýÏñûÎðüËìûÍíüÐðÿÓðÿÌíþÏðÿÒóÿÐñÿÊíÿÊîþÐñÿÕõÿÛùÿÚ÷ÿÙ÷ÿÅëÿ³ßøžÓõ˜ÒøÒý”Ôÿ—Öÿ©Þþ±âÿ¾èÿÂëÿÎñÿÕöÿÛùÿÛöýÝõÿÓïúÑïúËïýÉîþÍðÿÐñÿÒóÿÙõÿÜ÷ÿÝöýâùÿëÿÿëþÿìÿÿìÿÿìÿÿíÿÿíÿÿïÿÿðþþïýýñÿÿòÿÿïýýéýþÐñÿ¿åú¥×ú¡Øÿ–ÔÿËþŠÈûˆÇúŠÉþŽÐÿ’Ðÿ–Óÿ—Ôÿ˜Õÿœ×ÿ›Õû¤Úþ¨Ýÿ­Þÿ¬Ýþ§Ûÿ¥Ùÿ¥ÙÿªÜÿªÜÿªÚþ¨Úÿ¢ÖýÒúšÏù™Òý™Òý¢Öý©Ûÿ§Ûÿ¤Ùÿ˜Õÿ”Ñÿ–ÐþŸÔÿ¢Õÿ¦×ÿ¨Øü±Þý¿éÿÂëÿÌñÿÍñÿÎïþÎðüÏðÿÎïÿÌïÿÌðÿÎïÿÐíûÖôÿÐðÿÈëÿ´áþ­Þÿ¯Üû·ãÿ¸äÿµãý¶ãÿ°Ýú°Þø·ãüºçþ½çýÄçûÇçüÎïÿÎïÿÎïÿÂäýÁåýÁçþÂçÿ¾æÿ½åþºãùÁçüÐóÿÑòÿÌïÿ¾çÿ±Þý¡ÕúŸÖý™×ÿ—ÕþšÕý¥Úü¬ÝýµâÿÀêÿÅëÿÈíÿÒòÿÙõÿÓïûÏìúËìûÅêýÁçüÄéüÎïÿÓóÿÚöÿÚõþáøþæûÿìÿÿìþÿíÿÿìÿÿìÿÿíÿÿíÿÿïÿÿïÿÿðÿÿòÿÿóÿÿñÿÿíÿÿÝûÿÌñÿ¦×ø›Òù’ÐÿÎÿŽÌÿŠÉþŠÉþ‰ËÿÌÿÎÿÎýÏú•Ðø›Õû£Ùý§Üþ®Þÿ°Þÿ§Ûÿ ÕÿŸÔü£×ü¥Ùþ«ßÿªÞÿ£ØÿœÒþšÐþ“Ðý’Ïû˜ÒúžÓûŸÖÿœÕÿš×ÿ–Óÿ™ÒÿœÑûžÒú§×ÿªÚÿ³àÿÀèÿÂèÿÇìþÊíÿÌðÿËïÿÇêýÈëÿÉìÿÊïÿÌïÿÏñýÑñþÌíÿÄèÿ®Üþ£Ùÿ¦Øû­Ûý®ßÿ³áÿ²àÿ±àþ¯Þü±àü²áýµäÿ½æÿ»åþ¾èÿ¾èÿ»åþºßú·ßù¸áý»äÿ¹åÿ¸äÿ°ÜõµßøÃìÿÇíÿÄéÿ¶ãÿ®Üþ¢Öý Õý×ÿžØÿ£ØÿªÜÿ­Þÿ²ßü¹åþ¿èþÅëÿÐñÿØôÿÖòÿÎîýÊëüÂèý¾çýÅèûÏïüÖôÿÜ÷ÿÞ÷þåúÿèûÿíÿÿìþÿìþÿìþþëÿþìþþìþþîþþîþþðÿÿòÿÿóÿÿòÿÿîÿÿÝùÿÍðÿ©ÚúŸÕû“Ðÿ‘ÏÿÎÿŒËÿ‰ËÿˆÊþÌÿÎÿÎý‘Ðü—Òü›Õý£Ùÿ©Ûÿ°Þÿ±Ýÿ©Ýÿ ÕýŸÓú£×ü¥Úü¦Úÿ¦Úÿ ×þ›Ôÿ›Ôÿ‘ÎûÍú’Ìô—Ìô˜Ïö—Î÷›ÖÿšÕÿÓÿŸÓú¡Òú«Ùý¯ÛÿµáþÂçÿÁçþÆëþÈëÿÊíÿÊíÿÅéÿÅèþÅéÿÈìÿÉîÿÎïþÏðÿÉìÿÁçþªÛü Õý¡Õú¦Øû©Ûþ¯ßÿ­Þÿ¯àÿ­Þþ¯àÿ¯àÿ²àÿ¶åÿ³âÿ´ãÿ¶åÿ±àþ¬Úü¬Úü¬Üÿ­Ýÿ«ÝÿªÜÿ¤Öù£Õø¨Ùú¬Ýþ¬Üÿ£Öÿ¢Õÿ¥Öÿ¦×ÿªÚþ²àÿµáÿ·äÿ´áÿ¯Üû­Ùö»ãýÄêÿÍðÿÐðÿ×ôÿÌíÿÄçû¾äû¿çÿÏïü×ôüÜ÷þåýÿéþÿìþÿìþÿïÿÿïÿÿîþþìþþìþþìþþìþþîþþîþþïÿÿðÿÿïÿÿðÿÿïÿÿåýÿÔôÿµâÿ©Ýÿ‘ÎûÍþÍÿ‹Íÿ‹Íÿ‰Ëÿ‹ÊýÍþ‘Ïþ”Óÿœ×ÿ Öÿ¥Ùÿ©Úÿ¯Üÿ±ÝÿªÚÿ¥×ü¤Öù¨Úû©Ûþ¨Úý¦ÚÿžÕü˜Ñü™ÔÿžÛÿÚÿŸÖÿ Öü¡Õú¡×ýŸÖý£Ûþ§Üþ²áÿµáþ¼ãÿ¿äÿÁåÿÇëÿÇêÿÉìÿÅéÿÆêÿÆìÿÁéÿÀåÿ¾æÿ¾èÿÀéÿÅëþÉîÿÃéÿºäý£×ü™ÒýšÑú›ÒûÔý¢×ÿ¢×ÿ¢Øþ¢Öý¨Üÿ¥Ùþ¥×ü£ÛÿžØýŸÙÿŸÙÿœÖü Ò÷£Õú¦Úÿ§Ûÿ¦Ûÿ¦Ûÿ ÕýŸÔüŸÕû¡×ý¢×ÿÓÿŸÕÿ¨Ùÿ¬Üÿ´áÿ½æÿ¾çÿ»çÿ¸äÿ´àý¬Øó¹áûÂèÿÊíÿÍîÿÐïÿÊëþÄçûÀæýÁéÿÐðûÛ÷ûâûÿêÿÿëÿÿîÿÿïÿÿðþÿðþÿïýþìÿýìÿýìþþìþþìþþìþþìþÿíÿÿìþÿíÿÿîÿÿæýÿØõÿ¶ãÿ¨Ýÿ‘ÎûÍþŽÍÿ‹ÍÿŠËÿˆËÿ‹ÊýÍü‘Ïþ“Òþœ×ÿ¡×ÿ¦ÚÿªÛÿ°Üÿ±Ûÿ­ÛÿªÛü«Üý®ßÿ®ßÿ¬Þÿªßÿ ×þ˜Ñü™Ôÿ—Ôÿ—ÔÿœÓúžÒ÷ ÒõŸÔö¤Úþ©Þþ°áÿ»çÿ¿éÿÈêÿÇéÿÇêþÌïÿÌïÿÊíÿÇìÿÇíÿÄìÿ½çÿ½åÿ»åþ¹åþºæÿ¿èþÅëÿ¾æÿ¶âÿ¡Õü–Ñý•Îû–Ïü–ÏüšÐüÓÿŸÖÿŸÔþ£Øÿ Öü Ôû×ýšÖû›Öþ™Ôü–ÑùŸÔþŸÔþ ×ÿ¡ØÿŸÕÿÓÿšÓÿ™Òÿ—Ñÿ‘Îý’Ïþš×ÿ¡Ûÿ«Ýÿ´áÿÀæýÆëþÆëþÀæû¼åùºäü¾èÿÀéÿÅëÿÌïÿÍîÿÎíÿÍîÿÊíÿÈìÿÊîÿÖôüáúþåÿÿëÿÿìþþïÿþïÿþðþÿïýþîýÿìþþëÿþêþýëÿÿëÿÿêÿÿëÿÿëÿÿèýÿèüÿëÿÿàùÿ×ôÿ¹æÿ¦Úÿ‘ÎûÍÿŽÍÿ‰Êÿ†Éþ‰ÌÿŒÎÿÎý—Õÿ™×ÿ›Ôÿ¢ØÿªÛÿ­Ýÿ®Úý³Þÿµàÿ·ãÿ¹åÿºæÿºæÿ´áþ³âÿ®àÿ£ÙÿÔû™ÓûŸÖý­ßÿ³áÿ±àü°ßû²ãÿ¶åÿ»èÿÊðÿÎóÿÔôÿÖôÿ×õÿÔôÿÒôþÊðýËðÿÄîÿ½êÿ´âü´àý±àþ®ßý®ßý±Þû¸äÿ³àý¯ÝþžÕþ’ÏüËý‘Íÿ‘ÍÿÌû‘Îý›ÕÿœÕÿœÕÿÔýŸÕÿœ×ÿœ×ÿšÕý™ÔüšÕý Õý Õý¢Ùÿ¤Ùÿ¡Øÿ Öÿ™Òÿ—Òþ•ÒÿÎÿ’Ðÿ™ÖÿžÙÿ©Ûü³àýÃéþÇëûÈìüÅêüÃêûÂëÿÁêÿÆêÿÉîÿÑòÿÐðÿÑñÿÐïÿÎïÿËîÿÌïÿÛøÿãüÿæÿÿêÿÿêþÿðÿÿðÿÿðÿÿñÿÿðÿÿìÿÿìÿÿìÿÿíÿÿëÿÿèÿÿæýÿãüÿáúÿáùÿãüÿÜõüÓóÿ»èÿ©Ýÿ”ÑÿÍÿŽÍÿ‡Èþ…Èý†ÉþŒÎÿÎý–Ôÿ˜Öÿ›ÔÿžÔÿ¨Ùÿ¯Ýÿ±Üü¶ßÿ»äÿ¾æÿ¿çÿ¿çÿ¾èÿºæÿ¹çÿ³äÿ«Ýÿ¦Úÿ¢Øü¦Ûý¶åÿºçÿ»çÿ¹åþ¸æÿ¹çþ¿êýÌñÿÒôÿÙ÷ÿØöþÙ÷ÿÖ÷þÓõþÏõÿÍôÿÃíÿ»éÿ²áû±Þý®ßÿ¬Þÿ­ßÿ°ßý´ãÿ°ßý«ÜýÔý‘ÏþŽÌÿÎÿÍÿÍþ‘Íÿ–Ðÿ–Ðþ—Ðý—ÐûšÐüœÖþœÖþ›Õý™ÓûœÓü©Ûþ©Ûþ¬Þÿ­ßÿªÞÿ©ÝÿžÕþšÓþ•ÒÿÎÿ‘Ïÿ˜ÓýœÖþ§Ùú³âÿÆïÿÎóÿÐôÿÌòÿËñþÌñÿÌðÿÑñÿÔôÿÙöÿÚöÿÛ÷ÿÙõÿ×õÿÖôÿØõÿØôÿÞùÿáýÿçÿÿéþÿìÿÿìÿÿìÿÿíÿÿìÿÿêÿÿêÿÿéÿÿêÿÿäýÿàûÿ×ôüÑïúÔòýÖóÿÕóþÓïûÊíÿµæÿ¤Üÿ’ÐÿŠÉüŠÉþ‡Êÿ‡Êÿ‰ÌÿŒÎÿÎÿ”Òÿ–ÓÿšÓÿÔý§Ùü°ßý¸âû½åþÃéÿÄèþÆéýÆéüÆéüÆëþÅêý½æüµáü´àû¶äþºæÿÄíÿÉîÿÉîÿÇíÿÅîÿÅîÿÊïÿÔôÿØöÿÚ÷ýÚ÷ýØ÷üÓôûÐòûÊñÿÃìþµáú®Ý÷¦×÷¥Ö÷£×ü¢Úÿ£Ûÿ¦Ûý¨Úû§Ùü£×ü™ÒÿÎÿ‹Íÿ‹Íÿ‹ÍÿŽÍÿÎÿ”Ñÿ•Òÿ™ÔÿšÓþœÕÿÔýÔûŸÔüžÓû£×þ®ßÿ®ßÿ°áÿ±âÿ¯àÿ®Þÿ¤Øÿ Õý—ÒþÍü‘Îý™ÒýŸÖÿ©Ûþ³áÿÁëÿËñÿÍòÿËðÿÊïÿÌðþÐòþÖôÿØöÿÛ÷ÿÝøÿÜ÷ÿÜ÷ÿÚ÷ÿÙöþÛ÷ÿØôÿÛøÿßúÿäýÿæþÿêÿÿêÿÿêÿÿëÿÿêÿÿéÿÿèÿÿèÿÿèÿÿàûÿÝúÿÑïúËëøÏïüÓôÿÓõÿÌìùÄéü­ßÿ×ýÏÿˆÊþ‡Éý‡Êÿ‰Ìÿ‹ÎÿŒÎÿÐÿ“Ñÿ•ÒÿšÓþžÕü¨Ùú¯Þúºäú¿èüÈëÿÈëþËìýÍîÿÎïþÏðÿÍîÿÅêý¿åü¾ãý¼çúÀéûÉîþÎïþÏðÿÍñÿÊðÿÊïÿÌïÿÖóÿ×õÿØöþØöþ×õýÑñüÎðüÆíþÀéÿ²ßü­Üú§Øù¤Öù Öü×ýŸÙÿ£Ûÿ¢Øü¢Öû Öü—ÑÿÎÿ‹ÍÿŠÍÿŠÍÿŒÎÿÏÿ‘Ïþ“Òþ–Óÿ™ÔþœÖþÔýŸÔþ¡Öÿ£×ÿªÛÿ¶âý¶âý¹åÿºæÿ¸äÿµâÿ«Üý¤Øý›Òû“Îú”ÎüœÒÿ¡Õÿ¥ÖÿªÚÿ²ßÿ¼åÿÂçÿÉíÿËðÿÓôÿÕóýÜ÷þÞùÿàùþãûÿáøþäûÿâûÿßøýßöü×õÿ×õÿ×õÿÛöýÞ÷üÞ÷ûßùúâüýåýÿçÿÿæÿÿåþÿàüÿßúÿÚ÷ÿ×õÿÌìùÄèøÇëûÏôÿÒõÿÎïÿÄíÿ«áÿœ×ÿ‹Íÿ‡Êÿ†Çý†ÉþˆËÿ‰ÌÿŒÎÿÐÿ‘Îý’Ïü›Ñý Öü­Þü¹çÿÆñÿÊñÿÏðÿÐïÿÒïÿÔòýÖòý×óþÖôþÔñÿÏïþÍîÿÌðþÍòû×õýÚ÷ÿÜùÿÛùÿÎòÿÌðÿÍîÿÒïýÓïûÔñÿÒòÿÒòÿÍîÿÈëÿ¼äý¹âþ°Üÿ­Úÿ¨Ùÿ§ÛÿÔû–Ñû–ÔûŸÙÿŸ×ü ÕýžÕþ•ÒÿÏÿŒÍÿˆËÿ‰ÌÿÏÿŽÎþÎý’Ñý—ÕþšÕýœÖþžÔÿŸÕÿ£Øÿ¤ÙÿªÞÿ´áø¶ãú½çÿ¾æÿ¾æÿ½çÿµãý¬Ýý›Òû‘Ïÿ‘Íÿ™Òÿ›ÓÿšÓÿ›Ôÿ¢Ùÿ¨Úû¯ÞúºäúÃìþÍïû×ôúÝöúßøüäüþçùùëþüæøøåúýÞúÿÕõÿÅëþÆïÿÈñÿÈñÿÉïÿÊïÿËïÿÒòýØöÿÛøÿÕ÷ÿÒ÷ÿÍôÿÊñÿÈîÿÈîÿÅëÿÆéÿÇêþÏðÿÕòÿãüÿáýÿÆïÿµãý—ÏôÎúŽÌûŒËþÌÿŽÍÿÏÿÎÿ”Ñÿ•ÐüŸÕû­Þÿ¿çÿÌïÿÝùÿáúÿæýÿæþÿæþÿèýÿèýÿçüÿæûÿâùÿàùÿÞùÿÞúþâþÿÝùýÚõü×÷ÿÔöÿËðÿÁêÿ¼æþ½çÿÀêÿÉïÿÉïÿÉíÿÂæÿ¾äû¾äù¼åû»åþ¸äÿ±ßÿ¬ÞÿœÔù’ÍùŽËø—Öÿ˜×ÿ™×ÿ—Õþ“Îú‘Ëû’ÐÿÎÿÌÿŒËþÌÿÍþÍü•Ðü™ÒýœÒþœÑûžÓý¡Õü£×þ®Þÿµâù·äû½çÿ¾æÿ¾æÿ¾èÿ¸æþ°âýŸÖý’Ðÿ‘Ïÿ•Îû—Ïþ—Ñÿ–ÓÿžØÿ¢Øú§Ú÷²ßö¾çùÍïûØõûÞ÷üáúþäüþçúøîþûèúúæûÿÚúÿÏòÿ»åý¼èÿ¼êÿ½éÿ¼èÿ¿éÿÁêþËïÿÒôÿÖôÿÍòÿÉòÿÃîÿÀêÿÀêÿÂëÿÄêÿÆéÿÊêÿÑðÿÖòÿæûþæÿÿÔøÿÅîÿ¥Ø÷–Ñù’ÏûŽÌýŽÌÿÎÿÏÿÎÿ”Ñþ–Ñý¡×ý®ßÿÃéÿÏðÿâúÿèûÿéþÿéÿýéÿýêþýêþýìÿÿìÿÿéþÿæþÿæýÿäüþçÿÿâûÿÝøÿÖöÿÒóÿÉîÿ½çÿ·ãþµâÿ¶äþ½çÿ½çÿÁèÿ¿çÿ½åþ»äø»äø¼æþ¹åþ´áÿ­àÿœÔù“ÍûËü’Òÿ–Öÿ™Øÿ˜×ÿ—Òþ•Ïÿ‘ÏÿÎÿÌÿŒËþŽÍÿŽÌÿÍþ”Îü—ÐýšÐüÒüžÓûŸÓú¤Öû¬Ýþµäÿ·äÿºæÿ¼åÿ¾æÿ¿çÿ¸æýµåü¦Üþ—Òþ”Îü–Ìú–Ïü˜ÑþšÓþžÕþ¦Ûý°áÿ¼éÿÃìÿÌðÿ×õÿÝúÿßüÿßûÿáùûéýþåúÿàøÿËîÿ¿äþ¦Õñ§ØöªÛù¯Þü±àü³ßø¹ãûÈîÿÍðÿÍîýÄçúÂçú¼âõ»áôÂçúÅêýÇêýÍîýÑñÿÙõÿÜôþçüýèÿÿãÿÿÙúÿµáú©Þÿ¡Øÿ’ÏþÎÿÎÿÎÿÎý”Ñþ˜Óÿ¥Ûÿ«Üý¾æÿÇêþÖòþàøÿêÿÿëÿÿìÿÿíÿÿíÿÿìþþìþþêþÿéþÿéþÿêÿÿèýþáùýßøýÕóýÐðûÅéù¾äû¼äýºäý·ãü³áû±Þû³Þþ¶áÿ¶âý·äû·äû·åÿµäÿ®àÿ«àÿšÔü’ÎÿŽÍÿ†Èü‡ÉûÐý‘Ñÿ“Ðÿ“ÏÿŽÍÿ‹ÍÿŠÌÿ‰ËÿŒÎÿŽÍÿŽÍÿ‘Îý•Îû—ÍûŸÕÿ ×ÿŸÔü¢Öý­Ýÿ²ãÿ³äÿ·äÿ¸ãÿ¾æÿ¿çÿ»èý¹çþ­âÿ¡ØÿœÕÿšÐþ›ÑÿÓÿÓÿÔû¨Ýÿ±âÿ¿éÿÂëÿÍñÿÖöÿÝûÿÞüÿÜúÿßûÿåýÿàùÿÚöÿÃéþ¶ßû£Ôõ£Õø¥×ú©ÚûªÛû²ßü¸äýÉïÿÌñÿÉìÿÄåöÁä÷¿äöÀå÷ÉìÿÌðÿÎïþÔòýÙõÿÞùÿàùþéþÿçÿÿäÿÿÞüÿÁçü²ãÿ¨Üÿ“ÐýÏÿÏÿ‘Ïÿ‘Îý˜Òÿ™Ôþ¦Üÿ¬Þÿ½çÿÅéÿÒïýÚöÿæþÿêÿÿìÿÿíÿÿîÿÿðÿÿîÿÿîÿÿìÿÿìÿÿìÿÿçüýß÷ùßöüØõýÖôþÊëúÃèûÃéþ¾æÿ¼æÿ´ãý±àü°Ýþ³àÿ´áþ´âú´âú²áý®ßÿ¥Ùþ¦Üÿ™Òý‘ÏÿÎÿ†ÇýƒÆúŠÎýŽÐÿ‘Ïÿ‘ÎÿŠËÿ‰Ìÿ‡ÊÿˆËÿŠÍÿÏÿÎÿ’Ïþ•Ðü–ÏüÓÿŸÖÿ Õý£×ÿ®àÿ«àÿ«àÿ±ßÿ³àÿ¼äþ¿èþ½èù½èùµäþªÜý¥Ùþ¢×ÿ¡Öÿ£Øÿ¢×ÿ Ôû©Úû®Ûú´Þ÷·àöËîÿÑòÿÔõÿÑõÿÐôÿÙûÿÙùÿÐñÿÈëþ³àýªÛüŸÖÿÔýÔýŸÕû¢Öû­Ûü´áÿÆîÿÉïÿÆêÿÈéúËëúÑñÿÓóÿÙ÷ÿÛùÿßüÿàùþäýÿéÿÿèÿÿèÿÿèÿÿçÿÿåþÿÒòÿÀêÿ¯àÿ•ÐúŽÎüÏÿÎý–ÐþœÕÿœÕÿ¥Ùÿ«ÝÿµáþºäüÇêþÍîÿÜ÷þäüþèýþìÿÿíÿÿíýüîþýïÿþïÿÿîþþðÿÿìÿýëÿÿçüÿÞ÷þÞùÿÚøÿÓôÿÍðÿÇìÿÅëÿ¸æý¶âû¶âÿ½æÿ¼èÿ·åü¸æý¶åÿ¯àÿ¢ÖûžÕü˜ÒÿÊÿŽÍÿ‰Êÿ…ÈýˆËÿˆËÿ‡ÈþˆÉÿ…ÈÿƒÈÿ‚Çþ„Éÿ‰ÌÿÏÿÏÿ‘Ïÿ”Ñþ–Ðþ™ÒÿœÕÿ¡Öÿ¤Øÿ¬Ýÿ¨ÞÿªÞÿ°Þÿ²ßÿ¼äþ¾çûÁëûÁëûºçþ®ßý«Ûÿ¥Ùÿ¤×ÿ§Ûÿ¦Úÿ¤Öû­Ûü³ßüºâü»áøÉîÿËïÿÍñÿÊïÿÉðÿÓøÿÒöÿÈíÿÀæý«Üü¤ØýšÕÿ™ÔÿšÓþ¡Øÿ¤ÚÿªÛü³àÿÅïÿÉîÿÇëÿÍîÿÑñÿ×÷ÿÛøÿÞúÿßüÿãþÿâûÿæþÿêÿÿéÿÿæÿÿçÿÿåüÿáúÿÎîûÁëÿ²áÿ•ÐúŽÎüŒÐÿ‘Îý—ÑÿÖÿžÕþ¤Øÿ¬Þÿ´áþ»åþÉíÿÌïÿÙöþáúþåýÿëÿÿíÿÿîþýîþýñÿÿðÿÿðþÿîþýîþýðÿÿëÿÿÝôúÞ÷þÝùÿØøÿÓôÿÏðÿÍòÿ¾éü»åý¼ãÿÁéÿÁëÿ½êÿ¿ìÿ½ëÿ·æÿ¨ÚÿÔû™ÓÿŒÉÿŒËÿ‰Êÿ‹ÌÿŒÏÿ‹ÎÿˆËÿ‰Êÿ„Çþ‚ÇþÆýƒÈÿˆËÿŒÎÿÏÿÐÿ“Ðÿ–Ðþ›Ôÿž×ÿ£Øÿ¦Úÿ¬Ýÿ¡Öö¤Ùù°ÞÿµàÿÃéÿÇìþÑõÿÓ÷ÿÅïÿ»åþµàÿ§Ùþ¥×ü§Ùþ­Ýÿ·åÿ·ãÿ»äÿÁçþ¿åüÄéüÉìÿÅëþ¾çû¿éÿÁëÿ¿éÿ´àù°Ýú£ÙÿšÓþ‘ÏÿÎÿ”Ñþ ×ÿªÞÿ¶äÿ¶ãÿÁéÿÆìÿÇëÿÒòÿÙöÿÚøÿÛ÷ÿãþÿãÿÿáúþæþÿëÿÿåúûãûýÚ÷ýÚ÷ÿÕñüÐîùÄçú½éÿ²ãÿ‘Ìø‡Çõ‹ÍÿÍü—ÐýŸÖÿ Õý¨Úÿ¯àÿ¼èÿ»åþÅëÿËïÿÓóÿÛøÿÜ÷þæþÿëþÿðÿÿïÿþïýýòþþóÿÿïýýïÿþðÿÿíÿÿäùþßöüÛöÿÚöÿØöÿÓóÿÒóÿÌñÿÊïÿÅéÿÊîÿÉîÿÊðÿÉïÿÁëÿ¹åÿ«Ùû¡×ý—Ðý“Íÿ’ÎÿÏÿ‘ÐÿÏÿŒÐÿ…Èÿ†ÈÿƒÆý…Êÿ‚Çþ‚Çþ…Èý‰Ëÿ‹Íÿ‘Ïÿ’Ïü•ÏýšÐüšÑú Õý¤Øÿ§Ùþ°âý±ãþ·ãþ¼äþÊëþÎîûÖ÷ÿÖ÷ÿÏóÿÇëÿÀçÿ­Þþ«Üü³áÿ¸åÿ¸äÿ¿éÿÁéÿÃéþÃéþÆëþÉìÿÁçþ»åýµãû²áû²àúªÛû¥ÚüšÕÿ”ÑÿŽÍÿŽÌý”Ñÿ¤Ùÿ­ßÿ»çÿ¾èÿÄêÿÆëþÈëþÐòþÔôÿÚøÿÙ÷ÿÝùýàùþàøüäüþåýÿáùýÝøÿÑòÿÌíþ¿ä÷»áø³àý¬áÿ£Úÿ‘ÎûÍýŽÎþ”Ñÿ˜Ñþ¡Öÿ£×þ®Þÿ³áÿ¾çÿ¿çÿÇíÿÊîÿÎòÿÕõÿÕóýÛöýäüÿìþÿîþþðþþóÿÿôÿÿõÿÿóÿÿíÿÿêüþáöûÝõùÝöýÜ÷ÿÜøÿÙ÷ÿÖöÿÍñýÌðþËîÿËîÿÉîÿÅìýÃêûºäü´àû¬Úû¦Øû ÕýœÒÿšÒÿ™Óÿ—Ôÿ’ÑýÏý„Æú…ÆþŠËÿˆËÿ†Éþ…Èý‡ÊÿÏÿÎÿÍü”Ïû™ÒÿÒúžÔú¥Ùþ«Ýÿ±âÿ¹éÿ¹çÿ»åý¿åüÎíÿÔòýØöþ×õýÒóÿÊìÿÆëÿ²áÿ®Ýû³àý¶âý·áùÂëÿÆìÿÆêÿÆëþÇìÿÉìÿÁçþ¼æþµäþ¯áü¬Û÷¥×øŸÕù“ÐýÍþÎÿÍþ•ÏýŸÓú§×û»äÿÀèÿÉîÿÊîþÊëúÎðüÐòüÖ÷ÿ×õýÚöúÜøüàùýäýÿáúþßøýÛøÿËðÿÅéÿµßø°ÜùªÜÿ¥Üÿœ×ÿÎýÍþÏÿ”Ñÿ˜Ñþ Õÿ¢Öý­Þÿ³àÿ½çÿÀèÿÈìÿËîÿËïÿÒóÿÑñþÙôýâùÿêüÿíüÿñÿÿóÿÿôÿÿõÿÿòÿÿìþÿéûÿâ÷üß÷ûáúÿÞùÿÜøÿ×õÿÓóþÊðûÈîûËðÿÌðÿÍòÿÅëþÁêü¶âû±Þû«Ùû¨Úû§Ûÿ¥Øÿ¡ÖÿÓÿ×ÿ–Ñû‘ÎúˆÈøŠËÿŒÎÿ‹ÍÿŠÌÿˆÊþŠÌÿÏÿÏÿÍü–ÏüœÒÿ Öü£×üªÜÿ®ßÿ¶äÿ¼éü½êýÄêýÉìÿØõÿÝùÿÚ÷ûÙöüÏïþÅçÿÆëÿºéÿµãý°Üõ³à÷¼åûÄêýÊïÿÊïÿËðÿÆëýÈëÿÁçþÀêÿºéÿ³äÿ°áÿ§ÙüŸÕû‘ÏþÏÿŽÍÿ•Òÿ˜ÓÿœÎó¥Óô¼äýÇíÿÕöÿÔöÿÓóþÏôýÎôýÔ÷ýÓôûÖó÷Ú÷ûãÿÿâþÿáüÿÛöÿÓðþÁéÿ¸áý¥Ö÷ŸÓú˜Õÿ“Óÿ‘ÑÿŠÉüŠÉüŽÌûÍü—Ðý¡Öþ¤Øý±àþ¹åÿ¿çÿÅëÿÉìÿÊêÿÄëüËðÿÍñÿÙ÷ÿÞùÿåøþéûýðþÿñýýóÿÿóÿÿðÿÿëýÿêýÿêÿÿéÿÿâûÿÜ÷ÿÛ÷ÿÔòüÎîùÄîúÅìýÉïÿÂêÿÁëÿ¼éþºèÿ°ßû©Úú¥×ú«Üü°áÿ®ÞÿªÛÿ¥Ùÿ¢ØþœÖûšÖû‘Îû‘Ïÿ‘ÐÿÎÿÏÿ‰Èû‰ÈûÍÿÎÿ“Íû™Òÿ Öÿ§ÛÿªÜý¬Ýý¯Ýþµâÿ¿éùÃêûÊîüÏðÿÙõÿÜùÿÚ÷ÿØôÿËêüÀâûÂçÿ¾ìÿ¼èÿ·äû¹ãù¾çûÄêýÉïÿËðÿËñÿÆëþÆêÿ¾çýÁëÿ¼ëÿ·æÿ°áÿ¦ØûÓùÍúŽÎþŒËþ—ÔÿœÕÿŸÑô¨×õÀæýËîÿØøÿÙ÷ÿÚ÷ÿÖ÷þÓöüÕöýÓôûÕòøÚ÷ýàüÿÞúþâýÿÜøÿÏïþ¼åÿ³àÿ¢ÖûžÕþ™ØÿŽÐÿÏÿˆÇú‡ÆùËþÍü˜Ñþ¥ÚÿªÜÿ¶ãÿ¾çÿÃèÿÈìÿÉìÿÉêýÃéüÊïÿÍñÿÛùÿÞùÿãøûçûüïÿÿîþþðÿÿóÿÿñÿÿëýÿêüþêýÿêÿÿÞ÷þØôÿØôÿÒðûËíùÃíýÁêþÄîÿ¸äý¶âûµâùµãû¬Ýû§Ùú¤Øý«Üü±ßÿ­Ýÿ«Ûÿ«Ûÿ¯ßÿ«àÿªÞÿœÒþ–Ðÿ“ÑÿÐÿÏÿˆÇú„ÆúÌÿÍþ”ÎüšÓþ¡×ÿªÞÿ¬Þÿ­Þþ¯Þü¶âýÎêöÏëöÖó÷ÚöúÜ÷þÚ÷ÿÔóÿÍíÿÂçÿ½çÿ»èÿÂìÿÂêÿ½æü½æüÂëÿÆìÿÆïÿÃëÿÆîÿ¾èÿ·ãü·ãü¸æþ¹çÿ¶ãÿ´âÿ©Ýÿ£Ùÿ•Ðú’Íù‘Ëû—Ïþ™Ðù­Ûü¹åÿÏòÿÕõÿãûÿäûÿâõûàøüÞ÷ûÔïøÑëøÑíùÔðüÛøþÛøþÜùÿÖòþËìý²ãÿ«ÛÿŸÔþ›Ôÿ”ÓþŽÏù‹ÎùŒÌüÌÿÍÿ’Îÿ™Òÿ¤ØÿªÜÿ·ãÿ¿æÿÈìÿÌïÿÎïÿÌíþÆìÿËïÿÐòþÛøþáúþãù÷äú÷çýûæÿÿäÿÿëÿþìÿýìþþìþþçûüäùüßøÿÙ÷ÿØõÿÍîÿÇìÿ¿éÿ½æÿ´áÿ²áÿ³àý¶âý¸äÿ©Úú£Øø¦Üÿ­Þÿ±ßÿ¯Ýþ³àÿ¶Ýú¾áýÌðÿÇìÿ²Ýý¤ØýžÕþ‘ÎûÍþ†Éý„ÇþŠÍÿ‹Îÿ‘Ïþ™ÓûŸÖýªàÿªßÿ±âÿ¶ãÿÀåÿÒðûÓñûÙøûÝúþÝúÿÜøÿÑðÿÅèþ¾æÿ»éÿ¹çÿÀêÿÁëÿ¿èþ¾çýÀæûÄêÿÅëÿ¿çÿÂêÿ»åþ±ßù±Þû²áý´ãÿ²àÿ°áÿ§Ûÿ¡Øÿ—Òü”Ïû’ÍùÔýŸÕû³àý¾èÿÎòÿÕõÿåþÿçþÿåøþäýÿàûÿÖòýÓïýÒïýÔòýÙ÷ÿÙ÷ÿÙ÷ÿÑîüÇèû°áÿ¨Øü›Ðü—Ðý‘ÐüŽÎúÍùŽÌûÍÿ‘Íÿ•ÏÿœÒþ§Øÿ­ÝÿºæÿÁéÿÊïÿÏòÿÐñÿÏïþÅêüÊîüÐòüÝúþäþÿåûùæüùéÿýåÿÿâþÿéÿÿêÿÿëÿÿìÿÿèýÿäüÿÝøÿ×õÿÔñÿÌíþÇìþ¼æÿ¹âþ²ßþ³àÿµáþºäý¼æÿ¯Þü¨Ûú©Þÿ¯Ýþ´ãÿ²ßþµâÿ½åþÄèþÐóÿÎòÿ¿éÿ­Þÿ¡Øÿ‘ÎûÎýˆËÿ„Çþ‡ÊÿˆËÿÎÿšÓþŸÖÿªàÿªßÿ´ãÿ¹åÿÄèÿÙ÷ÿÚøÿâÿÿäÿÿàÿÿÞüÿÊíÿ¿åü±Ýø³âü´ãý²Þù¸áýÀèÿÁêÿÁçüÆëþÃéþ½âüºßù¯Ûø©Úû¥×ü¥×ü§Ùþ¥ÙþŸÕû›ÕýšÕÿ™Öÿ™Öÿ©ßÿ´åÿ¶åÿ¾èþÄëüÌîøÒóúâþÿäÿÿåþÿÝûÿÙùÿÓóÿÑðÿÓòÿÓóÿ×øÿØùÿÖöÿÍìþÄçûªÜ÷¢ÔõšÏû™Ñÿ™Öÿ”Óÿ•Òþ—Òü—Òü›ÑýŸÔü¤Øý¯Ýþ´áþÁêÿËïÿÓôÿ×÷ÿÖôÿÓñüÌìùÍíøÓñûãüÿçÿÿêÿþêÿþçÿÿáúþÛ÷ûÛøÿÚ÷ÿÚ÷ÿÛöýÚõüÙôýÙõÿÔòýÏïüÌíüËïÿÀéÿºäý´àû·áú·áùÂèÿÅëÿºæÿ´áþ¯àÿ°ßû´ãýµãý¹æýÊïÿÒóÿØöÿÕõÿÏõÿ½êÿ­áÿ“ÎúŽÍùŒÎÿŠÍÿ„Çþ†ÉþÎÿ™Ôÿž×ÿ§Ýÿ©Ûüµâÿ½çÿÎîÿÙöþÚ÷ýâþÿåÿÿäÿÿáÿÿÍîÿÄèþ²Þ÷²âù´ãý±Ýú¶ßûÀèÿÅëÿÆëþÈíÿÆêÿ¾äûºßù®Ú÷©Ùÿ¡Õý Ôû ÔûŸÔüžÕü›ÖÿšÕÿ—Ôÿ—Öÿ­âÿºéÿ¼êÿÄíÿÊïÿÒôýÕöýÞûÿÞûÿÝúÿÕõÿÓóÿÐïÿÑðÿÒñÿÒòÿ×÷ÿØùÿÖöÿÎíÿÅêý¬Þ÷¤×öœÑýÓÿœÖÿšÔÿ›ÖÿžØþ ×þ¢Øþ¥Úü¬Ýý³àýºäýÄéüËîÿÔôÿÙ÷ÿÚøÿÙõÿÔòýÓïúÖóûäýÿèÿÿéÿýçÿÿæÿÿàüÿÞùÿ×õÿÔôÿÓóþÕóýÔòüÔðûÖòýÓñüÑñþÐñÿÐñÿÆìÿ¾æÿ¹ãü¹ãû¹âøÆëþÊíÿÁéÿ¸äý±àþ°ßû±àüµãý¹æýËðÿÖöÿÛøÿÚ÷ÿÖøÿÅðÿ³åÿ”ÏùÊ÷ŠÌÿ‹Ìÿ„Çþ†ÉþÍý–Óÿœ×ÿ¥Ûÿ§Ùú´áþ¾æÿÐðÿçÿÿçÿÿêÿþëÿþçÿýåÿÿ×õÿÏîÿÄêÿ¼éüºéý¹åÿ¹ãüÃéþÉîÿÐñÿÔõÿÔõÿÎñÿÇëÿ¼åÿ²âÿ¥Úÿ¢×ÿžÓý›ÒûŸÖÿ Úÿœ×ÿ—Òú›Ùÿ²áÿ¿çÿÀéÿÊîþÐñÿÕõÿÔôÿÎïþËìýÉìÿËïÿÊîþÍíÿÏïÿÐìÿÏìü×õÿØöÿ×ôÿÑðÿÊïÿ¶êÿ­àýÒþšÎþ“ËþŸÕÿ¢Ùÿ«àÿ°ãÿ¶åÿ¸æþÀêÿÆìÿÉìÿÎîùÔòýÙôýÚõüÜøüÞ÷üåþÿßøýáùýèÿÿëÿÿèÿÿæÿÿàüÿÛøÿÚöÿÏôÿÍôÿËðÿÌðÿÌîúÌì÷ÏíøÓñüÖöÿØøÿÕõÿÊíÿÄéüÁçþÀæû¿ä÷ÌíÿÏðÿÇëÿ¾æÿ±Þû°ßýªØù´áþ¸äýÊîþÕóþàùÿáúÿÚ÷ÿÈíÿ¸çÿ—ÑùÊö†Åø„Åû‚ÇþƒÈÿ‡ÉûÍü•Òÿ¡×ý¤Öù±Þû½åþÒñÿèüýìÿÿíÿüíÿúìÿüêþüâûÿÚöÿÍîýÉðÿÈòÿ½çÿ½åþÈëþÎïþÖôÿÙ÷ÿÚ÷ÿÔóÿÍîÿ¿äþ±Ýÿ§Ùþ¦Øý¨Ùÿ¨Üÿ§Ûÿ¥Ûÿ£Ùý¡Öø¢×ù´ÜöÆéÿÈëÿÐïÿÒòÿÔóÿÐñÿÃèÿ½äÿ±Þÿ´Þö¸á÷ÄêÿÉíÿÏîÿÏîÿÔòýÖôÿÕòÿÍìÿËïÿ¶êÿ©ÞýœÑû˜ÌûšÎþ¥Ùÿ¬Þÿ¶äüºçþÅîÿËñÿÍñÿÒòÿ×õÿÜ÷þÝöûäüÿåýÿæþÿêÿÿêÿÿéþÿéþÿçÿÿèÿÿâûÿâþÿØöþÏïüÌìûÄêýÁìÿÆíþÈíÿÍïûÎîùÒðúÕóû×óþÚöÿÚøÿÓóÿÍîÿÆëýÎñÿÑõÿÓóÿÒñÿÊíÿÁçþ°ÝüªÚþ§×ÿ°Þÿ¶áÿÊíÿÓðÿÝõÿß÷ÿÚöÿÆëþ²áýœÓú–ÑûŽÎþŒÎÿƒÈÿ„ÉÿŠÍÿÐÿ’ÐÿœÓü Ôù´áÿ¾èÿÐñÿèûÿëÿÿëÿûëþøìÿûêþüåüÿÝøÿÐðÿÌðþÊñÿ½çÿÁçüÍîýÓóþÛøÿÞùÿßúÿÙöÿÒòÿÄèþ´Ýû¬Úû¬Úû¯àÿ²ãÿ¯àÿ¯àÿ®ßÿ®Ýû®Ýû½áùÏïÿÔóÿØõÿØõÿÔóÿÎñÿ¿èÿ¶ãÿ§Øÿ©Øö­ÛõºãÿÀçÿËíÿÌïÿÏïþÎïþÍîÿÆéÿÅêÿ±äÿ©ÞþœÑû˜ÍùÐýªÜÿ°Þÿºäü¿èüËðÿÍñÿÑñüØôÿÛöýáùýãûÿèýÿéþÿéþÿëÿÿíÿÿéýþæûüæþÿèÿÿÝøÿÝúÿÑñüÇëûÅèûÁçü¾çûÂéúÈíÿÐòþÑñüØõýØõûÙôýÜ÷ÿÜùÿØöÿÓóÿÍñÿÑõÿÓ÷ÿÓóÿÒñÿÈìÿÀèÿ¯Þü¬Þÿ¥Öÿ­ÝÿµâÿÇëÿÐïÿÛóÿÝõÿÚöÿÃèû¯ÞúÓù™ÓûÐþŽÐÿ„Éÿ…ÊÿŠÍÿÏÿ’Ðÿ—ÐûžÔúµãÿ¼èÿÎñÿÛöÿàûÿåÿÿåýýêÿÿéÿÿáùÿÜöÿÑðÿËïÿÊïÿÆìÿÉîÿØöÿÝúÿåýÿêÿÿëÿÿáüÿÚ÷ÿÎîûÅèû¿åü¼åû¾æÿ¾èÿÁéÿÃëÿÇíÿÊîÿÈìÿËìýÖóÿ×ôÿØôÿÖôÿÍðÿÅëÿ¯Ýþ¦Úÿ™Óÿ–Ñù—Óø¡Öþ¨Ùÿ¶ãÿºæÿ½çÿ½êÿ»çÿ´áÿ°Þÿ§Üü§Ûÿ¤×ÿ¢Õÿ«Ýÿ²áý·äûÃéüÈëÿÏîÿØôÿÝøÿåüÿéþÿìÿÿëÿÿìþþìþþìþþìþÿîÿÿêþÿçüýáúþÝùýØöÿÔôÿÈíý½ãø¼âùÀæûÀåøÆéüÎïþÚøÿÜøÿÜ÷þàùýàùþÝöûÛôùÜ÷þÚøÿÔöÿÏðÿÎïþÏïþÊëü½ãú·ãü¬Ýþ¨Üÿ¥Úÿ¨Úÿ¬ÝýÄêÿÈëþÕóþÙ÷ÿÖöÿÀæù³áû¤ØýŸÖýÎý‹ÍÿÆÿ‚Çÿ…Èÿ‰ËÿŒËþ”ÎüšÓþ±ãÿ·æÿÈîÿÖôÿÜúÿáþÿáýÿåþÿåþÿÝ÷ÿÙôÿÐñÿËîÿÉîÿËðÿÏóÿÝûÿãÿÿêÿþëÿþëÿÿãüÿÜ÷þÔòýÐðÿÈëþÆëýÆëþÅëÿÉíÿÍðÿÎñÿÏðÿÏîÿÑñþ×õÿÖôþ×óþÔòüÈìü½æú§Øù¡×ý–ÓÿÐüÐü•ÒþÓÿªÛÿ­Þÿ®Ýù°âý°áÿ­ßÿ©Ûÿ¥Úü¥Ùÿ¥Ùÿ¤Øÿ¬Ýþ³áùºäúÅêüËìÿÐíÿÚõÿáúÿéþÿìÿÿíÿÿíÿÿíýýíýýïÿÿíÿÿíÿÿìÿÿéþÿàùýÚõüÕõÿÒôÿÈïÿ¼åûºâûÂæüÃèúËìýÐðýÛ÷ÿÞùÿâûÿæÿÿæÿÿáúþßøüÜøüÛøÿÔôÿÌíüÊëúÍîÿÈéü¸àù·ãþ«Ýþ¦Úÿ¦Ûÿ¥Úü©Úú¿èþÆêúÕõÿØùÿÕ÷ÿÀêú´âü¥Úü Øý‘ÏþÏÿÆÿ€ÅþÆý‡Èþ‹Êÿ‘Îý–Ñý§Ûÿ­Þþ¿éÿÇêýÏóÿÖøÿÔõþÑòûÑñüÑðÿÎïÿÈìÿÄêÿÄêýÊîúÐòüàüÿçÿÿìÿüíÿüìÿþéþÿçÿÿãÿÿÚ÷ýÖôþÔôÿÔöÿÔõÿÍîÿÖöÿ×÷ÿØôÿÛõÿÜùÿßüÿÞûÿÛùÿÖôþ¾ãõ´Þô¢×÷×ý‘Ñÿ‡Íÿ‡Íÿ‹ÍÿÎÿ˜Òÿ›ÔÿšÒ÷˜Ðõ™Ð÷Öÿ›Ôÿ ÔûŸÓú©Ýÿ®àÿµäÿ½çý¾çùÊëüÏîÿØóÿÜ÷ÿäüÿíÿÿîÿÿïÿþñÿÿîüýïýþòÿÿòÿÿñÿÿíÿÿêþÿâùÿÝøÿÑñüÎïþÍòÿÄêÿÀéÿÊíÿÐñÿ×÷ÿØöÿÞùÿâþÿãüÿåÿÿçÿÿéþÿéþÿÝöûÛöýÔôÿÌíþÊëüËïÿÊíÿ¾æÿ»çÿªÛü§Üþ¡×û§ÜüªÝúµàóÁæöØùÿÛüÿÕ÷ÿÅïý¼éÿ­ßÿ£Ûÿ‘ÑÿŽÐÿƒÈÿ‚Çÿ„ÇþˆÊþŒËÿ’ÐÿÍú˜ÏöŸÔö²àúÃèûËðÿÐôÿÍñÿÎòþËñüÅêúÅêüÂèû¿èüÆìÿÑñü×õÿãÿÿéÿÿêþýîÿÿîÿÿìÿÿêÿÿåÿþÞ÷ûÚõüØõýÔôÿÔõÿÔõÿÕõÿÖöÿÙ÷ÿÛøÿàûÿßúÿÝúÿÚøÿÒóÿ·ßø®Ûø¢Øþ›ÔÿÌÿ‡ÉýˆÊþÎÿ’Ðÿ”Îþ”Îü–Ïú–Ïú–Ïú™ÔÿœÕÿ Öü¡×ý©Þÿ¯âÿºèÿÁçüÅêüÎîûÑîüØôÿÛöýçÿÿíÿÿñÿÿñÿýõÿÿîüüïýýóÿÿðÿÿðÿÿíÿÿëÿÿäøÿßõÿÚôÿÖòÿÎïþÅéùÆìùÎðüÔòýÜùÿÞúýàúûÞúûåÿÿâþÿæÿÿíÿÿêþÿÜ÷þÛ÷ÿ×ôÿÈéüÂãöÌðÿÊïÿÃìÿÁëÿ¶âÿ¯Ýÿ«Ýÿ§ÙüªÛü´ÞöÀåøØöÿßûÿÝûÿÌîúÄêÿ«ÜüÓ÷ÏÿŒÏÿ…Êÿ‚Çþ…ÇûÎÿÎÿËý”Ìý›ÒûŸÓú­Þþ¼áü¼äý¿èþÃéþÁêü½æø¹âô·àô½æü¾æÿÁçþÎðüÑóÿÒîùÔïøà÷ýçüÿèýÿæþþçÿÿâþÿÝùý×óþÔòýÑòÿÑôÿÊíÿÍîÿÐðÿ×õÿÛøÿßøýÛöýØõýÑñþÉêûÀêÿ²ßÿ™Ðù•ÏýŠÌÿ‡Èþ‰ËÿÌÿÌÿ’Îÿ•Òÿ—Ñÿ”Íú”Íø˜Ñü›Õý Öú¤Øý®àÿ²ãÿ¼æÿÂçúÅèûÎîûÏïúÙõÿÞùÿçÿÿíÿÿðÿÿñÿÿðÿüïýýïýýïþÿíÿÿëÿþëÿþêþÿèûÿæúÿá÷ÿÜ÷ÿØöÿÐòüÎòþ×÷ÿÚøÿÛ÷úÝ÷øàúûßûüáþÿãÿÿæÿÿëýýæúûàûÿÞùÿØóÿÌëýÈéúÌðþÌòÿÉðÿÉïÿÀèÿ¶ãÿ®ßÿ¥Ö÷¨×õ·á÷ÈíÿÝúÿâþÿãÿÿØöÿÎóÿ®ÜýÓù‹ÍÿˆÍÿ…Êÿ‚ÇþƒÅùŒËþŽÍÿ‘Ïÿ“Ñÿ™Ôþ›Õý¦Üÿ¬×ù¯Úüµàÿ¶ßý·àüºãÿ¹ãü·ßù¾åÿÄéÿÂçÿÁçúÅêýËîÿÏðÿÏïü×õÿÙõÿÝúÿáþÿâÿÿ×÷ÿÍñÿÈëþÂèýÃéÿÈîÿÊíÿÌíÿÓðþÖòýÞ÷þÜ÷þÙöþÓóþÌíþ»åþ³áÿ›ÒûÌù†ÉþƒÈÿ†Éÿ…Èý†ÈüŽÍÿ“Ñÿ•Ïý›ÔÿžÔÿŸÖÿ¡×ý§Ùú«Ýþµäÿ¸åÿ¼æþÄêýÇêýÏðÿÐòþÛùÿàûÿåýÿíÿÿîÿÿðÿÿðÿüðÿÿðÿÿìþÿìþÿêýÿéþÿéþÿèýþèýþçÿÿäýÿÙöüÖöÿ×ùÿØöÿÜùÿãüÿäüþâüýàüÿÙøýßüÿäýÿåùúäøùÞ÷ûÝöý×ñþÔðþÓñüÒôþÐõþËðÿÊïÿ¾æÿ·åÿ«Üú©Úø¯ÞøÉòÿÑõÿâþÿæÿÿçÿÿÛùÿÍóÿ¥×ü—Î÷„Åû‚Äþ‚ÄþƒÆý‹ÊÿÎÿÏÿÑÿ‘Ôÿ”Õÿ”Óü×ý¦Òõ©Õø°Ûý¯Úü³Üü¸áÿ½æÿ½äÿ½äÿÄèÿÄéÿ¾çý½æüÄêÿÉíÿÍðÿÒóÿÓóÿÔôÿ×÷ÿØøÿÕöÿËðÿÅëÿ¾æÿ½åþÀèÿÆêÿÉìÿÒòÿÖôÿØóúÛöýÛöýÖöÿÐñÿ¼äþ·äÿœÖþÍú†Éþ„ÉÿƒÈÿƒÆý†ÇýŽÍÿÐÿ“ÐýÖÿ ×ÿ£Øÿ¥Ùþ¬Ýý¯àÿ¸åÿºæÿ¾æÿÅëþÇìÿÏðÿÐñÿÛùÿßúÿäüÿìÿÿìÿÿñÿÿñÿýðÿÿðÿÿìÿÿëþÿëÿÿêÿÿéþÿêÿþêÿþèÿÿåÿþÙõùÚøÿÙùÿØôÿÜ÷þåþÿæþÿáûüÝùüØöþÛùÿßûÿáôøáõöß÷ùßöüÛóÿØôÿØöÿÖøÿÕ÷ÿÌòÿÊïÿ½åþ°Ýú¨Ûø¯àþ´ãýÈòÿ×ùÿæÿÿéÿÿçÿÿ×øÿÄìÿžÒù“Ì÷„ÅûÃýÃýƒÆýŒËÿÏÿÏÿÒÿÔÿ”Õÿ”Óü›Õý±ßÿ®Üý³áÿ¸åÿºæÿ¼èÿÂìÿÅíÿ»àúÁæÿÂêÿ»çÿ½éÿºæÿ¸äÿ»çÿÁëÿÃèÿÄèþÇìÿÊïÿÈîÿÂêÿ½çÿ·ãÿµáþ¹âÿÀèÿÆìÿÐñÿÓóÿÔñùÛöýÞùÿâþÿÛûÿËðÿÁíÿŸÖý“Ðý‰Ìÿ‡ÌÿƒÈÿ‚Èü‰ÌÿÎÿŽÎþ–ÓÿœÓüžÓû§Ûÿ­ßÿµâÿ¶ãÿºæÿ¾èÿÀéÿÅëþÆëýÍîÿÍîÿÖöÿÝøÿáùýëÿÿêþýñÿÿòÿÿíýýìþÿëÿÿèýÿÞöÿÞ÷þÞ÷ûâûøãüøåÿûæÿýÞúýÞúÿÚøÿÙõÿÝøÿãüÿâùÿÜõúØóúÍíøÓóþÚöÿà÷ýåúýäùúâúþÞöÿÚöÿÚøÿ×ùÿÓøÿËðÿÇíÿºãÿ²àÿžÐó¨Úû°ÞÿÅîÿÎòÿáüÿâýÿÛöÿÄèø³ßü–Ëõ“ÍûŠÍÿ†Ëÿ‡ÉÿˆÉÿˆÇü‹ÉüŽÍÿ”Óÿ•Õÿ˜Õÿ˜ÓÿŸÔü¹æÿºçÿºèÿ¼èÿÁëÿÃíÿÀèÿÀæýÁåûÇìÿÈîÿ¾èÿ»çÿ¹åÿ¶ãÿ±Þý¶ãÿ¼åÿ»ãü»äúÃéþÁêÿ¾èÿ¹åÿ±Þý¯Üû´ßÿÂêÿÅêÿÏðÿÐïÿÏìôÚõüÝøÿÞúÿÛøÿÒöÿÇðÿ£Ùÿ“Îú‰Ëÿ†Éÿ†ÉþˆËÿ‹Îÿ‘Ðÿ‘Ñÿ–ÓÿÔý Öü«Ýÿ®ßÿ¶âý¸äÿ¾èÿ½çÿÁêÿÉîÿËîÿÌíþÌíþÏïúÙôýãûÿëÿÿìÿÿñÿÿñÿÿìüüîÿÿçüÿâöýÜ÷ÿØóüÙõùÞø÷ãþùæÿüæÿýàüÿÜøÿÖôÿÑíøÖñúâûÿãúÿ×òûÒîùÍïûÏñý×õÿßøÿß÷ûæûüãûÿß÷ÿ×óþÕóýÔöÿÒ÷ÿÇîÿÀéÿ¸ãÿ«Ûÿ¤Øÿ¥×üªÚþ»ãýÅèþÖòÿÛ÷ÿÖóÿÂæü°Ýþ—Íû‘Íÿ‹Íÿ„Éÿ…Çÿ‡ÈÿÊÿÎÿÎÿ’Îÿ–Ïÿ™ÑÿœÒþªÜÿÅðÿÈóÿÉòÿÅîÿÄêýÅëþÈíÿÇìüÆêøÈìøÉíûÅëÿ¿èþ¶âý³âÿ¬Þÿ©Ûþ«Üý®Ûø±Ýø¼æþ½åþ¾èÿ¼èÿµâÿ®Üý°Ýüºãÿ½åÿÆêÿÊíÿÖôþÛøÿÛøÿÜ÷ÿÙõÿÍîÿÄèÿ©ÙýŸÔþ‘ÏÿÏÿŽÎþÌÿÎÿÐÿÏÿšÕÿŸÖý£×ü­Þÿ¯Þü´àû¸âû¾æÿ¾æÿÅëÿÉîÿÊíÿÍìþÎîýÔòýÚõüäüþêþÿêþýîþýñÿÿìþÿëþÿäøÿßöþÓóÿÏïüÏðùÓðô×õ÷âþÿåÿÿßüÿÕòúÑïùÒðúÖóûßúÿßúÿÕñÿÎîýÇìÿÉîÿÎòÿÚøÿÛøÿàùþß÷ÿÙõÿÔôÿÒôÿÊðýÅïý¿éÿ¸äÿ«Øÿ¥Øÿ¡×ÿ Õÿ£×ÿ±Üþ¸ßüÄæÿÇéÿÁæÿ®Ûü¥Öþ•Ïý‘ÏÿŠÌÿ‡ÌÿŠËÿŠËÿŽÌýŽÌýŽÎþ–ËÿšÌÿ¢Òÿ©ÖÿºåÿÊòþÍõÿÏôÿÊïÿÇêýÈëþËïÿÊîüÌîúÍïùÍïùÈíÿÁçú´àù°ßýªÜÿ£×ü¥×ú©Øö®Ûø¹åþ½æü¾æÿ½çÿ·äÿ¯Ýþ±Þý¶âÿºäýÄêÿÉîÿÓóþÛøÿÚ÷ÿÛöÿØóþÌëýÃæü¬Ùú¤Õý˜Òÿ‘ÎýÍúÍü‘Ïþ“Ñÿ“Ñÿ™Ôÿ Õý£×ü¯Ýÿ¯Þü¶âýºãÿ¿çÿ¿èþÆìÿÊíÿÍîÿÎîýÏïüÖôþÚöúåúýêþÿëÿþïÿþðÿÿëÿÿéüÿà÷ýÞ÷þÒóÿÌðþÎðüÑïùÖôüàýÿâÿÿÝúÿÖóûÒðúÑïùÔòüÞùÿÞùÿÔñÿÎïÿÄêÿÄêÿÊïÿÖöÿÙ÷ÿÛöÿÚõÿÕòÿÏðÿÌðÿÄîþÀëüºæÿµâÿ¥Ôþ ÕÿÕÿŸÕÿ¡Öÿ®Úý´Ýý¼áü¿äÿ·âÿ§ÙüžÒú”ÎþÍÿ†Èÿ†ËÿŒÍÿŽÍÿŽÌûÍüŽÎü–ÊúÍý©Öÿ°Üÿ¿èÿÏïúÑñüÓóþÒòÿÏîÿÏîÿÏîÿÎîýÑñþÕõÿ×øÿÖôþÎðü¿èþ¶äþ©Þÿ£Ùÿ¢Öû§Ùú­Þþ»çÿÁêþÀæû¾çý»çÿ´áÿ±Þý³ßü¶âû¾çûÅëÿÎðüÛùÿÞûÿáúÿÞöÿÔðþÌëý¶Ýú®Úý¤×ÿ ÕÿÓÿ—Ðý–Ñý”Ñþ”Ñý™Ôþ¡×ý¦Úÿ±ßÿ¯Þü³àýµáü»åþ½æüÆëþÎïÿÑñÿÔòýÖôþÛöÿÝöûçüÿìÿÿìÿÿðÿÿìþþêýÿæûþâùÿàøÿÊðýÅìûÅìýÆéüËìý×ôÿ×ôÿÖôþÛùÿÙ÷ÿÏïúÑñüÚöÿÚöÿÒñÿÍðÿ¿éÿ¹åþ¼æüÊïÿÎòÿ×ôÿÖóÿÏðÿÄêýÀéý¸åú²âù«Ûÿ§ØÿœÐÿ•Îû•Ðü™ÒýŸÖÿªÜÿ¯Ýþ±Þû²áÿ«ßÿ Úÿ™Òý’ÏþÌÿÆÿ…ÊÿŒÍÿÌÿŽËø‘Ðü’Òþ Ôû¦Öú´âÿ»çÿÁéÿÔòüÔòüÖôÿ×ôÿÕòÿÓðÿÒïÿÑîþÑñþ×÷ÿÛùÿÙöþÓóþÄíÿ»çÿªßÿ¥Ûÿ£ÙýªÜý°áÿ¼èÿÃìÿÃéþÂëÿ¾êÿµâÿ²ßþ³ßü·ãü¼çúÂëÿÎòþÛùÿÝúÿâûÿáøÿÙóÿÔñÿÀåÿ´ßÿ¨Ùÿ¥Ùÿ¢×ÿœÒþšÓþ—Ôÿ–Óÿœ×ÿ£Ùÿ¨Ýÿ±ßÿ®Ýû°Ýú³ßú»åþ½æüÈíÿÎïÿÒòÿØôÿÙõÿÜ÷þáúÿéþÿìÿÿìÿÿïÿÿìþþêýÿçüÿçþÿãûÿÌòÿÄîþÅëþÄçûÈèýÏîÿÑðÿÔñÿÙ÷ÿÚøÿÑñüÓóþÙ÷ÿØõÿÏïÿÊîÿ½éÿ¶âý¸âúÄêýÉîþÐðÿÑðÿËîÿÁçü¼åû³áø¯Þø¤Õý Óþ›Ñÿ‘ÌöÎ÷•ÐúšÔú§Üþ­Þþ¯Þü¬Ýý¤Üÿ™×ÿ˜ÑüÍþ‰Ëÿ‚Çþ…ÊÿŽÐÿÏÿ‘Îú–Õÿ™Úÿ§Ýÿ­Þþ·æÿ½éÿÄíÿÚõÿÙôÿØóüÙôýÛöýÚ÷ýÚ÷ÿÚøÿÕõÿÖøÿÚúÿÜ÷ÿÚøÿËðÿÂëÿ°ßý¨Øþ¦Øý®ßÿ¶åÿÁîÿÆëþÈíÿÇíÿ¼èÿ¸æÿ³áûºæÿ½çÿÂèýÈíÿÖöÿÜ÷ÿáúÿéþÿéþÿäüÿßúÿÎïÿÂèý²Þû¬Üÿ¦ØýžÒùŸÔþŸÕÿ›Ôÿ¥Üÿ¨Þÿ§Ûÿ«Þý­àý¬Û÷¯Þú·ãü½çýÉîÿÓóÿØöÿÞùÿâûÿçÿÿçÿÿêÿÿìþÿîýÿïýþðþÿðþÿïþÿëÿÿëÿÿßüÿÙ÷ÿÑñüÍîýÎïÿÊîþÌíþÓðþÙöþÛöÿÞ÷üßøýÞùÿÚöÿÌðÿÉïÿµáú¬Û÷«Úøµäÿ½ëÿÆìÿÂèý¾èÿ·ãþ¯Þü¤ÙûœÓú’ÏüÎÿ‹ÊÿŠËÿ‘Ðÿ‘Îû–Ñû§ßÿ«áÿ©ßÿ¥Ûÿ›Ñÿ—ÑÿÌþÎÿˆÊþƒÈÿƒÊÿŒÏÿÏÿ’Ðù¡Ùü§Ýÿ±àþ´áþ»åþ¾æÿÊðÿÕñÿÔñÿÙõÿÝùÿàýÿàýÿÜùÿÛùÿÓóþÑóÿÓóþÚ÷ÿÜøÿÎòÿÇîÿ¸æÿ¯Ýÿ«Ûÿ°Þÿ´ãÿ»èÿÅëÿÆìÿÂêÿ¹åþ¶äþµãý»åý¿èþÇìÿÊíÿÏìúßúÿäýÿåúûçûüéÿÿçÿÿÚøÿÐñÿ½æü°ÝþªÛü§Ùþ¦Úÿ§Üÿ¦Ûÿ¤Ùÿ¨Üÿ§Üü¬ßü¯áü²ßü´âü»åýÀéýËïÿÕóýÙöþàùýãûýçÿÿçÿÿêÿÿíÿÿðÿÿôÿÿôþÿïýþîþþëÿÿëÿÿìÿÿçÿÿáýÿÜúÿÙùÿÒôÿÐòþÕóþàûÿåýÿëÿÿçÿÿáýÿÞûÿÑõÿËòÿµáúªÙ÷¦×÷©Ûþ°áÿ½æú½çý¹åþ´ãÿ­ßÿÔû“ÎúˆÇú†Èü€Åþ|ÁüƒÆý‹ÊýÍü™ÔþØÿž×ÿ›Öÿ•ÏÿÌþÍÿŠÉþ„Çû…Ëÿ‡ÍÿˆÌýŠÊø—Ñù®ãÿµæÿ¸åÿ¸åÿ»åþ½åþÅëÿÍìþÎîýÔñÿØöÿÝúÿÝúÿÝúÿÛùÿÖôÿÑñþÒòýØõýÚøÿÎòÿÈïÿ»éÿ®ÜÿªÚÿ°Þÿ´ãÿ¹çÿ¼æþ½åþ»åþ´âü´âü¶äþ¼æþÀéýÊíÿÍîÿÐíûßúÿãÿÿçüýéýþêÿÿçÿÿßüÿ×÷ÿÅêý³àý°ÞÿªÜÿ«Üÿ©Ýÿ§Üÿ¥Ùÿ«Ýÿ«Þý²áý´ãý¶âý¸äý¾çýÃéþÎïþÙõÿÝøÿãûýçüýéþÿèýþëÿÿðÿÿòÿÿõÿÿõÿÿòþþîüýìþÿìþÿëÿÿéÿÿåþÿàýÿÛùÿÒòýÑñüÖòýÞùÿãüÿéþÿäüüÝùýÜùÿÏóÿÉïÿ¶âûªØù¥Ö÷¦Øý¬Ýþ¼æü¿éÿ¹åÿ³áÿ®àÿÔý•Ðü‹Êÿ†ÉþÄý{ÀûÄý‡Éý‹ËûÎú“Ðý”Ñþ”Ñþ‘ÎýŽÌý‘ÏÿˆÊþ…ÇûˆÎÿŠÐÿŒÎÿŒÌúšÔú²äÿ¸çÿ¹æÿ¸åÿ·ãþ¹ãüÀéÿÃçÿÃçýÇêýÌíþÓóþÖôþ×ôü×óþÕóþÓðþÓïûÔðûÖôþÎòþÊñÿ»çÿ°Þÿ¬Üÿ¬Üÿ­Þþ­ßú¯Þú°ßý¯Þü¯Þü²áý·ãþÀèÿÆìÿÎïÿÐðÿØöÿÛøÿàüÿéÿÿëÿÿêÿþéþÿçÿÿäÿÿ×÷ÿÀèÿºçÿ°Þÿ«Ûÿ¨Úÿ§Ûÿ«Ýÿ±ßÿµâÿ»åý¼æþÁéÿÂëÿÈíÿËîÿ×ôÿÝøÿãúÿçûüçûúéüúëýýíÿþòÿþõÿÿ÷ÿÿöÿÿôÿþóÿýðþþðþÿíýüìÿýêþýçÿÿáúÿÖñúÖòýÙõÿÜ÷ÿÝöýèÿÿçÿýßûþÜùÿÊîþÄêÿ´áþ§×û£Õú¦×ÿ¬Üÿ¸äý»çÿµâÿ¬Þÿ§Ûÿ˜Ñþ’ÏþŠËÿ…Êÿ{Ãý}ÆýÊÿ€ÇÿÄýÃý‚ÃýƒÄú†ÈüŒÎþÏÿŽÍÿ‰Ëÿ†ÈüŠÍÿŒÏÿÍü‘Îú¡×ý¶åÿºæÿ¶åÿ´ãÿ°Þø²àúºäüÀåÿ¿äþÂæüÇêýÒòÿÖôÿ×óþ×óþ×óþÕñýÔðüÔðüÔòýÏóÿÌóÿ¹åþ°Þÿ­Ýÿ«Ýÿ¬Þÿ«Þý­Þþ¬Ýþ«Üý«Üü±àü¶âýÃìÿÈîÿÎïÿÐðÿÖöÿÛøÿÝøÿäüþéþÿëÿþéÿýèÿÿèÿÿÜùÿÆìÿÀêÿ±Þý¬Úü¨Úÿ©Ûÿ­Ýÿ³àÿ·ãþ½æü¾çýÂèÿÃéþÈëþÍîÿÖôÿßøýãûÿéýþêüüêýùìÿýïÿþòÿþõÿÿ÷ÿþöÿý÷ÿÿöÿÿñÿÿðþþïþûïÿüìÿýëÿÿäüÿÙôûØóüÚõþÜ÷ÿÛöÿäüüäýúßüÿÛùÿÉîÿÂëÿ±Þý¤Ôú Ñù¤Øÿ¬Ýÿ·äÿ¹æÿ´âÿ«ßÿ§Ýÿ–ÐþŽÌý†ÉÿƒÈÿ|Äþ}Æý€Ëÿ|ÄÿzÀü|ÀýÃÿÁû‚Åü‰ÍþÏÿŒËþÌÿˆÊþŠÌÿÏÿŽÍù“Îø¤Øýµäÿ¸äÿµäÿ°âý®Ý÷²àú¹åþ½æÿ¼åÿ½ãúÀäúÏðÿÕõÿÛ÷ÿÜ÷ÿÜ÷ÿÚõÿÙóÿÖóÿÕóþÍñýÈðü¼éÿ¯Ýþ­Ýÿ«Ýÿ©Þÿ©ßÿ§Ýÿ¢Øþ¢Öý©Ûþ°ßý»èÿÂëÿÇìÿÎïþÎîýÒôþÜúÿÜùÿÜõùâúþêÿÿèýÿêÿÿêÿÿãüÿÑòÿÈìÿ·ßù°Üù¬Ýþ­Ýÿ¯àÿ¸äÿ½çÿÃéþÄéüÄèþÆéýÑòÿÐñÿÖòýÞ÷üåúÿéýþéýüìÿýëýýìÿýðÿýóÿÿõÿÿôÿþõÿÿóÿÿñÿÿïýþòÿþïÿþìÿýêÿÿçüÿÞ÷üÛôûÖñúÜ÷ÿÝøÿâþÿÞûùÙ÷ÿÕ÷ÿÆìÿ½æÿ«ÙýÐûÐû¡Öÿ£ØÿªÜÿªÜÿ¨Üÿ¢ÙÿŸØÿ“ÑÿÎÿƒÈÿÇÿ‚Êÿ~Éÿ|ÇÿwÁþu¿þu¼þx¿ÿ{Áÿ{ÁüƒÉýŽÒÿŒÎÿÌÿÌÿÎÿ’Ðÿ˜Õÿ›Ôÿ¨Úÿ´áÿ¶áÿ²ãÿ¯âÿ¯áüµäÿºæÿ»çÿ¼åÿ½ãú¿ãùËìûÐðûÚ÷ÿÞùÿßúÿÚõÿØóþ×ôÿÔôÿÌðüÆîú¹æû¬ÚûªÚþ¥Ùþ¢Øü Øû¦Ýÿ¢×ÿ Õý¦Úÿ³âÿ¸åÿÀéÿÅëþÌðÿÎïþÑóýÚøÿÚøÿÚöúßøýèýÿæûÿåúýåýÿãüÿÔôÿÌïÿ½ãú¶àù¯Ýþ¬Ýþ°áÿ¹æÿ¾èÿÄêÿÆëþÅéÿÆéÿÎïÿÏðÿÖôÿàùÿäüÿéþÿëÿþìÿÿíÿÿìþþíÿþðÿýóÿÿðÿÿñÿÿòÿÿðÿÿîþþðÿÿïÿþíÿÿìÿÿèÿÿßøýÜõüÖñúÜ÷ÿÝøÿàüÿÜúüÔõþÐôÿÁéÿ¸ãÿªÚÿ Õÿ Õÿ Öÿ Öÿ Õý¡ÖþŸÖÿ›Ôÿ™Ôÿ‘ÏÿŒËÿƒÈÿ‚ÈÿÉÿ~ÇþzÅþxÂÿvÀÿu¿ÿw¾ÿ|Âÿ|Âþ‚Éÿ‹ÏÿŒÎÿŽÍÿŽÍÿÐÿ’Ðÿ˜ÒÿšÓþ¦Úÿ±ßÿ°Ýþ­ÞþªÝü®ßý¶åÿ¾êÿÀèÿÁéÿÇëÿÉìÿÐðûÔòüßúÿèÿÿèÿÿÞ÷þÚõÿØõÿÓóÿÌîúÅëøºåø°ßý«Ûÿ¢×ÿ ×þ›Õû›Ôÿ ÖÿŸÕÿ¢Öý°áÿ³àý¼æþÀéÿÈíÿËðÿÑóÿÕõÿÙ÷ÿÛ÷ÿÛöÿß÷ÿÝöýÛôùÞõûáúÿÚ÷ÿ×õÿÌïÿÂëÿ°Ýü¨ÙúªÜÿ¶åÿ¹åÿ¿èþÃéÿÆìÿÅëÿÉîÿÌïÿÓóÿÛ÷ÿßúÿäüÿåýÿèÿÿéþÿéþÿéþÿéþÿêÿþëÿÿìÿÿìÿÿêýÿêýÿéþÿæþÿåýÿâúþáøþÞ÷þÚõüÔñùØôÿÚöÿÜúÿÖ÷þÊîþÄêÿµàÿ¬Üÿ¡Öÿ›Óÿ™Óÿ•Ïý‘Îû‘Îý’Ïþ’Ïþ‘ÎýÍþ‰ÈýƒÄúƒÆý‚Çÿ}Ãþ}Ãþ}Ãþ|Äÿ|ÃÿyÃÿv½û|Âþ|ÂýƒÈÿŠÍÿŽÍÿ‘Ïÿ’Ðÿ“Ñÿ“Ðÿ“Íû–Ïü Õÿ¤Øÿ¦ØýªÜÿªÜý¯àÿ´ãÿ¸äÿÀæýÃéþÎñÿÓôÿÚøÿÜùÿâþÿåþÿåþÿàùþÜ÷ÿÒïÿÏïþÎðúÊðûÂíþ³âÿªÚþŸÔüžÕþšÓþ—ÑÿœÔÿÖÿ£×þ¬Ýþ±Þý¸äý¼æþÀéýÅëÿÏðÿÓóÿÕõÿÙõÿØòÿÙóÿÚôÿÜ÷ÿÜ÷ÿÛöÿßøýßøÿÕõÿËðÿ±àü©Úû¥×ü­Þþ³âÿ»åþ¼æþ¾èÿÂêÿÅëÿÇíÿËïÿÔôÿØöÿÛøþÞúþãüÿâûÿåþÿæÿÿãÿÿáýþäýÿãüÿãûÿáøþáøþÜ÷þÛøÿÚ÷ýÙôûÚõþÝøÿÜùÿÚöÿØöÿÙ÷ÿÕ÷ÿÎòþÀæû¸âû«Øÿ¦×ÿ™ÑÿÍüÍüÎýŽÎþ‹ÎÿŠÍÿ‹ÍÿŒËÿŒËÿŒËÿ‡Èþ‡Èÿ†ÉÿÆÿ„Æÿ„ÆÿÆÿÆþ~ÇþzÃú|Ãû|Áú„ÆÿÎÿÍÿ‘Ïþ’Ðÿ’Ðÿ’Ïþ“Íû•Ïý™ÒÿžÔÿ¡×ÿ¬Þÿ­ßÿ²àÿµâÿ¹åÿÂæüÆëþÏóÿÓõÿØöþÚ÷ýàùýàùýäüÿàùþÛöÿÑîÿÎîýÎðúÌòýÆñÿ¸çÿ°àÿ¥Úÿ¡Øÿ˜Óÿ˜Òÿ˜Ðÿ™Òý¡ÕüªÛü¯Üû·ãü¹æý¾éüÃìÿÏðÿÓóÿÔôÿÖóÿ×òÿ×òÿØôÿÚöÿÚöÿÚ÷ÿâúþáøþÖöÿÍòÿ´ãÿ¬Ýþ£×üªÛü±ßÿ·ãþ¶âû¹åþ½çÿ¾çýÄêÿÉíýÑñþÓóþØõýÚ÷ýßúÿÞùÿÝøÿÜøüÛøüÜúüÜøüÛ÷ûÝöûÝöýÞ÷þØõýØöÿ×õýÖóû×óþÛ÷ÿÛ÷ÿÚøÿØöÿÕõÿÒôÿËïýºãù±Ýú¦Öþ¡Ôÿ–ÎÿÍþÍþÏýŒÎþˆÍÿ‡ÌÿˆËÿˆÉÿˆÊþ‹ÊÿŠÉÿ†Çý…Èý…Çÿ…Åÿ„ÆÿÆÿ€Çý€Çý|ÃùÄû~Ãú…ÆÿËÿÍÿ’Ïþ’Ïþ’Ïþ‘Îý‘Îý“Ðÿ™Óÿ›ÔÿÖÿ¨ÙÿªÚþ¯Ýÿ²ßÿ¹åÿÆìÿËïÿÐñÿÑîþÔòýÓñûÙ÷ÿØùÿÛøüÝ÷øÝöûÐíûÏíøÖôþÙ÷ÿÔöÿÉïÿÁëÿªÚþ Ôü™Òÿ•Óÿ”Ðÿ•ÏýšÐüžÓû¨Ýÿ©Ýÿ­ßÿºæÿÁêÿÌïÿÓóÿ×óÿÙñûÚòüÙôÿØôÿØöÿÚöÿÜ÷ÿáúþãüÿÛûÿÑöÿ·äÿ­Þþ ÖüŸÖý ×þ¤Ûÿªàÿ¬ßþ­àý°ßû³áù¾éüÈïÿÌñÿÏóÿÎòÿÌðþËðÿÊïÿÊðÿÇíÿÈîÿÊïÿÍñÿÍñÿÏïüÏïüÑñþÍîýÏðÿÌíþÌíþÎïÿÐñÿÒóÿÍîÿÊëüÀéý¹æý«Üý¤Úÿ–ÐþÌû’ÎÿŽÌûÍû‹Òÿ‰Ïÿ‹ÌÿˆÉÿ‡ÊÿƒÈÿ‚Çÿ~Äÿ|Âþ‚Çÿ€ÅÿÆÿÆÿ‚Çÿ‚ÇÿÆÿÆý€ÅþƒÅÿ‚ÄþƒÅÿŠÍÿÐÿŠÎÿŒÐÿÏÿŽÍÿŽÌÿÎÿ—Ôÿœ×ÿœ×ÿŸÔþ¡ÔÿªÜÿ¯ÝÿµàÿÂçÿÇíÿÎïÿÐíýÒðûÒðûÓõÿÖøÿÛúÿÝ÷øÜõùÔòýÓñûÙöþÛøÿ×õÿËîÿÃëÿ°Þÿ¥Öþ–Ïü’Ðÿ’Îÿ•Ïÿ™ÒýŸÕÿ Ùÿ¤Ùÿ¨Üÿ¸äÿ¿çÿÊîÿÓóÿÙõÿÝôüÝôúÜ÷þÛøÿÚöÿÚöÿÝöýãüÿàüÿØøÿÎóÿ·åÿ®ßÿ¡Ùþ›Õý™Ôþ™Ôþ×ÿ¥Ûÿ§Üþ«Üü¯Þú¸åüÁêÿÄíÿÉïÿÈïÿÅëþÀéý¿èþÁëÿ¼èÿ¿éÿ¼æÿÁêÿÅëÿÉíýÌðÿÐñÿÍîÿÌðÿÈëþÈëÿÉìÿÉîÿÌñÿÊïÿÇìþ¾èÿ¸æÿ©Ýÿ Úÿ“ÐÿÌû’ÏþŽÍùŽÎü‹Òÿ‰ÏÿŒËÿˆÉÿ‡ÉÿƒÉÿÇÿ{ÃþyÀþ~Äÿ}ÃÿÅÿÅÿÆÿ‚ÇÿÆÿÆÿ€ÅþƒÅÿƒÅÿ„ÆÿŠÍÿ‰Ïÿ‡ÍþˆÎÿˆËÿŠÌÿŽÍÿÎÿ“Ðÿ™Ôÿ›ÖÿŸÕÿ Õÿ¨Üÿ­Ýÿ³àÿºãùÀéýÌðÿÏïþÒïýÎîýÌðþÎòÿÖöÿÜ÷þÜ÷þÚøÿÙ÷ÿÚ÷ÿÙöþÓñüÍðÿÅíÿ¶äÿ«Üÿ–Ìú’Ïþ•Ïý—Ðý›ÒûÔýšÔüŸÖý¤Øý²áýºãÿÃéÿÍìþÔñÿÞ÷üÞõûÞúþÞùÿßúÿâûÿæûÿåýÿÞúþÏïúÇìþ¸æÿ³äÿžÕü˜Òú™Ôþ—Òü—ÒüœÒþÔý£×þ¨Úý±Þÿ¶âÿ»äÿ¾çÿ½çÿºãÿ´àý³àÿ¶ãÿ²àÿ²Þÿ°Üÿ³Þþ·àü½åþÃéÿËðÿËïÿÉîÿÄèþÁçüÁæÿ¾æÿ¿çÿÁëÿ½çÿ­Úù®Üþ§Ûÿ ×ÿšÓþšÔüœÓü—Ñù“ÎúŽÎþŠÌþˆÇü†ÇýˆÊÿƒÉÿ€Æÿ}ÅÿzÁÿ{Áý|ÂþÅÿÅÿ€Åþ€Åþ€ÅþÄý€ÅþƒÅÿƒÅÿ†ÈÿŠÍÿˆÎÿ‡Íÿ‡Íÿ„ÇüˆÉÿÎÿŽÍÿËý“Ðý—ÑÿšÓÿœÒÿ£Øÿ§Øÿ¬Úü¸âøÀéýÌðÿÏïþÏïþÍîýÊïÿÉîþÑòÿÚöÿÛøÿÙ÷ÿÚøÿÛøÿÙöþÓñüÌïÿÃëÿ³áÿ©Ûÿ—Íù”Îü—Ðý›ÑýžÓûžÕüœÖþŸÖý¢Øþ­Þü´àýÀéÿËìýÐðýÜøüßøýáýÿáýÿâþÿåþÿêþÿåýÿÝùýÍíøÆëý¹çÿ³äÿ£ÚÿšÓþ˜ÓÿÍùÌø•Ïý—ÐýŸÔþ¤ØÿªÚþ³àÿµâÿ¸ãÿ¸ãÿ´áÿ±Þÿ¯Ýÿ°Ýÿ«Ûÿ¬Ùÿ­Úÿ°Üÿ²Ýý¹âþ¾æÿÈíÿÉîÿÈíÿÃéÿ¾æÿ»äÿ¹âþ¸äÿ¸åÿ³âþ¨Öø¨Øþ¤ÙÿŸÖýœÖü Øý¤ÚþŸÕûšÑúÍüŒÊý‡Æû„Åû†ÈÿÇÿ~Äÿ~Æÿ|Ãÿy¿ûzÀü}Ãþ€ÆÿÆÿ€ÅþÄý~ÃüÆÿƒÅÿ„Æÿ‡Éÿ‰Ìÿ†Ìÿ†Ìÿ…ÊÿƒÆý‡ÈþŽÍÿŽÍÿÍþ’Ïü“Ðý–Ðþ—ÏþŸÔÿ¢Öþ©×û»æùÂëÿÊïÿÌíþÌíþÉíýÄêÿÁçüÄéüÍìþÏìüÓñü×õÿÛøÿÚ÷ÿÖôÿÊíÿÂëÿ°Þÿ¦Øý›Ñý—ÐýŸÕÿ£Øÿ©Ýÿ§Þÿ¤ÛÿžØÿŸÖý§Ùü®Üý¼æþÍòÿÔöÿÜøüâûÿèÿÿçÿÿçÿÿêÿÿíýüëÿÿãüÿÒòýËïÿ´âüªÛûžÕü™Ôþ•Òþ’Ïû”Ñþ‘Íÿ‘ÍÿšÓÿžÔÿ¡Õý§Ùþ¨Øþ©ÙÿªÚþªÜÿ¬Þÿ¨Ùÿ¨Ùÿ¤×ÿ¦Úÿ£×ÿªÜÿ­Þÿµâÿ¸åÿ¿èüÅëþÁêþ¼æÿ¶âÿ¬ÚûªÛü©Ûþ¤Øý ÖúÐûžÑþÔýžÖû§Þü¬âþ¸êÿ³äÿ«ÝÿžÔÿ˜Òÿ‹Êÿ†Çý…ÇÿÅÿ}Ãþ|Äÿ|Ãÿx¾ú{Áý|ÂýÅÿÆÿÆÿÆÿÆÿ‚Çÿ‚ÄþƒÅÿ†Èÿ…Çÿ‚ÇÿƒÅÿ…Çÿ…Èÿ‡ÈÿŽÍÿŽÍÿÎÿÎÿÍþÎÿÍü—ÐýœÑû¨Úÿ¾éüÄïÿÌñÿËïÿËïÿÉîÿÂèý½æüÂæüÇèûÇçöÏìúÓñüÙõÿÙöþÖôÿÌðÿÆïÿ³áÿ¨ÚÿžÕþžÔÿ¤Ùÿ§ÜÿªÞÿ¨àÿ¦ÝÿŸÙÿ ×þ¨Úý°Þÿ¹ãüÎóÿÕ÷ÿÛ÷ûáúþåÿÿåÿÿçÿÿêÿÿïÿþîÿÿæÿÿÖôÿÌðÿ²Þù¦×÷¢Ùÿ›Öÿ•ÒþÍù’Ïü‘Ïÿ’Îÿ›Óÿž×ÿ Õý¤Øÿ¥×ü¦Øý§ÙþªÜÿ¥Ùÿ¡Õý¡Ôÿ Óþ¢×ÿ¥Ùÿ¬Þÿ®àÿ´ãÿ·äÿ½æúÂëÿ¿èþ¸äÿ³ßü¨Öø¥×ø£×üžÔúœÔù˜Ëø˜Ìû›ÒûŸ×ü¯åÿµéÿ¾îÿºéÿ°àÿ¤ØÿžÖÿÌÿ‡Èþ…ÇÿÅÿ}Ãþ|Äÿ}ÄÿzÀü}ÃÿÅÿ~Äÿ€Åþ‚ÇÿƒÈÿƒÈÿ‚Çÿ‚ÄþƒÅÿ†ÈÿƒÅÿƒÈÿƒÅÿ†Èÿ‡ÊÿˆÉÿÎÿŽÍÿÌÿŽÌýÍþÎÿÍü–Ïü›Ñý©Ûÿ \ No newline at end of file diff --git a/Extras/ode/drawstuff/textures/wood.ppm b/Extras/ode/drawstuff/textures/wood.ppm deleted file mode 100644 index 36f893db7..000000000 --- a/Extras/ode/drawstuff/textures/wood.ppm +++ /dev/null @@ -1,5 +0,0 @@ -P6 -# Created by Paint Shop Pro -256 256 -255 -ÛÛÛÐÐÐÇÇÇÉÉÉÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÃÃÃÌÌÌÌÌÌÇÇÇ¿¿¿°°°¬¬¬¸¸¸±±±±±±µµµ»»»»»»¼¼¼ÉÉÉØØØÕÕÕÔÔÔØØØâââêêêæææØØØÊÊÊÃÃÃÑÑÑÜÜÜîîîîîîäääçççäääÙÙÙÛÛÛÐÐÐÇÇÇÅÅż¼¼æææçççèèèæææÛÛÛæææèèèâââãããÛÛÛèèèçççæææãããàààâââçççêêêêêêëëëîîîñññòòòòòòñññïïïëëëçççääääääèèèêêêêêêççççççÝÝÝíííèèèÎÎÎÂÂÂÂÂÂÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÅÅÅÅÅÅÅÅÅÆÆÆÅÅÅÎÎÎÅÅ۰°´´´······ÍÍÍØØØÌÌÌ»»»¼¼¼ÇÇÇÐÐÐÊÊÊÉÉÉÎÎÎÀÀÀººº¾¾¾¸¸¸¼¼¼¾¾¾ÃÃÿ¿¿³³³³³³¼¼¼¿¿¿¸¸¸ÂÂÂÉÉÉÇÇÇ»»»¸¸¸ÅÅÅÑÑÑÕÕÕØØØÑÑÑÆÆÆØØØãããÒÒÒÉÉÉÉÉÉÆÆÆÍÍÍÊÊÊ»»»ÍÍÍäää×××ÐÐÐÐÐÐÔÔÔØØØØØØ×××ÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÇÇÇÊÊÊÍÍÍÌÌÌÀÀÀºººÅÅÅÇÇÇ»»»ÍÍÍÆÆÆÇÇÇÅÅÅ»»»»»»¿¿¿¸¸¸¸¸¸¿¿¿ÃÃÃÃÃÃÆÆÆÇÇÇÃÃÿ¿¿ÆÆÆÂ¸¸¸ÝÝÝçççØØØÇÇÇÐÐÐÍÍÍÕÕÕÔÔÔäääíííßßßÝÝÝãããÝÝÝÜÜÜÙÙÙÕÕÕÑÑÑÍÍÍÊÊÊÉÉÉÆÆÆÆÆÆÇÇÇÉÉÉÌÌÌÌÌÌÇÇÇÅÅÅÀÀÀÆÆÆÉÉÉÃÃø¸¸±±±±±±´´´³³³¿¿¿ÍÍÍÑÑÑÌÌÌÉÉÉÎÎÎÕÕÕÒÒÒÊÊÊÅÅÅÇÇÇÊÊÊÊÊÊÌÌÌÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÉÉÉÂÂÂÍÍÍÎÎÎÉÉÉÀÀÀ´´´­­­³³³³³³···ººº¸¸¸ºººÀÀÀÍÍÍ×××ÒÒÒÔÔÔÙÙÙâââèèèæææÛÛÛÐÐÐÌÌÌÎÎÎÑÑÑâââêêêæææçççàààßßßÜÜÜÑÑÑÌÌÌÅÅŸ¸¸ßßßçççßßßàààÛÛÛãããäääÝÝÝãããàààßßßâââæææçççççççççêêêíííêêêêêêèèèçççæææäääääääääãããßßßÝÝÝßßßâââãããâââßßßãããÜÜÜèèèÛÛÛ¼¼¼»»»ÀÀÀÀÀÀÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÆÆÆÇÇÇÇÇÇÉÉÉÉÉÉÊÊÊÀÀÀ±±±´´´»»»¿¿¿ÌÌÌÐÐÐÆÆÆ¿¿¿ÆÆÆÍÍÍÐÐÐÍÍÍÌÌÌÌÌ̼¼¼ºººÀÀÀ»»»ÀÀÀÀÀÀÃÃÿ¿¿¸¸¸ºººÂÂÂÃÃÿ¿¿¾¾¾ÂÂÂÀÀÀººº¼¼¼ÌÌÌ×××ØØØÕÕÕÎÎÎÂÂÂÒÒÒÝÝÝÐÐÐÊÊÊÊÊÊÇÇÇÂÂÂÃÃÃÂÂÂÔÔÔâââÒÒÒÍÍÍÑÑÑÔÔÔÕÕÕÕÕÕÒÒÒÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÅÅÅÉÉÉÐÐÐÊÊÊ»»»¸¸¸ÀÀÀÃÃõµµ´´´¿¿¿ÆÆÆ¼¼¼µµµººº¼¼¼ÀÀÀÃÃÃÃÃÃÃÃÃÆÆÆÇÇÇÀÀÀ¸¸¸ÉÉÉ¿¿¿±±±ÒÒÒÛÛÛÑÑÑÇÇÇÒÒÒÇÇÇÕÕÕÐÐÐäääçççÝÝÝÝÝÝàààÝÝÝÜÜÜÙÙÙÕÕÕÑÑÑÍÍÍÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÊÊÊÌÌÌÊÊÊÇÇÇÅÅÅÂÂÂÉÉÉÐÐÐÑÑÑÍÍÍÉÉÉÊÊÊÍÍÍÊÊÊÉÉÉÊÊÊÍÍÍÑÑÑÑÑÑÎÎÎÊÊÊÇÇÇÅÅÅÃÃÃÆÆÆÇÇÇÉÉÉÊÊÊÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÇÇÇÐÐÐÐÐÐÇÇǾ¾¾´´´°°°´´´···¾¾¾¾¾¾······ÃÃÃÑÑÑÕÕÕÑÑÑÒÒÒÙÙÙâââçççæææßßßØØØÒÒÒÌÌÌÅÅÅÑÑÑçççæææçççÝÝÝàààÙÙÙÐÐÐÎÎÎÃÃø¸¸ÝÝÝêêêàààãããßßßäääâââÛÛÛâââããããããçççêêêêêêçççæææèèèíííóóóóóóïïïêêêãããààààààãããëëëçççäääæææêêêëëëêêêèèèæææßßßíííØØØ´´´ºººÅÅÅ¿¿¿ÆÆÆÇÇÇÇÇÇÆÆÆÃÃÃÃÃÃÆÆÆÊÊÊÇÇÇÉÉÉÌÌÌ···´´´µµµ¿¿¿ÌÌÌÌÌÌÇÇÇÂÂÂÆÆÆÑÑÑÕÕÕÑÑÑÑÑÑÐÐÐÉÉÉ»»»ÂÂÂÉÉÉÃÃÃÊÊÊÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÃÃÃÆÆÆÃÃþ¾¾ÂÂÂÎÎÎÕÕÕÔÔÔÎÎÎÌÌÌÅÅÅÔÔÔÝÝÝÎÎÎÇÇÇÇÇÇÇÇǼ¼¼ÅÅÅÑÑÑ×××ØØØÐÐÐÎÎÎÒÒÒÒÒÒÒÒÒÑÑÑÍÍÍÌÌÌÊÊÊÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÆÆÆÆÆÆÃÃÃÀÀÀÌÌÌÑÑÑÀÀÀ´´´»»»ÅÅÅÆÆÆ¾¾¾¿¿¿ÅÅÅ»»»°°°µµµ¾¾¾¾¾¾¾¾¾ÀÀÀÃÃÃÉÉÉÍÍÍÇÇǼ¼¼ÊÊÊ¿¿¿¯¯¯ÎÎÎÕÕÕÎÎÎÉÉÉÒÒÒÀÀÀ×××ÊÊÊæææàààÝÝÝßßßßßßÜÜÜÛÛÛØØØÕÕÕÑÑÑÎÎÎÌÌÌÊÊÊÊÊÊÌÌÌÍÍÍÍÍÍÊÊÊÇÇÇÆÆÆÆÆÆ¿¿¿ÃÃÃÊÊÊÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÊÊÊÃÃÿ¿¿ÅÅÅÐÐÐÕÕÕÒÒÒÌÌÌÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÊÊÊÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐÒÒÒÐÐÐÌÌÌÇÇÇ¿¿¿³³³³³³ººº»»»¿¿¿¾¾¾···¸¸¸ÂÂÂÎÎÎÔÔÔÐÐÐÒÒÒÙÙÙàààäääæææãããààà×××ÌÌÌÀÀÀÊÊÊæææäääçççÝÝÝØØØ×××ÐÐÐÌÌÌÂÂÂÃÃÃâââíííàààÛÛÛÕÕÕÕÕÕÑÑÑÌÌÌÎÎÎÒÒÒÌÌÌÐÐÐÒÒÒÔÔÔÕÕÕÛÛÛäääíííøøøùùùöööñññèèèäääæææèèèêêêäääßßßÝÝÝâââæææèèèèèèçççßßßíííÙÙÙ³³³¸¸¸ÅÅÅ¿¿¿ÅÅÅÇÇÇÇÇÇÆÆÆÂÂÂÂÂÂÆÆÆÊÊÊÆÆÆÆÆÆÌÌ̺ºº°°°¸¸¸»»»ÇÇÇÔÔÔÎÎÎÅÅÅÀÀÀÇÇÇÔÔÔ×××ÒÒÒÐÐÐÒÒÒÇÇÇÀÀÀÍÍÍÔÔÔÎÎÎÒÒÒÒÒÒÍÍÍÍÍÍÑÑÑÐÐÐÉÉÉÅÅÅÅÅÅÊÊÊÍÍÍÊÊÊÃÃÃÀÀÀÅÅÅÉÉÉÉÉÉ¿¿¿ÅÅÅÆÆÆÛÛÛäääÕÕÕÎÎÎÍÍÍÆÆÆÂÂÂÒÒÒßßßÔÔÔÌÌÌÐÐÐÔÔÔÔÔÔÒÒÒÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÇÇǼ¼¼ÀÀÀÌÌÌÉÉÉ¿¿¿¼¼¼»»»ÍÍÍ»»»¾¾¾¿¿¿¾¾¾¿¿¿ÀÀÀÀÀÀÀÀÀÆÆÆÇÇÇÆÆÆÉÉÉÆÆÆ¼¼¼ÇÇÇ¿¿¿´´´ÕÕÕÛÛÛÔÔÔÌÌÌÐÐп¿¿ØØØÉÉÉèèèÝÝÝßßßâââßßßÜÜÜÛÛÛØØØÕÕÕÑÑÑÎÎÎÌÌÌÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÉÉÉÆÆÆÆÆÆÆÆÆ¿¿¿ÀÀÀÀÀÀÃÃÃÃÃÃÀÀÀ¼¼¼ººº······¸¸¸¾¾¾ÃÃÃÊÊÊÎÎÎÐÐп¿¿ÃÃÃÆÆÆÆÆÆÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÌÌÌÍÍÍÑÑÑÒÒÒ×××ÌÌÌÊÊÊÑÑÑÇÇǵµµ³³³¼¼¼¾¾¾ººº¸¸¸ººº»»»¾¾¾ÇÇÇÒÒÒÑÑÑÔÔÔØØØÝÝÝâââäääææææææÔÔÔÎÎÎÆÆÆÊÊÊèèèàààæææßßßÒÒÒÙÙÙÒÒÒÉÉÉÀÀÀÑÑÑççççççæææØØØÐÐÐÌÌÌÌÌÌÊÊÊÉÉÉÊÊÊÉÉÉÌÌÌÍÍÍÎÎÎÐÐÐÕÕÕÝÝÝäääëëëîîîñññîîîèèèææææææèèèæææßßßÕÕÕÑÑÑÕÕÕÝÝÝãããæææààà×××æææØØØµµµ´´´¼¼¼»»»ÃÃÃÅÅÅÆÆÆÃÃÃÀÀÀ¿¿¿ÃÃÃÉÉÉÉÉÉÉÉÉÌÌ̸¸¸³³³ÂÂÂÇÇÇÔÔÔÒÒÒÎÎÎÆÆÆÀÀÀÃÃÃÊÊÊÍÍÍÌÌÌÉÉÉÍÍÍÅÅÅÅÅÅÔÔÔÙÙÙÕÕÕÑÑÑÀÀÀÀÀÀÇÇÇÒÒÒÔÔÔÌÌÌÇÇÇÊÊÊÊÊÊÐÐÐÐÐÐÉÉÉÀÀÀÀÀÀÆÆÆÉÉÉÍÍÍÔÔÔÒÒÒßßßãããÐÐÐÉÉÉÇÇÇÍÍÍÑÑÑßßßãããÔÔÔÍÍÍÔÔÔÔÔÔÔÔÔÒÒÒÐÐÐÌÌÌÇÇÇÆÆÆÇÇÇÉÉÉÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÂÂÂÇÇǼ¼¼¾¾¾ÆÆÆÉÉÉÉÉÉÀÀÀ³³³¿¿¿ÂÂÂÀÀÀ¿¿¿ÃÃÃÇÇÇÀÀÀ¸¸¸¾¾¾ÂÂÂÌÌÌÌÌÌÅÅÅÆÆÆÉÉÉÀÀÀÇÇÇ¿¿¿¸¸¸ÙÙÙÜÜÜ×××ÍÍÍÍÍÍÃÃÃÕÕÕÌÌÌëëëßßßââââââàààÛÛÛÛÛÛØØØÕÕÕÑÑÑÎÎÎÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÆÆÆÅÅž¾¾¼¼¼¾¾¾¼¼¼···´´´±±±µµµººº»»»»»»»»»ÀÀÀÅÅÅ¿¿¿ÃÃÃÆÆÆÅÅÅÃÃÃÆÆÆÉÉÉÉÉÉÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÎÎÎÒÒÒÔÔÔÒÒÒÉÉÉÎÎÎÙÙÙÑÑѾ¾¾µµµ¸¸¸¼¼¼······¼¼¼¾¾¾¼¼¼ÃÃÃÎÎÎÕÕÕÕÕÕ×××ÙÙÙßßßãããæææçççÒÒÒÐÐÐÌÌÌÌÌÌíííÝÝÝâââÝÝÝÔÔÔÛÛÛÒÒÒÉÉÉÂÂÂÝÝÝêêêàààèèèÙÙÙÒÒÒÐÐÐÒÒÒ×××ÑÑÑÔÔÔØØØÛÛÛÛÛÛÛÛÛÛÛÛÙÙÙÛÛÛÛÛÛàààäääêêêíííëëëêêêêêêëëëêêêâââÙÙÙ×××ÛÛÛãããèèèêêêÝÝÝ×××âââ×××¼¼¼ººº¼¼¼¿¿¿ÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀÀÀÀÃÃÃÇÇÇÌÌÌÌÌÌÊÊʾ¾¾»»»ÉÉÉÔÔÔßßßÐÐÐÎÎÎÉÉÉÃÃÃÀÀÀÀÀÀÃÃÃÃÃÃÂÂÂÅÅÅÂÂÂÊÊÊÔÔÔ×××ÕÕÕÇÇǸ¸¸¼¼¼ÆÆÆÐÐÐÎÎÎÇÇÇÅÅÅÉÉÉÐÐÐÕÕÕ×××ÔÔÔÎÎÎÐÐÐÕÕÕÛÛÛÛÛÛàààØØØÙÙÙØØØÇÇÇÆÆÆÉÉÉØØØÝÝÝàààãããÜÜÜ×××ØØØÐÐÐÕÕÕÔÔÔÑÑÑÌÌÌÇÇÇÆÆÆÉÉÉÌÌÌÉÉÉÉÉÉÆÆÆÅÅÅÃÃÿ¿¿ÂÂÂÃÃÃÃÃÃÇÇÇÅÅŵµµºººÉÉÉÌÌÌÃÃÃÂÂÂÇÇÇÆÆÆÃÃÃÅÅÅÆÆÆÑÑÑÐÐÐÃÃÃÃÃÃÆÆÆ»»»ÉÉÉ¿¿¿···××××××ÕÕÕÐÐÐÎÎÎÌÌÌÎÎÎÎÎÎëëëâââäääàààâââÛÛÛÙÙÙØØØÕÕÕÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÃÃÃÀÀÀ¼¼¼ºººººº¼¼¼¾¾¾»»»¸¸¸µµµ···¸¸¸»»»¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÂÂÂÃÃÃÀÀÀÀÀÀÆÆÆÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒÕÕÕÑÑÑÍÍÍÔÔÔØØØÐÐÐÆÆÆ¿¿¿······¸¸¸»»»¾¾¾¿¿¿ÂÂÂÆÆÆÉÉÉÙÙÙ×××ÕÕÕ×××ÜÜÜâââææææææÔÔÔÑÑÑÍÍÍÊÊÊïïïÜÜÜßßßÙÙÙ×××ÕÕÕÍÍÍÌÌÌÊÊÊèèèëëëàààÝÝÝÒÒÒÔÔÔÑÑÑÒÒÒÕÕÕÎÎÎÕÕÕÎÎÎÎÎÎÑÑÑÔÔÔØØØÛÛÛÜÜÜÜÜÜßßßãããçççëëëîîîîîîîîîíííâââÝÝÝÛÛÛÜÜÜàààääääääãããÜÜÜÝÝÝàààÌÌ̼¼¼ÀÀÀÂÂÂÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÃÃÃÅÅÅÆÆÆÌÌÌÌÌ̾¾¾¾¾¾ÆÆÆ×××ÜÜÜÒÒÒÒÒÒÑÑÑÎÎÎÉÉÉÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÒÒÒÒÒÒÔÔÔ××׿¿¿¼¼¼ÅÅÅÎÎÎÑÑÑÌÌÌÆÆÆÇÇÇÍÍÍØØØ×××ÔÔÔÔÔÔÔÔÔÕÕÕØØØÙÙÙÉÉÉÑÑÑÊÊÊÐÐÐÒÒÒÌÌÌÔÔÔÝÝÝÙÙÙäääàààæææäääÙÙÙØØØÒÒÒÕÕÕÕÕÕÒÒÒÍÍÍÊÊÊÉÉÉÊÊÊÍÍÍÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀÅÅÅÅÅÅÀÀÀÅÅÅÆÆÆ¼¼¼³³³ÂÂÂÆÆÆÀÀÀÅÅÅÊÊÊÐÐÐ×××ÒÒÒÌÌÌÑÑÑÐÐÐÃÃÃÃÃð°°ÍÍÍ»»»ÙÙÙØØØØØØÕÕÕÐÐÐÔÔÔÆÆÆÑÑÑèèèæææãããÛÛÛàààÛÛÛÙÙÙ×××ÕÕÕÑÑÑÐÐÐÍÍÍÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÃÃúºº¸¸¸µµµ···»»»»»»ººº···µµµµµµ···ººº¾¾¾ÀÀÀÀÀÀ¿¿¿»»»¿¿¿¿¿¿¼¼¼¿¿¿ÆÆÆÊÊÊÇÇÇÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÌÌÌÎÎÎÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÔÔÔÕÕÕÔÔÔÔÔÔÕÕÕÐÐÐÇÇÇÌÌÌÉÉɺºº³³³ººº¿¿¿¾¾¾ÀÀÀÇÇÇÉÉÉÅÅÅÜÜÜØØØÔÔÔÕÕÕÛÛÛâââäääæææÕÕÕÑÑÑÌÌÌÇÇÇñññÜÜÜÝÝÝÕÕÕÕÕÕÎÎÎÆÆÆÍÍÍÑÑÑïïïíííäääÛÛÛÕÕÕÝÝÝÛÛÛØØØØØØÐÐÐÙÙÙÕÕÕÑÑÑÍÍÍÎÎÎÔÔÔÙÙÙÜÜÜÝÝÝÝÝÝßßßãããçççêêêëëëëëëêêêÜÜÜÜÜÜßßßäääèèèèèèãããÝÝÝÕÕÕÝÝÝØØØººº³³³¿¿¿ÀÀÀÃÃÃÇÇÇÆÆÆÅÅÅÃÃÃÅÅÅÆÆÆÆÆÆÇÇÇÇÇÇÇÇǸ¸¸ººº¼¼¼¿¿¿ÑÑÑÕÕÕÛÛÛÛÛÛÛÛÛÙÙÙÕÕÕÐÐÐÊÊÊÇÇÇÍÍÍÊÊÊÍÍÍÛÛÛÔÔÔÔÔÔÛÛÛ¼¼¼¿¿¿ÊÊÊÔÔÔÔÔÔÎÎÎÎÎÎÕÕÕÜÜÜØØØÐÐÐÆÆÆÅÅÅÉÉÉÊÊÊÆÆÆÀÀÀÂÂÂÍÍÍÉÉÉÍÍÍÐÐÐÉÉÉÑÑÑÙÙÙÕÕÕæææãããêêêèèèÕÕÕÔÔÔÙÙÙ×××ÕÕÕÒÒÒÐÐÐÌÌÌÊÊÊÍÍÍÎÎÎÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀÂÂÂÂÂÂÅÅÅ¿¿¿ÀÀÀÅÅÅÂÂÂÅÅÅÆÆÆ¿¿¿³³³¼¼¼¿¿¿ÃÃÃÊÊÊÅÅž¾¾ÀÀÀ¿¿¿···¿¿¿ÊÊÊÌÌÌ×××ØØØÃÃÃÎÎÎÆÆÆÂÂÂâââàààßßßÙÙÙÑÑÑØØØ¿¿¿ÒÒÒæææçççããã×××àààÛÛÛÙÙÙ×××ÕÕÕÑÑÑÐÐÐÍÍÍÌÌÌÉÉÉÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀ¼¼¼»»»ººº»»»»»»ºººµµµ±±±···¸¸¸ººººººººº»»»¾¾¾ÀÀÀ¿¿¿ÀÀÀ¿¿¿»»»¼¼¼ÃÃÃÆÆÆÅÅÅÊÊÊÉÉÉÇÇÇÉÉÉÌÌÌÎÎÎÎÎÎÍÍÍÒÒÒÑÑÑÎÎÎÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÎÎÎÕÕÕÒÒÒÇÇÇÇÇÇÎÎÎÌÌÌÀÀÀ³³³µµµººº¼¼¼¾¾¾ÀÀÀÅÅÅÇÇÇâââÜÜÜÕÕÕÒÒÒ×××ÜÜÜàààâââ×××ÐÐÐÑÑÑÊÊÊñññàààÝÝÝÛÛÛÐÐÐÌÌÌßßßêêêèèèëëëçççêêêÛÛÛÙÙÙØØØÕÕÕÔÔÔÒÒÒÒÒÒÑÑÑÎÎÎÒÒÒÕÕÕØØØÙÙÙÙÙÙÜÜÜßßßØØØâââäääàààäääîîîëëëßßßçççßßßãããèèèæææââââââßßßÙÙÙ×××ÌÌ̼¼¼¸¸¸ÂÂÂÇÇÇÅÅÅÉÉÉÅÅÅÇÇÇÉÉÉÅÅÅÇÇÇÌÌÌÉÉÉÐÐÐÆÆÆ¾¾¾¿¿¿Â¿¿¿¿¿¿ÀÀÀÃÃÃÉÉÉÑÑÑÙÙÙÜÜÜØØØÒÒÒÒÒÒÑÑÑÕÕÕ×××ÑÑÑÔÔÔÎÎμ¼¼ÍÍÍØØØÍÍÍÍÍÍÕÕÕßßßßßßÆÆÆÇÇÇÇÇÇÅÅÅ¿¿¿¼¼¼ÂÂÂÅÅž¾¾ÀÀÀÆÆÆÆÆÆÃÃÃÌÌÌÜÜÜßßß×××ÙÙÙÜÜÜÝÝÝÜÜÜÙÙÙ××××××ØØØÕÕÕÑÑÑÎÎÎÎÎÎÐÐÐÑÑÑÐÐÐÎÎÎÌÌÌÉÉÉÃÃÿ¿¿¼¼¼»»»¼¼¼¾¾¾¾¾¾ÆÆÆÆÆÆÂÂÂÂÂÂÃÃÃÌÌÌÛÛÛÃÃúºº¾¾¾ÎÎÎÂÂÂÍÍÍÎÎÎÇÇÇÃÃÃÌÌÌÉÉÉÆÆÆÊÊÊÌÌÌÎÎÎÛÛÛÊÊÊÆÆÆ¸¸¸ßßßÙÙÙÛÛÛÍÍÍÒÒÒ×××ØØØÆÆÆããããããÛÛÛÛÛÛÔÔÔØØØÕÕÕÒÒÒÑÑÑÐÐÐÍÍÍÊÊÊÆÆÆÇÇÇÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿»»»¸¸¸¸¸¸»»»ººº´´´´´´¸¸¸ºººººººººººº»»»¼¼¼¾¾¾¿¿¿¾¾¾ÀÀÀÀÀÀ¾¾¾¿¿¿ÅÅÅÆÆÆÅÅÅÉÉÉÇÇÇÇÇÇÊÊÊÍÍÍÎÎÎÎÎÎÍÍÍÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÌÌÌÎÎÎÍÍÍÉÉÉÊÊÊÐÐÐÎÎÎÇÇÇ¿¿¿»»»ººº¾¾¾ÃÃÃÆÆÆÇÇÇÙÙÙÙÙÙÛÛÛÜÜÜÝÝÝÜÜÜÛÛÛÙÙÙÐÐÐÊÊÊÍÍÍÉÉÉíííÝÝÝÛÛÛØØØÐÐÐÎÎÎãããíííëëëíííæææäää×××××××××ÕÕÕÔÔÔÔÔÔÒÒÒÒÒÒÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒ×××ÛÛÛßßßÝÝÝââââââßßßâââêêêëëëçççèèèâââçççîîîèèèãããàààÛÛÛÜÜÜÎÎξ¾¾¿¿¿ÂÂÂÅÅÅÇÇÇÉÉÉÅÅÅÇÇÇÉÉÉÆÆÆÉÉÉÍÍÍÊÊÊÎÎÎÅÅž¾¾ÀÀÀÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÃÃÃÅÅÅÇÇÇÌÌÌÒÒÒÙÙÙÝÝÝÕÕÕÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÌÌÌÀÀÀÉÉÉÔÔÔÌÌÌÌÌÌÑÑÑØØØàààÒÒÒÇÇÇÆÆÆÂÂÂÂÂÂÌÌÌÒÒÒÒÒÒÐÐÐÂÂÂÅÅÅÆÆÆÇÇÇÐÐÐÛÛÛÝÝÝ×××ÔÔÔÕÕÕ×××ÕÕÕÔÔÔÒÒÒÔÔÔÕÕÕÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÍÍÍÉÉÉÃÃÿ¿¿¾¾¾¾¾¾¾¾¾¾¾¾ÂÂÂÅÅÅÃÃÃÅÅÅÇÇÇÃÃÃÃÃÃÎÎÎÉÉÉ»»»»»»ÐÐÐÃÃÃÌÌÌÎÎÎÑÑÑÒÒÒÔÔÔÎÎÎÎÎÎÔÔÔÒÒÒÍÍÍÐÐÐÍÍÍÍÍÍ¿¿¿âââÛÛÛÛÛÛÐÐÐÔÔÔ×××ÙÙÙÉÉÉãããàààÙÙÙÙÙÙÔÔÔ×××ÕÕÕÒÒÒÑÑÑÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿»»»······ººººººµµµµµµ¸¸¸¸¸¸¸¸¸ºººººº»»»¼¼¼¿¿¿¿¿¿»»»¿¿¿ÂÂÂÀÀÀÃÃÃÆÆÆÇÇÇÅÅÅÇÇÇÇÇÇÉÉÉÌÌÌÎÎÎÐÐÐÎÎÎÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÉÉÉÇÇÇÇÇÇÊÊÊÍÍÍÎÎÎÎÎÎÎÎÎÇÇÇÀÀÀ»»»»»»ÂÂÂÅÅÅÃÃÃÀÀÀÐÐÐÔÔÔÙÙÙÝÝÝÜÜÜØØØÔÔÔÑÑÑÌÌÌÉÉÉÌÌÌÉÉÉçççÜÜÜÛÛÛØØØÑÑÑÒÒÒæææîîîíííîîîãããÜÜÜÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑ×××ÕÕÕÔÔÔÔÔÔØØØßßßãããæææãããâââßßßÜÜÜÝÝÝãããêêêïïïëëëäääçççêêêæææâââßßßØØØÙÙÙÅÅŸ¸¸ÂÂÂÇÇÇÂÂÂÃÃÃÊÊÊÇÇÇÃÃÃÇÇÇÉÉÉÆÆÆÊÊÊÎÎÎÌÌÌÉÉÉ¿¿¿ººº¾¾¾ÂÂÂÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÃÃÃÊÊÊ×××âââÛÛÛÙÙÙ×××ØØØÛÛÛÔÔÔÌÌÌÌÌÌÂÂÂÊÊÊÆÆÆÆÆÆÆÆÆÇÇÇÎÎÎÊÊÊÌÌÌÊÊÊÂÂÂÆÆÆØØØÙÙÙÔÔÔÙÙÙÅÅÅÆÆÆÉÉÉÎÎÎÕÕÕÙÙÙÙÙÙ×××ÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÒÒÒÎÎÎÐÐÐÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÉÉÉÃÃÿ¿¿¿¿¿ÀÀÀ¿¿¿¿¿¿¾¾¾¿¿¿¿¿¿ÃÃÃÊÊÊÅÅÅÀÀÀÆÆÆÔÔÔÅÅÅÆÆÆÜÜÜÎÎÎÌÌÌÉÉÉÍÍÍÆÆÆÐÐÐÒÒÒÐÐÐÍÍÍÇÇÇÉÉÉÐÐÐÊÊÊÐÐÐÉÉÉäääÝÝÝßßßØØØÜÜÜ×××ÛÛÛÍÍÍâââÜÜÜ××××××ÕÕÕ×××ÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¸¸¸µµµµµµºººººº······ººº¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÀÀÀ»»»ÀÀÀÃÃÃÂÂÂÃÃÃÇÇÇÉÉÉÆÆÆÆÆÆÇÇÇÉÉÉÍÍÍÐÐÐÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÊÊÊÆÆÆÆÆÆÌÌÌÎÎÎÌÌÌÌÌÌÎÎÎÉÉÉ»»»¸¸¸¼¼¼ÀÀÀÀÀÀ¿¿¿ÉÉÉÍÍÍÑÑÑÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÍÍÍÎÎÎÊÊÊãããÜÜÜÜÜÜÛÛÛÒÒÒÔÔÔæææëëëèèèëëëààà×××ÕÕÕÕÕÕ×××ØØØØØØÕÕÕÒÒÒÑÑÑÒÒÒÑÑÑÐÐÐÔÔÔÙÙÙÝÝÝààààààäääßßßÛÛÛÛÛÛÙÙÙÜÜÜæææñññèèèââââââãããÝÝÝÝÝÝßßßÙÙÙÎÎο¿¿»»»ÆÆÆÌÌÌÅÅÅÃÃÃÌÌÌÇÇÇÃÃÃÇÇÇÊÊÊÇÇÇÌÌÌÐÐÐÍÍÍÃÃü¼¼¸¸¸¼¼¼ÀÀÀÀÀÀÀÀÀÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÇÇÇÌÌÌÑÑÑ×××ÎÎÎÐÐÐÌÌÌÎÎÎÔÔÔÊÊÊ¿¿¿ÅÅÅ¿¿¿ÃÃÃÆÆÆÊÊÊÌÌÌÊÊÊÍÍÍÍÍÍÇÇÇÊÊÊÂÂÂÆÆÆØØØÕÕÕÐÐÐÝÝÝÎÎÎÌÌÌÎÎÎ×××ÛÛÛØØØÕÕÕÕÕÕÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÊÊÊÍÍÍÐÐÐÍÍÍÐÐÐÒÒÒÒÒÒÑÑÑÐÐÐÑÑÑÒÒÒÑÑÑÌÌÌÃÃÃÀÀÀÂÂÂÃÃÿ¿¿···ÀÀÀÀÀÀ¾¾¾ÃÃÃÇÇÇÆÆÆÇÇÇØØØÊÊÊÂÂÂÎÎÎÂÂÂÇÇÇÌÌÌÕÕÕÜÜÜ×××ÌÌÌÅÅÅÆÆÆÌÌÌÑÑÑ×××ÊÊÊ×××ÔÔÔçççÝÝÝÜÜÜÙÙÙÙÙÙØØØÝÝÝÒÒÒâââØØØÔÔÔÔÔÔ×××ÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÍÍÍÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¸¸¸´´´´´´¸¸¸ººº¸¸¸¸¸¸ººº¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÀÀÀ¾¾¾ÂÂÂÅÅÅÂÂÂÀÀÀÆÆÆÉÉÉÉÉÉÅÅÅÆÆÆÉÉÉÌÌÌÐÐÐÑÑÑÐÐÐÍÍÍÊÊÊÌÌÌÎÎÎÐÐÐÐÐÐÍÍÍÊÊÊÉÉÉÎÎÎÇÇÇÆÆÆÌÌÌÌÌÌÇÇÇÅÅÅÉÉÉÎÎÎÊÊÊ»»»¸¸¸ººº¾¾¾ÂÂÂÃÃÃÆÆÆÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÐÐÐÎÎÎÊÊÊÙÙÙÙÙÙÛÛÛÙÙÙÔÔÔÑÑÑãããæææãããäääÜÜÜ×××ØØØÙÙÙÛÛÛÛÛÛØØØÕÕÕÒÒÒÑÑÑÐÐÐÑÑÑÔÔÔÙÙÙÝÝÝàààßßßÜÜÜâââÛÛÛØØØÙÙÙØØØ×××ßßßêêêâââÝÝÝàààãããßßßààààààÙÙÙÀÀÀ¿¿¿ÃÃÃÊÊÊÌÌÌÆÆÆÆÆÆÌÌÌÉÉÉÅÅÅÇÇÇÊÊÊÇÇÇÌÌÌÑÑÑÎÎξ¾¾ºººººº¿¿¿ÂÂÂÂÂÂÅÅÅÉÉÉÅÅÅÅÅÅÅÅÅÉÉÉÍÍÍÎÎÎÌÌÌÉÉÉÇÇÇÊÊÊÇÇÇÌÌÌÑÑÑÇÇǼ¼¼ÃÃÃÇÇÇÃÃÃÃÃÃÅÅÅÆÆÆÅÅÅÃÃÃÅÅÅ¿¿¿ÉÉÉÆÆÆÊÊÊ×××ÑÑÑÐÐÐããã×××ÒÒÒÕÕÕÜÜÜÝÝÝÕÕÕÑÑÑÔÔÔÎÎÎÌÌÌÉÉÉÆÆÆÇÇÇÉÉÉÌÌÌÎÎÎÌÌÌÐÐÐÒÒÒÔÔÔÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÎÎÎÆÆÆÃÃÃÃÃÃÅÅÅ¿¿¿ÀÀÀÒÒÒÎÎμ¼¼»»»ÆÆÆÌÌÌÌÌÌÐÐÐÍÍÍÅÅÅÇÇǸ¸¸ÂÂÂÂÂÂÃÃÃÊÊÊÇÇÇÉÉÉÌÌÌÐÐÐÔÔÔ×××ÕÕÕÍÍÍßßßßßßçççÛÛÛØØØÕÕÕÑÑÑÛÛÛàààØØØâââÕÕÕÔÔÔÒÒÒ×××ÔÔÔÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÅÅÅÃÃÃÃÃÿ¿¿¾¾¾¾¾¾¼¼¼···³³³±±±···ºººººº¸¸¸ººº······¸¸¸ººº»»»¾¾¾ÀÀÀ¾¾¾ÃÃÃÆÆÆÂÂÂÀÀÀÃÃÃÇÇÇÇÇÇÅÅÅÅÅÅÆÆÆÊÊÊÎÎÎÐÐÐÐÐÐÎÎÎÊÊÊÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÎÎÎÉÉÉÆÆÆÉÉÉÉÉÉÃÃÃÂÂÂÃÃÃÎÎÎÑÑÑÑÑÑÍÍÍÆÆÆ¾¾¾ººº¸¸¸¾¾¾ÃÃÃÉÉÉÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÉÉÉÑÑÑÔÔÔ×××ÕÕÕÔÔÔÎÎÎßßßäääàààßßßÙÙÙÛÛÛÛÛÛÛÛÛÛÛÛÙÙÙØØØÕÕÕÒÒÒÑÑÑÔÔÔ×××ÛÛÛßßßããããããâââàààÝÝÝÙÙÙØØØÙÙÙÙÙÙÕÕÕØØØßßßÙÙÙÛÛÛâââçççäääæææããã×××¼¼¼ÃÃÃÊÊÊÍÍÍÊÊÊÊÊÊÊÊÊÌÌÌÊÊÊÆÆÆÉÉÉÌÌÌÉÉÉÌÌÌÑÑÑÎÎδ´´´´´¸¸¸¼¼¼¼¼¼¼¼¼ÂÂÂÉÉÉÊÊÊÇÇÇÅÅÅÆÆÆÌÌÌÍÍÍÊÊÊÆÆÆÉÉÉÌÌÌÌÌÌÎÎÎÑÑÑÌÌÌÇÇÇÉÉÉÉÉÉÀÀÀ¿¿¿»»»¼¼¼ÂÂÂÀÀÀÅÅÅÇÇÇÒÒÒÔÔÔÒÒÒÕÕÕÐÐÐÑÑÑàààÛÛÛ×××ØØØÛÛÛÙÙÙÒÒÒÐÐÐÑÑÑÐÐÐÍÍÍÉÉÉÇÇÇÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÐÐÐÒÒÒÔÔÔÔÔÔÕÕÕ××××××ØØØÒÒÒÊÊÊÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀÑÑÑãããÛÛÛÀÀÀºººÃÃÃÉÉÉÊÊÊÅÅÅÐÐÐÐÐÐÔÔÔÉÉÉÐÐÐÆÆÆÀÀÀ»»»ÀÀÀÍÍÍÔÔÔÑÑÑÐÐÐÑÑÑÎÎÎÉÉÉÝÝÝàààâââØØØÙÙÙÜÜÜÕÕÕßßßãããÜÜÜâââÒÒÒÕÕÕÑÑÑ×××ÒÒÒÐÐÐÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¸¸¸³³³±±±···ºººººº¸¸¸¸¸¸······¸¸¸ººº»»»¾¾¾ÀÀÀ¼¼¼ÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÌÌÌÎÎÎÐÐÐÎÎÎÊÊÊÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÉÉÉÆÆÆÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÊÊÊÎÎÎÒÒÒÔÔÔÐÐÐÇÇÇ»»»´´´¼¼¼¿¿¿ÃÃÃÉÉÉÌÌÌÍÍÍÌÌÌÉÉÉÊÊÊÍÍÍÎÎÎÍÍÍÑÑÑ×××ØØØÔÔÔÒÒÒÌÌÌÝÝÝèèèâââÛÛÛØØØàààØØØØØØ××××××ÕÕÕÔÔÔÒÒÒÑÑÑÕÕÕÕÕÕ×××ØØØÙÙÙÛÛÛÝÝÝßßßÝÝÝÛÛÛÙÙÙÙÙÙÙÙÙØØØ××××××ÕÕÕ×××ÝÝÝàààßßßâââàààÔÔÔÃÃÃÆÆÆÉÉÉÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÇÇÇÊÊÊÍÍÍÉÉÉÌÌÌÐÐÐÍÍÍ»»»¾¾¾ÂÂÂÃÃü¼¼···¼¼¼ÆÆÆÉÉÉÇÇÇÆÆÆÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÃÃÃÃÃÃÆÆÆÆÆÆÃÃÃÇÇÇÊÊÊÆÆÆÅÅÅÅÅÅÎÎÎÊÊÊÌÌÌÕÕÕ×××ßßßÔÔÔÛÛÛÝÝÝØØØÔÔÔÑÑÑÒÒÒÕÕÕÙÙÙ×××ÕÕÕÕÕÕÒÒÒÐÐÐÐÐÐÑÑÑÐÐÐÌÌÌÉÉÉÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÕÕÕØØØÙÙÙÙÙÙÙÙÙÕÕÕÎÎÎÉÉÉÅÅÅÂÂÂÀÀÀÀÀÀÑÑÑØØØÐÐп¿¿¾¾¾ÂÂÂÆÆÆÌÌÌÅÅÅÌÌÌÊÊÊÒÒÒÎÎÎÛÛÛÛÛÛàààæææØØØÐÐÐÍÍÍÍÍÍÒÒÒÕÕÕÍÍÍÊÊÊààààààÛÛÛÕÕÕÙÙÙãããÜÜÜãããæææààààààÒÒÒ×××ÑÑÑ×××ÑÑÑÐÐÐÎÎÎÍÍÍÍÍÍÌÌÌÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¸¸¸³³³±±±µµµººº¸¸¸······µµµ······ººº»»»¿¿¿ÀÀÀ»»»ÃÃÃÉÉÉÆÆÆÂÂÂÂÂÂÂÂÂÀÀÀÅÅÅÃÃÃÃÃÃÆÆÆÊÊÊÎÎÎÐÐÐÎÎÎÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÅÅÅÃÃÃÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÃÃÃÐÐÐÊÊÊÅÅÅÅÅÅÇÇÇÉÉÉÅÅÅ¿¿¿¼¼¼»»»»»»¾¾¾ÂÂÂÅÅÅÅÅÅÃÃÃÉÉÉÍÍÍÒÒÒÔÔÔÕÕÕÛÛÛÜÜÜ×××ÑÑÑÉÉÉÝÝÝíííäääÙÙÙØØØäääÕÕÕÔÔÔÔÔÔÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÝÝÝÝÝÝÛÛÛØØØØØØÛÛÛâââèèèàààÝÝÝÛÛÛÙÙÙÙÙÙÙÙÙ×××ÔÔÔ×××ÔÔÔÕÕÕÔÔÔÑÑÑØØØÜÜÜÒÒÒÍÍÍÆÆÆÅÅÅÊÊÊÎÎÎÎÎÎÎÎÎÐÐÐÍÍÍÉÉÉÌÌÌÍÍÍÉÉÉÌÌÌÐÐÐÍÍÍÑÑÑÕÕÕØØØÒÒÒÅÅÅ»»»¾¾¾ÇÇÇÂÂÂÅÅÅÇÇÇÇÇÇÃÃÃÃÃÃÆÆÆÊÊÊÆÆÆÃÃÃÇÇÇÅÅž¾¾ÉÉÉÑÑÑÊÊÊÎÎÎ×××çççÜÜÜÒÒÒÔÔÔÍÍÍÒÒÒÔÔÔØØØÛÛÛ×××ÔÔÔØØØÙÙÙÔÔÔÕÕÕÕÕÕÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÐÐÐÍÍÍÊÊÊÉÉÉÊÊÊÍÍÍÑÑÑÒÒÒÒÒÒÔÔÔÑÑÑÑÑÑÒÒÒ×××ÛÛÛÛÛÛÛÛÛÛÛÛØØØÑÑÑÊÊÊÃÃÃÀÀÀÀÀÀÀÀÀÂÂÂÀÀÀ»»»»»»ÀÀÀÂÂÂÃÃÃÎÎÎÑÑÑÑÑÑÌÌÌÔÔÔÊÊÊÍÍÍÊÊÊÕÕÕÒÒÒÌÌÌÐÐÐÑÑÑÎÎÎÒÒÒÙÙÙÕÕÕÙÙÙëëëæææØØØÐÐÐÔÔÔßßß××׿ææçççâââàààÒÒÒØØØÑÑÑ×××ÑÑÑÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÉÉÉÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾ººº³³³±±±µµµººº¸¸¸···µµµµµµ······ººº¼¼¼¿¿¿ÀÀÀÃÃÃÂÂÂÂÂÂÆÆÆÂÂÂÇÇÇÇÇǼ¼¼ÃÃÃÃÃÃÅÅÅÀÀÀÃÃÃÍÍÍÐÐÐÍÍÍÎÎÎÇÇÇÉÉÉÌÌÌÍÍÍÎÎÎÍÍÍÊÊÊÉÉÉÆÆÆÃÃÃÃÃÃÆÆÆÅÅÅÀÀÀÂÂÂÉÉÉÆÆÆÅÅÅÃÃÃÂÂÂÃÃÃÇÇÇÊÊÊÍÍÍÅÅÅÊÊÊÍÍÍÌÌÌÇÇÇÃÃÃÀÀÀ¿¿¿ÆÆÆÆÆÆÌÌÌÒÒÒÙÙÙÝÝÝÜÜÜ×××ÌÌÌÐÐÐÙÙÙâââßßß×××ÔÔÔÕÕÕÝÝÝÛÛÛØØØÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÙÙÙÙÙÙÛÛÛÝÝÝßßßààààààààà×××ØØØÙÙÙØØØÕÕÕÔÔÔÒÒÒÑÑÑÊÊÊÐÐÐãããßßßÔÔÔ×××ÕÕÕÕÕÕÔÔÔÃÃþ¾¾ÊÊÊÎÎÎÆÆÆÇÇÇÑÑÑÎÎÎÊÊÊÇÇÇÆÆÆÇÇÇÉÉÉÇÇÇÇÇÇÇÇÇÆÆÆÉÉÉÌÌÌÇÇÇÀÀÀÅÅÅÎÎÎÑÑÑÔÔÔÔÔÔÍÍÍÊÊÊÎÎÎÕÕÕ×××ÙÙÙßßßÒÒÒÂÂÂÅÅÅÊÊÊÊÊÊÍÍÍâââ×××ÐÐÐÐÐÐÐÐÐÍÍÍÎÎÎÔÔÔÒÒÒÔÔÔ××××××ÕÕÕÔÔÔÔÔÔÔÔÔÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÔÔÔÕÕÕ×××ÔÔÔÔÔÔÔÔÔ×××ØØØÙÙÙ×××ÔÔÔÜÜÜÙÙÙÒÒÒÒÒÒÛÛÛâââÝÝÝÔÔÔÃÃÿ¿¿¾¾¾ÀÀÀÂÂÂÂÂÂÆÆÆÊÊÊÍÍÍÐÐÐÒÒÒÑÑÑÎÎÎÌÌÌÊÊÊÌÌÌÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÒÒÒÒÒÒÒÒÒëëëÛÛÛßßßØØØÒÒÒÜÜÜÙÙÙÛÛÛêêêàààêêê×××ÑÑÑÐÐÐÔÔÔÍÍÍÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÀÀÀ¿¿¿ÃÃÃÃÃþ¾¾ÀÀÀ¿¿¿´´´µµµ¯¯¯³³³ººº···µµµºººººº»»»´´´³³³···»»»¼¼¼ÂÂÂÇÇÇÆÆÆÅÅÅÇÇÇÂÂÂÆÆÆÇÇÇ¿¿¿ÇÇÇÃÃÃÅÅÅÀÀÀÂÂÂÌÌÌÎÎÎÍÍÍÐÐÐÎÎÎÎÎÎÐÐÐÎÎÎÍÍÍÉÉÉÅÅÅÃÃÃÆÆÆÃÃÃÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÆÆÆÅÅÅÃÃÃÀÀÀÀÀÀÀÀÀÃÃÃÆÆÆÉÉÉÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉÌÌÌÒÒÒ×××ÔÔÔÕÕÕÙÙÙÜÜÜÜÜÜØØØÑÑÑÍÍÍÊÊÊÎÎÎ×××ÜÜÜÙÙÙÒÒÒÐÐÐÒÒÒÑÑÑÒÒÒÒÒÒÑÑÑÎÎÎÍÍÍÐÐÐÒÒÒÕÕÕ×××××××××ØØØØØØÛÛÛÜÜÜÝÝÝÝÝÝÜÜÜØØØÔÔÔÎÎÎÌÌÌÉÉÉÎÎÎÒÒÒæææäääÝÝÝàààÛÛÛ×××ÍÍÍ¿¿¿ÉÉÉÍÍÍÇÇÇÇÇÇÐÐÐÍÍÍÊÊÊÆÆÆÅÅÅÆÆÆÇÇÇÇÇÇÆÆÆÊÊÊÊÊÊÌÌÌÍÍÍÌÌÌÌÌÌÑÑÑ×××ÛÛÛßßßÝÝÝ×××ÑÑÑÒÒÒ×××ØØØÔÔÔÛÛÛÔÔÔÊÊÊÒÒÒÝÝÝâââäääÜÜÜÙÙÙØØØÙÙÙÙÙÙÕÕÕÑÑÑÐÐÐÒÒÒÔÔÔÔÔÔÔÔÔÑÑÑÑÑÑÒÒÒÔÔÔÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÑÑÑÑÑÑÑÑÑÒÒÒÔÔÔÕÕÕØØØØØØ×××ÕÕÕÕÕÕ×××ØØØÙÙÙÙÙÙÙÙÙÙÙÙÕÕÕÐÐÐÑÑÑÛÛÛææææææßßßÔÔÔÇÇÇ¿¿¿ÂÂÂÉÉÉÊÊÊÊÊÊÊÊÊÎÎÎÐÐÐÑÑÑÑÑÑÎÎÎÍÍÍÊÊÊÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÍÍÍÉÉÉÅÅÅÃÃÃèèèàààçççÝÝÝÕÕÕÜÜÜßßßäääíííâââêêêÕÕÕÑÑÑÐÐÐÕÕÕÐÐÐÒÒÒÑÑÑÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÉÉÉÃÃÃÀÀÀÃÃþ¾¾ÀÀÀÀÀÀ······°°°´´´»»»······»»»ººº´´´±±±³³³¸¸¸»»»»»»¾¾¾ÂÂÂÉÉÉÇÇÇÇÇÇÀÀÀÅÅÅÇÇÇÀÀÀÊÊÊÃÃÃÃÃþ¾¾¿¿¿ÊÊÊÎÎÎÍÍÍÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÇÇÇÃÃÿ¿¿ÅÅÅÅÅÅÅÅÅÆÆÆÅÅÅÀÀÀÂÂÂÅÅÅÃÃÿ¿¿¾¾¾¾¾¾¿¿¿ÂÂÂÃÃÃÉÉÉÅÅÅÀÀÀ¼¼¼»»»»»»ÀÀÀÅÅÅÊÊÊÌÌÌÍÍÍÑÑÑÔÔÔÒÒÒÐÐÐÑÑÑÊÊÊÎÎÎÕÕÕÜÜÜÛÛÛÔÔÔÔÔÔØØØÕÕÕØØØÙÙÙÔÔÔÊÊÊÆÆÆÉÉÉÍÍÍÌÌÌÍÍÍÐÐÐÐÐÐÎÎÎÑÑÑÕÕÕÙÙÙÛÛÛØØØ×××ÕÕÕÒÒÒÎÎÎÊÊÊÉÉÉÐÐÐÑÑÑâââãããßßßâââ×××ÌÌÌÅÅÅÀÀÀÂÂÂÆÆÆÉÉÉÇÇÇÉÉÉÍÍÍÊÊÊÉÉÉÅÅÅÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÊÊÊÉÉÉÉÉÉÊÊÊÑÑÑÕÕÕ×××ÐÐÐ×××ØØØÔÔÔÑÑÑÔÔÔ××××××ÙÙÙßßßØØØÎÎÎÑÑÑÙÙÙÜÜÜÝÝÝÙÙÙØØØÔÔÔÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÒÒÒÒÒÒÑÑÑÎÎÎÌÌÌÍÍÍÐÐÐÔÔÔÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÔÔÔÔÔÔÔÔÔÕÕÕ×××ØØØÛÛÛÜÜÜÙÙÙÙÙÙÙÙÙØØØØØØÙÙÙÛÛÛÝÝÝÛÛÛÕÕÕÐÐÐÑÑÑÛÛÛäääçççãããØØØÌÌÌÂÂÂÃÃÃÊÊÊÍÍÍÎÎÎÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÉÉÉÎÎÎÇÇÇÅÅÅÉÉÉÉÉÉÉÉÉÍÍÍÕÕÕßßßÝÝÝäääÜÜÜÑÑÑÕÕÕÝÝÝçççîîîãããêêêÔÔÔÒÒÒÑÑÑÕÕÕÔÔÔÒÒÒÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÊÊÊÊÊÊÆÆÆÃÃÃÃÃþ¾¾ÂÂÂÃÃúºº···³³³µµµ¾¾¾···ººº»»»ººº°°°´´´ººº¾¾¾¿¿¿»»»»»»ÀÀÀÇÇÇÇÇÇÉÉÉÀÀÀÃÃÃÆÆÆ¿¿¿ÉÉɼ¼¼¾¾¾ÉÉÉÍÍÍÍÍÍÑÑÑÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿ÂÂÂÅÅÅÂÂÂÀÀÀ¿¿¿¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿ÀÀÀ¿¿¿ÂÂÂÊÊÊÑÑÑÕÕÕÙÙÙÝÝÝÛÛÛÕÕÕÊÊÊÉÉÉÎÎÎÎÎÎÌÌÌÎÎÎÐÐÐÔÔÔÜÜÜããããããÝÝÝÝÝÝâââààààààßßßÙÙÙÒÒÒÍÍÍÍÍÍÎÎÎÌÌÌÐÐÐÑÑÑÐÐÐÌÌÌÌÌÌÎÎÎÒÒÒÑÑÑÎÎÎÐÐÐÔÔÔÕÕÕÕÕÕÕÕÕ×××ßßßÛÛÛçççèèèçççêêêÛÛÛÌÌ̾¾¾ÀÀÀÃÃÃÅÅÅÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÇÇÇÊÊÊÊÊÊÇÇÇÊÊÊÒÒÒÒÒÒÎÎÎÃÃÃÌÌÌÒÒÒÑÑÑÑÑÑÔÔÔÕÕÕÕÕÕÐÐÐÕÕÕÒÒÒÊÊÊÎÎÎÙÙÙßßßÝÝÝØØØØØØÒÒÒÊÊÊÊÊÊÑÑÑÕÕÕÒÒÒÒÒÒÑÑÑÍÍÍÉÉÉÆÆÆÉÉÉÎÎÎÒÒÒÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒ×××××××××ØØØÙÙÙÛÛÛÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜÙÙÙØØØÛÛÛÜÜÜßßßÙÙÙÔÔÔÔÔÔØØØÝÝÝÝÝÝÛÛÛÍÍÍÉÉÉÆÆÆÇÇÇÉÉÉÊÊÊÎÎÎÕÕÕÑÑÑÐÐÐÐÐÐÐÐÐÑÑÑÐÐÐÌÌÌÉÉÉÅÅÅÂÂÂÉÉÉ×××ÛÛÛ×××ÙÙÙãããÛÛÛÜÜÜßßßÙÙÙÒÒÒÔÔÔÝÝÝçççîîîäääêêêÒÒÒÔÔÔÒÒÒ××××××ÔÔÔÔÔÔÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÊÊÊÇÇÇÅÅÅÅÅÅÃÃÃÀÀÀÅÅÅÅÅźºº···µµµ···ÀÀÀ···¾¾¾»»»ººº±±±¼¼¼ÂÂÂÅÅÅÅÅÅ¿¿¿¼¼¼ÃÃÃÂÂÂÅÅÅÇÇÇÀÀÀºººÃÃÃÀÀÀ¼¼¼¼¼¼ÇÇÇÍÍÍÍÍÍÑÑÑÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆ¿¿¿¿¿¿¿¿¿¼¼¼»»»¿¿¿ÃÃÃÇÇÇÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¼¼¼ººº¼¼¼ÇÇÇÎÎÎÎÎÎÎÎÎÑÑÑää䨨ØÇÇÇÃÃÃÍÍÍÉÉÉÀÀÀÃÃÃØØØÜÜÜäääêêêèèèàààÝÝÝàààÝÝÝÛÛÛØØØØØØÜÜÜÝÝÝÜÜÜÛÛÛÙÙÙÝÝÝßßßÜÜÜÕÕÕÎÎÎÍÍÍÎÎÎÕÕÕÒÒÒÔÔÔÛÛÛÝÝÝÝÝÝàààäääæææÝÝÝççççççèèèîîîàààÑÑÑ»»»¿¿¿ÃÃÃÅÅÅÆÆÆÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÃÃÃÃÃÃÅÅÅÍÍÍÑÑÑÑÑÑÎÎÎÑÑÑÕÕÕÑÑÑÉÉÉÉÉÉÒÒÒÙÙÙÙÙÙ×××ØØØØØØÕÕÕÎÎÎÒÒÒÒÒÒÎÎÎÒÒÒàààèèèæææ×××ÛÛÛÙÙÙÔÔÔÒÒÒ××××××ÒÒÒÒÒÒÐÐÐÌÌÌÆÆÆÅÅÅÆÆÆÌÌÌÐÐÐÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒØØØØØØØØØÙÙÙÛÛÛÜÜÜÝÝÝßßßßßßââââââàààÜÜÜØØØØØØØØØßßßÛÛÛ×××ÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÌÌÌÉÉÉÊÊÊÎÎÎÐÐÐÎÎÎÐÐÐÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÒÒÒÑÑÑÍÍÍÉÉÉÉÉÉÉÉÉÒÒÒâââäääÜÜÜÜÜÜäääããããããÜÜÜÛÛÛÛÛÛÜÜÜãããçççëëëæææêêêÔÔÔ×××ÔÔÔÕÕÕ×××ÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÌÌÌÇÇÇÅÅÅÆÆÆÆÆÆÅÅÅÇÇÇÅÅÅ···¸¸¸ººº¸¸¸ÃÃ÷··ÀÀÀ¼¼¼ººº´´´ÂÂÂÇÇÇÅÅÅÆÆÆÀÀÀ¼¼¼ÃÃþ¾¾ÂÂÂÇÇÇÂÂÂÂÂÂÀÀÀ···¿¿¿¿¿¿ÀÀÀ¼¼¼¾¾¾ÉÉÉÎÎÎÍÍÍÑÑÑÍÍÍÍÍÍÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÃÃþ¾¾ÀÀÀ¿¿¿¼¼¼»»»¿¿¿ÅÅÅÆÆÆÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿¸¸¸ºººÇÇÇÒÒÒÕÕÕ×××ÛÛÛÒÒÒÎÎÎÂÂÂÅÅÅÑÑÑÌÌÌÀÀÀÇÇÇàààãããçççêêêãããÙÙÙÕÕÕ×××ØØØÔÔÔÑÑÑÕÕÕÝÝÝãããâââÝÝÝÜÜÜàààääääääâââÝÝÝÜÜÜÜÜÜãããààààààæææãããßßßâââèèèâââÛÛÛããããããäääíííâââ×××¾¾¾¿¿¿ÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÉÉÉÉÉÉÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÅÅÅÇÇÇÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÊÊÊÃÃÃÉÉÉÔÔÔÛÛÛÜÜÜÛÛÛÜÜÜÜÜÜÙÙÙØØØÙÙÙØØØÑÑÑÐÐÐÛÛÛãããÝÝÝØØØÙÙÙØØØÒÒÒÐÐÐÑÑÑÔÔÔÔÔÔÑÑÑÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÊÊÊÎÎÎÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒ××××××ØØØØØØÙÙÙÜÜÜÝÝÝßßßàààââââââàààÝÝÝÙÙÙ×××ÕÕÕÙÙÙÕÕÕÔÔÔÔÔÔÔÔÔÑÑÑÑÑÑÒÒÒØØØÑÑÑÎÎÎ×××ÜÜÜÛÛÛÒÒÒÎÎÎÒÒÒÒÒÒÒÒÒÔÔÔÒÒÒÑÑÑÎÎÎÌÌÌÍÍÍÍÍÍÕÕÕÝÝÝßßßÛÛÛÝÝÝäääääääää××××××ÜÜÜÜÜÜààààààçççäääêêêÕÕÕÙÙÙÕÕÕÔÔÔÕÕÕÕÕÕÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÇÇÇÅÅÅÆÆÆÇÇÇÆÆÆÉÉÉÅÅÅ···¸¸¸¼¼¼ºººÆÆÆµµµÃÃü¼¼ººº³³³ÅÅÅÆÆÆÂÂÂÅÅÅ¿¿¿ºººÀÀÀ¼¼¼ÂÂÂÇÇÇ¿¿¿µµµ¾¾¾¾¾¾ÀÀÀ¼¼¼¿¿¿ÌÌÌÎÎÎÍÍÍÑÑÑÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆÃÃÃÀÀÀÅÅÅÅÅÅÀÀÀ¿¿¿ÂÂÂÃÃþ¾¾¼¼¼¼¼¼¼¼¼»»»»»»»»»¼¼¼ººº±±±´´´ÅÅÅÒÒÒÕÕÕØØØÜÜÜØØØÛÛÛÕÕÕ×××ÜÜÜÐÐÐÇÇÇ×××äääãããäääãããÜÜÜÒÒÒÑÑÑÔÔÔÙÙÙ×××ÔÔÔÕÕÕÙÙÙÜÜÜÛÛÛÙÙÙ×××ÙÙÙÝÝÝâââããããããããããããäääâââãããæææâââÙÙÙÝÝÝèèèêêêäääíííëëëêêêïïïçççÜÜÜÃÃÃÀÀÀÀÀÀÆÆÆÊÊÊÌÌÌÊÊÊÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÆÆÆÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÑÑÑÙÙÙÛÛÛÙÙÙÛÛÛÙÙÙØØØÔÔÔÒÒÒÒÒÒÍÍÍÌÌÌÙÙÙæææàààÙÙÙ×××ÔÔÔÐÐÐÍÍÍÊÊÊÎÎÎÔÔÔÐÐÐÎÎÎÍÍÍÉÉÉÆÆÆÆÆÆÉÉÉÌÌÌÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÕÕÕÕÕÕ××××××ØØØÛÛÛÜÜÜÝÝÝàààßßßÝÝÝÝÝÝÜÜÜÛÛÛØØØ××××××ÒÒÒÑÑÑÒÒÒÒÒÒÑÑÑÔÔÔØØØÜÜÜÕÕÕÔÔÔÜÜÜãããßßßØØØÒÒÒÔÔÔÕÕÕ×××ÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÃÃÃÍÍÍÙÙÙââââââÝÝÝÛÛÛÜÜÜâââæææÕÕÕÔÔÔÙÙÙ×××ÛÛÛÜÜÜâââãããêêê×××ÝÝÝ×××ÑÑÑÒÒÒÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÌÌÌÊÊÊÅÅÅÅÅÅÆÆÆÅÅÅÉÉÉÆÆÆ¸¸¸¸¸¸¿¿¿»»»ÉÉɵµµÆÆÆ¼¼¼ººº´´´ÇÇÇÉÉÉÃÃÃÉÉɸ¸¸¾¾¾¾¾¾ÃÃÃÉÉÉÂÂÂÀÀÀ¿¿¿µµµ¿¿¿¾¾¾ÀÀÀ¾¾¾ÀÀÀÍÍÍÐÐÐÍÍÍÐÐÐÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆÃÃÃÉÉÉÊÊÊÆÆÆÃÃÃÅÅÅÃÃÿ¿¿»»»»»»»»»ººººººººº»»»»»»µµµ¯¯¯³³³ÆÆÆÔÔÔÔÔÔÒÒÒÔÔÔÕÕÕÝÝÝÛÛÛØØØØØØÊÊÊÌÌÌäääãããâââàààßßßØØØÒÒÒÔÔÔÛÛÛ×××ØØØØØØØØØ×××ØØØÙÙÙÛÛÛØØØØØØÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØÙÙÙØØØÛÛÛàààÛÛÛÔÔÔÛÛÛèèèëëëæææïïïëëëæææèèèÝÝÝÔÔÔÇÇÇÀÀÀ¿¿¿ÇÇÇÍÍÍÌÌÌÊÊÊÌÌÌÊÊÊÌÌÌÊÊÊÉÉÉÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÊÊÊÍÍÍÔÔÔ×××ÑÑÑÑÑÑÔÔÔÒÒÒÛÛÛàààÝÝÝÙÙÙ×××ÔÔÔÑÑÑÕÕÕÔÔÔÒÒÒÎÎÎÌÌÌÜÜÜèèèããã××××××ÛÛÛßßßÛÛÛÑÑÑÍÍÍÐÐÐÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÇÇÇÉÉÉÊÊÊÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÕÕÕÕÕÕÕÕÕÕÕÕØØØÙÙÙÛÛÛÜÜÜàààÝÝÝÛÛÛÙÙÙÛÛÛÜÜÜÛÛÛÙÙÙØØØÒÒÒÐÐÐÑÑÑÑÑÑÐÐÐÕÕÕÜÜÜÔÔÔÔÔÔØØØßßßàààÜÜÜÛÛÛÜÜÜÔÔÔÕÕÕØØØ×××ÔÔÔÑÑÑÐÐÐÑÑÑÐÐÐ×××ÜÜÜÜÜÜÙÙÙÙÙÙÛÛÛÜÜÜæææíííÜÜÜÙÙÙÜÜÜ×××ÝÝÝàààßßßãããëëëØØØàààØØØÐÐÐÐÐÐÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÌÌÌÌÌÌÆÆÆÅÅÅÃÃÃÃÃÃÉÉÉÆÆÆººº¸¸¸ÀÀÀ»»»ÊÊʵµµÇÇǼ¼¼ººº···ÌÌÌÍÍÍÉÉÉÎÎÎÇÇÇ»»»¾¾¾Â¿¿¿ÀÀÀÉÉÉÆÆÆ¾¾¾ÀÀÀÆÆÆ¼¼¼¿¿¿ÉÉɺººÕÕÕÎÎÎÕÕÕÐÐÐÌÌÌÍÍÍÇÇÇÉÉÉÑÑÑÑÑÑÍÍÍÍÍÍÌÌÌÌÌÌÎÎÎÒÒÒÒÒÒÎÎÎÅÅž¾¾¸¸¸···¸¸¸ººº»»»ºººµµµ³³³¬¬¬°°°ÂÂÂÑÑÑÐÐÐÍÍÍÐÐÐÑÑÑØØØÛÛÛÑÑÑÔÔÔÎÎÎÊÊÊÝÝÝçççÛÛÛãããÜÜÜÝÝÝ×××ÍÍÍÒÒÒÎÎÎÕÕÕÛÛÛßßßâââßßßÙÙÙ×××ÕÕÕÝÝÝÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜßßßÙÙÙÙÙÙÙÙÙÛÛÛÜÜÜßßßâââäääãããæææíííîîîççççççâââÔÔÔÕÕÕÎÎÎÂÂÂÀÀÀÌÌÌÎÎÎÌÌÌÎÎÎÊÊÊÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÆÆÆÆÆÆÊÊÊÐÐÐÔÔÔÔÔÔÒÒÒÔÔÔÔÔÔÔÔÔàààÙÙÙÕÕÕÕÕÕÕÕÕÒÒÒÒÒÒÔÔÔÒÒÒÎÎÎÐÐÐÍÍÍÆÆÆãããââââââßßßàààëëëíííÛÛÛÍÍÍÌÌÌÌÌÌÑÑÑÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÉÉÉÉÉÉÐÐÐÉÉÉÇÇÇÎÎÎÒÒÒÐÐÐÍÍÍÍÍÍÑÑÑÔÔÔÕÕÕ×××ÙÙÙÛÛÛÝÝÝâââÝÝÝÜÜÜÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙ××××××ÕÕÕÑÑÑÎÎÎÍÍÍÎÎÎÒÒÒÕÕÕÝÝÝÔÔÔØØØààààààßßßßßßÛÛÛÛÛÛÜÜÜÙÙÙÕÕÕÕÕÕØØØÕÕÕÎÎÎÊÊÊÔÔÔÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜÛÛÛãããÝÝÝãããèèèàààÜÜÜßßßÝÝÝäääâââèèèèèèÛÛÛÒÒÒÒÒÒÒÒÒÕÕÕ×××××××××ÔÔÔÑÑÑÍÍÍÊÊÊÂÂÂÅÅÅÆÆÆÉÉÉÉÉÉÇÇÇÆÆÆÅÅž¾¾ÆÆÆÍÍÍÅÅż¼¼ÃÃÃÆÆÆ¾¾¾¸¸¸ÊÊÊÊÊÊÌÌÌÍÍÍÉÉÉÍÍÍÎÎÎÆÆÆ¿¿¿ÂÂÂÆÆÆÅÅÅ¿¿¿¼¼¼ÆÆÆ¾¾¾¾¾¾ÃÃ÷··ÑÑÑÌÌÌÒÒÒÌÌÌÌÌÌÑÑÑÎÎÎÍÍÍÑÑÑÎÎÎÊÊÊÎÎÎÌÌÌÍÍÍÐÐÐÒÒÒÒÒÒÎÎÎÇÇÇÂÂÂÅÅÅÃÃÃÂÂÂÀÀÀÀÀÀ¼¼¼¸¸¸´´´¯¯¯³³³ÆÆÆÒÒÒÊÊÊÉÉÉÐÐÐÐÐÐÔÔÔ×××ÑÑÑÕÕÕÐÐÐÇÇÇÔÔÔØØØÛÛÛÝÝÝÕÕÕØØØÔÔÔÍÍÍÑÑÑÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÜÜÜÝÝÝÜÜÜÙÙÙ××××××ÔÔÔÒÒÒØØØØØØØØØÙÙÙÛÛÛÝÝÝßßßàààâââàààäääççççççêêêæææÙÙÙØØØÕÕÕÉÉÉÂÂÂÊÊÊÌÌÌÉÉÉÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÉÉÉÑÑÑÌÌÌÊÊÊÎÎÎÑÑÑÒÒÒØØØàààßßßÙÙÙÕÕÕ××××××ÔÔÔÒÒÒÕÕÕÔÔÔÑÑÑÐÐÐÌÌÌÅÅÅââââââàààãããâââçççççç×××ÍÍÍÍÍÍÍÍÍÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÒÒÒÍÍÍÊÊÊÍÍÍÐÐÐÎÎÎÍÍÍÐÐÐÌÌÌÐÐÐÔÔÔÔÔÔÔÔÔÕÕÕÜÜÜãããÝÝÝÜÜÜÛÛÛÙÙÙÙÙÙØØØ×××ÕÕÕÐÐÐÎÎÎÍÍÍÎÎÎÑÑÑÔÔÔ×××ØØØØØØÑÑÑØØØãããâââÝÝÝÙÙÙÒÒÒàààâââßßßÛÛÛÙÙÙÙÙÙÔÔÔÍÍÍÐÐÐØØØßßßßßßßßßâââãããâââÝÝÝØØØÝÝÝãããÝÝÝÜÜÜââââââäääßßßâââÝÝÝÐÐÐÇÇÇÌÌÌÍÍÍÑÑÑÒÒÒÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÑÑÑÇÇÇÃÃÿ¿¿¾¾¾¾¾¾ÃÃÃÇÇÇÌÌÌ···ÃÃÃÎÎÎÇÇÇ»»»¾¾¾ÃÃþ¾¾ºººÌÌÌÊÊÊÊÊÊÌÌÌÆÆÆÊÊÊÌÌÌÌÌÌ¿¿¿ÂÂÂÅÅÅÀÀÀÃÃúººÆÆÆ¿¿¿»»»¾¾¾´´´ÍÍÍÉÉÉÐÐÐÉÉÉÊÊÊÔÔÔÔÔÔÑÑÑÑÑÑÊÊÊÇÇÇÎÎÎÊÊÊÍÍÍÒÒÒÔÔÔÒÒÒÎÎÎÊÊÊÉÉÉÌÌÌÊÊÊÇÇÇÆÆÆÅÅÅÀÀÀ»»»¸¸¸¯¯¯°°°ÇÇÇÒÒÒÆÆÆÆÆÆÒÒÒÑÑÑÑÑÑÒÒÒÍÍÍÐÐÐÍÍÍÉÉÉÑÑÑÔÔÔÜÜÜÛÛÛÒÒÒÔÔÔÒÒÒÐÐÐÔÔÔÐÐÐÑÑÑÎÎÎÊÊÊÉÉÉÉÉÉÌÌÌÍÍÍÍÍÍÑÑÑØØØÛÛÛØØØÙÙÙßßßßßßÙÙÙÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÝÝÝßßßßßßâââÜÜÜßßßâââäääëëëëëëâââ×××ÛÛÛÐÐÐÅÅÅÇÇÇÌÌÌÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÇÇÇÅÅÅÆÆÆÉÉÉÍÍÍÒÒÒÅÅÅÀÀÀÌÌÌÔÔÔÕÕÕÜÜÜèèèÝÝÝØØØÕÕÕØØØØØØÕÕÕÔÔÔÕÕÕÔÔÔÔÔÔÎÎÎÊÊÊÃÃÃàààããããããêêêããããããàààÒÒÒÌÌÌÎÎÎÐÐÐÑÑÑÎÎÎÍÍÍÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐ×××ÑÑÑÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÑÑÑÐÐÐÒÒÒ×××ÒÒÒÊÊÊÊÊÊÒÒÒÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛØØØÕÕÕÒÒÒÒÒÒÍÍÍÌÌÌÊÊÊÍÍÍÒÒÒ×××ØØØ×××ÜÜÜ×××ßßßêêêêêêèèèæææßßßäääæææäääàààÝÝÝÜÜÜ×××ÑÑÑÑÑÑ×××ÛÛÛÜÜÜßßßæææèèèèèèàààÛÛÛÝÝÝâââÝÝÝÝÝÝäääçççêêêäääæææâââÒÒÒÉÉÉÌÌÌÍÍÍÑÑÑÑÑÑÐÐÐÐÐÐÑÑÑÑÑÑÒÒÒÔÔÔÍÍÍÉÉÉÃÃÿ¿¿ÀÀÀÆÆÆÎÎÎÔÔÔ»»»ÆÆÆÕÕÕÑÑÑÂÂÂÀÀÀÇÇÇÅÅż¼¼ÎÎÎÌÌÌÊÊÊÊÊÊÅÅÅÇÇÇÉÉÉÎÎξ¾¾ÂÂÂÃÃþ¾¾ÉÉɸ¸¸ÉÉÉÃÃû»»»»»µµµÊÊÊÉÉÉÎÎÎÇÇÇÊÊÊÒÒÒÒÒÒÑÑÑÑÑÑÌÌÌÆÆÆÊÊÊÆÆÆÍÍÍÕÕÕ×××ÔÔÔÐÐÐÍÍÍÍÍÍÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÅÅÅÀÀÀ¾¾¾¬¬¬¬¬¬ÃÃÃÒÒÒÇÇÇÌÌÌ×××ÐÐÐÐÐÐÌÌÌÅÅÅÃÃÃÆÆÆÍÍÍØØØÝÝÝÙÙÙÙÙÙ×××ÔÔÔÑÑÑÐÐÐÔÔÔ×××ØØØÒÒÒÍÍÍÌÌÌÍÍÍÑÑÑÒÒÒÔÔÔÎÎÎØØØÙÙÙÒÒÒÔÔÔÛÛÛÛÛÛÒÒÒâââàààßßßÝÝÝßßßàààâââããããããßßßàààâââàààæææëëëçççÔÔÔÛÛÛÒÒÒÃÃÃÆÆÆÍÍÍÍÍÍÌÌÌÇÇÇÊÊÊÊÊÊÇÇÇÅÅÅÆÆÆÌÌÌÑÑÑÌÌÌÀÀÀ¾¾¾ÉÉÉÕÕÕÙÙÙßßßçççÜÜÜØØØ×××ÙÙÙÙÙÙÕÕÕÔÔÔÔÔÔÔÔÔÕÕÕÊÊÊÇÇÇÅÅÅàààæææêêêñññçççãããßßßÒÒÒÌÌÌÎÎÎÎÎÎÐÐÐÎÎÎÌÌÌÉÉÉÊÊÊÍÍÍÑÑÑÔÔÔ×××ÔÔÔÑÑÑÐÐÐÎÎÎÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÒÒÒÎÎÎÆÆÆÆÆÆÍÍÍÐÐÐØØØÛÛÛÜÜÜÛÛÛ×××ÒÒÒÐÐÐÐÐÐÐÐÐÌÌÌÉÉÉÌÌÌÑÑÑÕÕÕÕÕÕÔÔÔ×××ÐÐÐÒÒÒÛÛÛßßßæææëëëçççääääääãããâââàààßßßÜÜÜÙÙÙÎÎÎÒÒÒÕÕÕ×××ÜÜÜæææëëëëëëêêêæææääääääãããâââçççíííëëëèèèíííëëëÛÛÛÐÐÐÎÎÎÍÍÍÔÔÔÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÇÇÇÊÊÊÍÍÍÎÎÎÃÃÃÆÆÆÒÒÒÒÒÒÅÅÅÅÅÅÌÌÌÇÇÇÂÂÂÒÒÒÎÎÎÌÌÌÊÊÊÅÅÅÇÇÇÇÇÇÐÐп¿¿ÀÀÀÅÅž¾¾ÌÌ̺ººÌÌÌÅÅÅ»»»¼¼¼¼¼¼ÌÌÌÌÌÌÐÐÐÉÉÉÌÌÌÐÐÐÍÍÍÍÍÍÒÒÒÐÐÐÇÇÇÆÆÆÃÃÃÌÌÌÕÕÕÙÙÙÕÕÕÑÑÑÎÎÎÎÎÎÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÇÇÇÅÅÅÃÃí­­¯¯¯ÂÂÂÑÑÑÍÍÍÐÐÐÒÒÒÆÆÆÉÉɾ¾¾ººº¿¿¿ÌÌÌ×××ÝÝÝÒÒÒÕÕÕØØØÒÒÒÌÌÌÌÌÌÐÐÐØØØÕÕÕÑÑÑÍÍÍÌÌÌÎÎÎÑÑÑÒÒÒÒÒÒÜÜÜãããäääÝÝÝßßßêêêëëëæææãããàààÝÝÝÛÛÛÛÛÛÝÝÝàààãããäääâââææææææÜÜÜÝÝÝçççêêê×××ÜÜÜÑÑÑÂÂÂÅÅÅÌÌÌÌÌÌÊÊÊÇÇÇÉÉÉÊÊÊÇÇÇÆÆÆÇÇÇÎÎÎÔÔÔÅÅÅÀÀÀ¿¿¿ÃÃÃÎÎÎÙÙÙâââãããÜÜÜØØØ×××ÙÙÙÙÙÙÕÕÕÒÒÒÔÔÔÒÒÒÔÔÔÅÅÅÉÉÉÊÊÊàààèèèñññóóóèèèæææâââÔÔÔÍÍÍÍÍÍÌÌÌÎÎÎÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÒÒÒÕÕÕÔÔÔÕÕÕÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÍÍÍÊÊÊÆÆÆÊÊÊÍÍÍÇÇÇÌÌÌÒÒÒÐÐÐÔÔÔ×××ÙÙÙÙÙÙÕÕÕÑÑÑÎÎÎÎÎÎÐÐÐÊÊÊÆÆÆÇÇÇÍÍÍÒÒÒÔÔÔÔÔÔÙÙÙÒÒÒÔÔÔÙÙÙÝÝÝêêêòòòïïïçççæææäääâââßßßÜÜÜÛÛÛÜÜÜÐÐÐÒÒÒÕÕÕÕÕÕÜÜÜæææëëëëëëëëëèèèççççççæææäääèèèñññæææâââæææäääÕÕÕÌÌÌÍÍÍÍÍÍÒÒÒÑÑÑÐÐÐÎÎÎÌÌÌÇÇÇÆÆÆÃÃÃÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÇÇǼ¼¼ÅÅÅÊÊÊÀÀÀÂÂÂÉÉÉÂÂÂÆÆÆÕÕÕÑÑÑÎÎÎÍÍÍÆÆÆÊÊÊÊÊÊÐÐÐÅÅÅÀÀÀÊÊʾ¾¾ÊÊÊ»»»ÍÍÍÅÅÅ»»»¿¿¿ÆÆÆÐÐÐÐÐÐÑÑÑÌÌÌÎÎÎÐÐÐÌÌÌÌÌÌÒÒÒÐÐÐÇÇÇÆÆÆÃÃÃÌÌÌÔÔÔØØØÕÕÕÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÃÃñ±±¸¸¸ÆÆÆÐÐÐÎÎÎÎÎÎÉÉɼ¼¼¿¿¿»»»¼¼¼···»»»ÇÇÇÌÌÌÑÑÑÌÌÌÎÎÎ×××ÑÑÑÉÉÉÊÊÊÊÊÊÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÊÊÊÐÐÐÑÑÑÎÎÎÒÒÒÜÜÜàààÝÝÝÝÝÝÛÛÛØØØÕÕÕÕÕÕØØØÛÛÛÝÝÝâââàààççççççÜÜÜÙÙÙâââæææßßßÝÝÝÍÍÍ¿¿¿ÃÃÃÉÉÉÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐÕÕÕÅÅÅÃÃÃÀÀÀ¾¾¾ÅÅÅÒÒÒÝÝÝâââßßßÙÙÙÕÕÕØØØ×××ÒÒÒÑÑÑÑÑÑÐÐÐÐÐÐÂÂÂÑÑÑ×××àààçççõõõñññçççäääâââÔÔÔÍÍÍÌÌÌÊÊÊÍÍÍÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔÑÑÑÔÔÔÕÕÕÕÕÕÔÔÔÒÒÒÎÎÎÉÉÉÉÉÉÅÅÅÍÍÍÒÒÒÊÊÊÌÌÌÑÑÑÊÊÊÎÎÎÒÒÒÕÕÕØØØ×××ÒÒÒÐÐÐÍÍÍÌÌÌÇÇÇÃÃÃÅÅÅÊÊÊÐÐÐÔÔÔÕÕÕÌÌÌÇÇÇÌÌÌÐÐÐÒÒÒÜÜÜàààÙÙÙëëëèèèçççäääßßßØØØ×××ØØØÕÕÕÙÙÙÛÛÛÛÛÛÝÝÝäääèèèèèèæææçççäääæææèèèçççèèèòòòèèèââââââÜÜÜÎÎÎÉÉÉÐÐÐÔÔÔÐÐÐÎÎÎÎÎÎÍÍÍÌÌÌÉÉÉÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÎÎλ»»ÀÀÀÊÊÊÂÂÂÅÅÅÌÌÌÃÃÃÆÆÆ×××ÑÑÑÎÎÎÎÎÎÉÉÉÍÍÍÎÎÎÑÑÑÍÍÍÃÃÃÐÐп¿¿ÆÆÆ»»»ÊÊÊÀÀÀºººÂÂÂÎÎÎÒÒÒÒÒÒÒÒÒÌÌÌÒÒÒÕÕÕÑÑÑÎÎÎÑÑÑÎÎÎÇÇÇÉÉÉÆÆÆÌÌÌÑÑÑÒÒÒÑÑÑÎÎÎÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆÆÆÆÅÅÅ¿¿¿°°°ÂÂÂÍÍÍÍÍÍÍÍÍÇÇÇÀÀÀ¿¿¿¼¼¼»»»ÀÀÀººº¼¼¼ÉÉÉÉÉÉÍÍÍÎÎÎÍÍÍÕÕÕÑÑÑÐÐÐÑÑÑÉÉÉÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÑÑÑÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎ××××××ÕÕÕÕÕÕÕÕÕ×××ØØØÙÙÙÜÜÜØØØßßßäääßßßÜÜÜßßßÝÝÝäääÙÙÙÅÅÅ»»»ÃÃÃÉÉÉÅÅÅÅÅÅÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÎÎÎÒÒÒÔÔÔÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÇÇÇÒÒÒÝÝÝàààÙÙÙÕÕÕÕÕÕÕÕÕÑÑÑÎÎÎÐÐÐÌÌÌÍÍÍÂÂÂÝÝÝäääàààâââòòòèèèààààààÝÝÝÑÑÑÊÊÊÌÌÌÌÌÌÊÊÊÌÌÌÎÎÎÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÒÒÒÔÔÔÔÔÔÕÕÕÕÕÕÐÐÐÆÆÆÉÉÉÉÉÉÙÙÙÜÜÜÌÌÌÇÇÇÍÍÍÆÆÆÊÊÊÍÍÍÑÑÑÕÕÕØØØÕÕÕÑÑÑÍÍÍÉÉÉÇÇÇÅÅÅÅÅÅÇÇÇÌÌÌÎÎÎÑÑÑÐÐÐÎÎÎÒÒÒ×××ÙÙÙâââäääÜÜÜêêêèèèèèèêêêãããÙÙÙÕÕÕ×××ÙÙÙßßßâââÝÝÝÛÛÛÜÜÜÝÝÝÜÜÜæææêêêèèèêêêîîîèèèçççñññîîîæææãããÝÝÝÐÐÐÌÌÌÒÒÒØØØÑÑÑÑÑÑÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÊÊÊÊÊÊÇÇÇÆÆÆÅÅÅÆÆÆÊÊÊÐÐÐÒÒÒÑÑѼ¼¼ÆÆÆÒÒÒÇÇÇÆÆÆÐÐÐÉÉÉÅÅÅÔÔÔÐÐÐÎÎÎÍÍÍÉÉÉÎÎÎÑÑÑÔÔÔÔÔÔÅÅÅÕÕÕ¿¿¿ÃÃúººÇÇǾ¾¾¸¸¸ÃÃÃÒÒÒÔÔÔÔÔÔÒÒÒÍÍÍÔÔÔÛÛÛØØØÒÒÒÐÐÐÊÊÊÇÇÇÍÍÍÉÉÉÌÌÌÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÐÐÐÇÇÇÅÅÅÂÂÂÀÀÀÀÀÀÀÀÀ¾¾¾¼¼¼ªªªÅÅÅÐÐÐÌÌÌÊÊÊÃÃÿ¿¿ÇÇÇÀÀÀ¿¿¿ÅÅż¼¼¾¾¾ÍÍÍÎÎÎÕÕÕ×××ÐÐÐ×××ÕÕÕØØØÜÜÜÍÍÍÌÌÌÉÉÉÊÊÊÌÌÌÊÊÊÉÉÉÉÉÉÌÌÌÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÑÑÑÎÎÎÎÎÎÎÎÎÔÔÔÕÕÕ×××ØØØÙÙÙÙÙÙØØØØØØØØØÐÐÐÕÕÕââââââàààÝÝÝØØØãããÔÔÔ¼¼¼···ÅÅÅÊÊÊÇÇÇÉÉÉÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÑÑÑÒÒÒÔÔÔ¿¿¿¾¾¾ÃÃÃÌÌÌÇÇÇÀÀÀÇÇÇ×××âââÛÛÛÕÕÕÔÔÔÒÒÒÎÎÎÍÍÍÐÐÐÊÊÊÌÌÌÃÃÃçççîîîàààÝÝÝîîîâââÛÛÛÛÛÛÛÛÛÎÎÎÉÉÉÍÍÍÎÎÎÉÉÉÌÌÌÎÎÎÒÒÒÒÒÒÒÒÒÐÐÐÎÎÎÐÐÐÒÒÒÒÒÒÑÑÑÔÔÔ×××ÐÐÐÆÆÆÀÀÀÇÇÇßßßãããÌÌÌÆÆÆÐÐÐÍÍÍÇÇÇÊÊÊÎÎÎÔÔÔØØØ×××ÒÒÒÍÍÍÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÉÉÉÑÑÑÎÎÎÒÒÒÕÕÕØØØäääêêêâââääääääêêêîîîèèèÝÝÝØØØØØØÛÛÛàààãããÝÝÝ×××ÔÔÔÒÒÒÐÐÐíííñññïïïïïïóóóëëëæææîîîëëëääääääàààÑÑÑÊÊÊÐÐÐÒÒÒØØØÕÕÕÑÑÑÍÍÍÊÊÊÊÊÊÌÌÌÍÍÍÃÃÃÂÂÂÂÂÂÂÂÂÆÆÆÊÊÊÐÐÐÒÒÒÊÊʸ¸¸ÆÆÆÔÔÔÅÅÅÀÀÀÌÌÌÇÇÇÂÂÂÒÒÒÎÎÎÌÌÌÍÍÍÉÉÉÐÐÐÑÑÑÔÔÔ×××ÎÎÎÃÃÃÑÑѺºº¸¸¸ÇÇÇÀÀÀºººÑÑÑÐÐÐ×××ÔÔÔÒÒÒÐÐÐÑÑÑÔÔÔÕÕÕÎÎÎÎÎÎÎÎÎÆÆÆÐÐÐÆÆÆÎÎÎÑÑÑÍÍÍÊÊÊÎÎÎÑÑÑÐÐÐÇÇÇ¿¿¿¿¿¿¾¾¾µµµ···¸¸¸°°°ÎÎÎÕÕÕÑÑÑÀÀÀºººÂÂÂÇÇÇÃÃÿ¿¿»»»»»»ÂÂÂÉÉÉÍÍÍÐÐÐÔÔÔÔÔÔÍÍÍÔÔÔÒÒÒÕÕÕÙÙÙÌÌÌÌÌÌÑÑÑÌÌÌÌÌÌÊÊÊÂÂÂÀÀÀÅÅÅÀÀÀÅÅÅÆÆÆÊÊÊÊÊÊÊÊÊÇÇÇÅÅÅÃÃÃÆÆÆÍÍÍÐÐÐÇÇÇÃÃÃÉÉÉÑÑÑ×××ÔÔÔÙÙÙÒÒÒ×××èèèçççÛÛÛÝÝÝãããßßßÙÙÙÒÒÒÍÍÍÉÉÉÆÆÆÃÃÃÂÂÂÃÃÃÆÆÆÉÉÉÍÍÍÔÔÔÛÛÛßßßÅÅÅ¿¿¿ÃÃÃÇÇÇÅÅÅÉÉÉÍÍÍÆÆÆØØØÜÜÜÑÑÑÑÑÑÒÒÒÐÐÐÕÕÕÉÉÉÌÌ̼¼¼ÃÃÃàààîîîãããàààëëëØØØÒÒÒÕÕÕÒÒÒÔÔÔÔÔÔÆÆÆÅÅÅÐÐÐÍÍÍÌÌÌÊÊÊÍÍÍÒÒÒØØØÛÛÛÎÎÎÐÐÐÑÑÑÔÔÔÍÍÍÔÔÔÛÛÛÀÀÀÅÅÅÎÎÎÜÜÜÙÙÙÊÊÊÊÊÊÑÑÑÍÍÍÉÉÉÉÉÉÌÌÌÑÑÑ××××××ÑÑÑÌÌÌÉÉÉÌÌÌÊÊÊÅÅÅÍÍÍÉÉÉÇÇÇêêêÎÎÎÍÍÍÑÑÑØØØÙÙÙÙÙÙßßßççççççïïïòòòêêêßßßÙÙÙ×××ÕÕÕÜÜÜÜÜÜÙÙÙÕÕÕÑÑÑÑÑÑÔÔÔ×××ØØØãããíííòòòóóóïïïäääÙÙÙíííãããêêêçççÍÍÍÆÆÆÑÑÑÎÎÎÑÑÑ×××ØØØÑÑÑÍÍÍÍÍÍÌÌÌÉÉÉÕÕÕÒÒÒÊÊÊÊÊÊÉÉÉÑÑÑÜÜÜÍÍ;¾¾ÂÂÂÆÆÆØØØÅÅÅÉÉÉÍÍÍ¿¿¿ÀÀÀ×××ØØØÎÎÎÐÐÐÔÔÔÑÑÑÑÑÑÔÔÔÔÔÔÊÊÊÊÊÊÕÕÕ¼¼¼ÂÂÂÇÇÇÅÅż¼¼ÊÊÊÒÒÒ×××ÔÔÔÒÒÒÐÐÐØØØØØØÛÛÛØØØÜÜÜÙÙÙÇÇÇÇÇÇÎÎÎÎÎÎÍÍÍÊÊÊÊÊÊÍÍÍÌÌÌÉÉÉÀÀÀÉÉÉ×××ÜÜÜ×××ÔÔÔ××××××ÙÙÙÎÎÎÇÇÇÉÉÉÇÇÇÀÀÀ¾¾¾¿¿¿ÊÊÊÆÆÆÅÅÅÉÉÉÎÎÎÎÎÎÑÑÑÔÔÔ¼¼¼¾¾¾ÊÊÊÍÍÍÑÑÑÕÕÕÇÇÇÃÃÃÊÊÊÉÉÉÊÊÊÆÆÆ¸¸¸···»»»»»»»»»¼¼¼¾¾¾ÀÀÀÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÇÇÇÉÉÉÅÅÅÂÂÂÇÇÇÎÎÎÑÑÑÕÕÕÜÜÜÕÕÕ×××çççæææÙÙÙÛÛÛêêêææææææçççÙÙÙÉÉÉÅÅÅÍÍÍÅÅÅÆÆÆÇÇÇÊÊÊÍÍÍÑÑÑØØØÜÜÜØØØÎÎÎÌÌÌÍÍÍÌÌÌÍÍÍÊÊÊÀÀÀÛÛÛâââØØØ×××ÔÔÔÐÐÐÔÔÔÌÌÌÊÊÊÂÂÂÉÉÉßßßêêêäääàààæææäääÛÛÛÙÙÙÔÔÔ×××ÙÙÙÎÎÎÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÑÑÑÔÔÔÕÕÕÙÙÙÙÙÙØØØØØØÊÊÊÊÊÊÕÕÕÂÂÂÇÇÇÇÇÇÌÌÌÌÌÌÇÇÇÌÌÌÍÍÍÅÅÅÅÅÅÅÅÅÆÆÆÌÌÌÑÑÑÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÉÉÉÃÃÃÇÇÇÆÆÆÅÅÅÜÜÜÐÐÐÐÐÐÒÒÒÙÙÙÜÜÜÛÛÛÝÝÝâââãããêêêëëëäääÜÜÜÙÙÙØØØ×××ÝÝÝÜÜÜØØØÕÕÕÒÒÒÒÒÒÔÔÔ×××ÔÔÔÛÛÛãããçççêêêêêêãããÛÛÛæææßßßÜÜÜÝÝÝ×××ÌÌÌÊÊÊÐÐÐÌÌÌÐÐÐÑÑÑÌÌÌÊÊÊÍÍÍÐÐÐÎÎÎÎÎÎÐÐÐÎÎÎÑÑÑÎÎÎÍÍÍÑÑÑÀÀÀ¿¿¿ÅÅÅÆÆÆÛÛÛÌÌÌÎÎÎÑÑÑÊÊÊÇÇÇÒÒÒ×××ÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔ×××ÐÐÐÅÅÅÎÎÎØØØÀÀÀÍÍÍÉÉÉÇÇǾ¾¾¿¿¿××××××ÔÔÔÒÒÒÐÐÐÜÜÜØØØÙÙÙÙÙÙäääãããÌÌÌÇÇÇÔÔÔÍÍÍÇÇÇÇÇÇÊÊÊÉÉÉÆÆÆÅÅÅ¿¿¿ÎÎÎÛÛÛßßßÝÝÝ×××ÔÔÔØØØÙÙÙÊÊÊÅÅÅÌÌÌÊÊʼ¼¼µµµºººººº´´´±±±´´´µµµ³³³´´´···¿¿¿ÂÂÂÇÇÇÃÃÃÅÅÅÌÌÌÆÆÆÃÃÃÉÉÉÇÇÇÌÌÌÅÅŵµµ±±±¸¸¸ººº¯¯¯°°°±±±µµµººº¾¾¾ÀÀÀ¿¿¿ÅÅÅÆÆÆÅÅÅÆÆÆÊÊÊÎÎÎÐÐÐÔÔÔØØØÔÔÔÕÕÕããããããÛÛÛßßßææææææêêêëëëßßßÊÊÊÀÀÀÂÂÂÆÆÆÇÇÇÊÊÊÌÌÌÍÍÍÐÐÐÕÕÕØØØßßßØØØÔÔÔÑÑÑÌÌÌÍÍÍÐÐÐÌÌÌÝÝÝãããßßßÜÜÜØØØÒÒÒÕÕÕÑÑÑÅÅÅÍÍÍØØØàààãããââââââãããíííßßßÙÙÙÔÔÔØØØÝÝÝÒÒÒÐÐÐÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÎÎÎÉÉÉÎÎÎ×××àààÔÔÔÍÍÍÔÔÔÉÉÉÆÆÆÂÂÂÂÂÂÂÂÂÃÃÃÉÉÉÊÊÊÃÃÃÃÃÃÃÃÃÆÆÆÌÌÌÒÒÒ×××ÕÕÕÒÒÒÊÊÊÆÆÆÊÊÊÆÆÆÆÆÆÌÌÌÌÌÌÕÕÕÔÔÔÒÒÒÕÕÕÛÛÛÝÝÝÝÝÝÜÜÜÝÝÝàààääääääßßßÛÛÛÛÛÛÛÛÛÙÙÙßßßÜÜÜØØØÕÕÕÔÔÔÕÕÕÕÕÕÕÕÕÒÒÒ×××ÛÛÛÝÝÝâââçççæææàààããããããÙÙÙØØØÛÛÛÇÇǺººÅÅÅÊÊÊÍÍÍÍÍÍÊÊÊÊÊÊÎÎÎÒÒÒÒÒÒÌÌÌÎÎÎÑÑÑÒÒÒÑÑÑÆÆÆÇÇǺººÀÀÀÆÆÆÅÅÅÛÛÛÒÒÒÑÑÑÒÒÒÕÕÕÉÉÉÆÆÆÎÎÎÕÕÕÔÔÔÒÒÒØØØÛÛÛÜÜÜÇÇÇÅÅÅÍÍÍÔÔÔÅÅÅÐÐÐÉÉÉÆÆÆ¾¾¾···ØØØ×××ÕÕÕÕÕÕÔÔÔÜÜÜ×××ÕÕÕÔÔÔßßßâââÒÒÒÑÑÑÔÔÔÌÌÌÆÆÆÇÇÇÆÆÆÂÂÂÂÂÂÇÇÇÉÉÉÔÔÔÕÕÕ×××ßßßÛÛÛÔÔÔÙÙÙÊÊÊÍÍÍÍÍÍÇÇÇ¿¿¿ººº······¾¾¾¸¸¸·········³³³´´´···¸¸¸¾¾¾ÀÀÀ»»»¾¾¾ÇÇÇÊÊÊÉÉÉÃÃÿ¿¿ÀÀÀ¼¼¼±±±¯¯¯³³³±±±¦¦¦©©©¬¬¬³³³¸¸¸¼¼¼¾¾¾¾¾¾ÃÃÃÅÅÅÇÇÇÊÊÊÎÎÎÑÑÑÒÒÒÒÒÒÎÎÎÑÑÑÍÍÍÎÎÎÛÛÛàààßßßäääÝÝÝãããçççäääàààÕÕÕÃÃó³³ÃÃÃÇÇÇÊÊÊÍÍÍÍÍÍÎÎÎÔÔÔØØØÝÝÝßßßÝÝÝÕÕÕÉÉÉÇÇÇÒÒÒÜÜÜââââââßßßÝÝÝÜÜÜÙÙÙØØØÒÒÒÀÀÀØØØçççãããÜÜÜßßßääääääæææÙÙÙÕÕÕÒÒÒØØØÜÜÜÐÐÐÌÌÌÊÊÊÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÉÉÉÐÐÐÜÜÜÒÒÒÆÆÆÉÉÉÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÅÅÅÇÇÇÇÇÇÃÃÃÅÅÅÇÇÇÎÎÎ×××ÜÜÜßßßÝÝÝÔÔÔÇÇÇÍÍÍÊÊÊÊÊÊ×××ØØØØØØ×××ÕÕÕÕÕÕÙÙÙÝÝÝßßßßßßßßßàààãããàààÜÜÜÛÛÛÝÝÝÝÝÝÛÛÛßßßÛÛÛ×××ÕÕÕ×××××××××ÕÕÕ×××ÙÙÙÛÛÛÜÜÜãããêêêêêêæææâââëëëæææâââäääÔÔÔÂÂÂÆÆÆÉÉÉÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÎÎÎÐÐÐÐÐÐÎÎÎÎÎο¿¿ÆÆÆ¾¾¾ÀÀÀÇÇÇÂÂÂØØØÔÔÔÐÐÐÎÎÎØØØÐÐÐÂÂÂÉÉÉØØØÕÕÕÑÑÑØØØÛÛÛßßßÂÂÂÉÉÉÆÆÆÊÊÊÇÇÇÊÊÊÇÇÇ»»»µµµØØØØØØ×××ØØØØØØÜÜÜÙÙÙÙÙÙÔÔÔÛÛÛÝÝÝÒÒÒØØØÍÍÍÉÉÉÇÇÇÆÆÆÀÀÀ¼¼¼ÃÃÃÎÎÎØØØÝÝÝÙÙÙ×××ÜÜÜØØØÑÑÑÕÕÕÇÇÇÐÐÐÐÐÐÃÃü¼¼¿¿¿¾¾¾¸¸¸»»»···µµµ···´´´±±±³³³···ºººÀÀÀÀÀÀ¿¿¿¼¼¼ººº···¯¯¯¸¸¸°°°­­­­­­ªªª¬¬¬­­­¦¦¦¦¦¦©©©­­­µµµ»»»¾¾¾»»»¸¸¸ÃÃÃÃÃÃÇÇÇÍÍÍÑÑÑÒÒÒÒÒÒÒÒÒÎÎÎÎÎÎÊÊÊÊÊÊÒÒÒØØØÜÜÜäääßßßæææêêêêêêèèèâââÑÑÑ¿¿¿¿¿¿ÅÅÅÊÊÊÍÍÍÍÍÍÐÐÐÔÔÔÙÙÙÝÝÝæææçççßßßÔÔÔÎÎÎÔÔÔÝÝÝëëëâââÜÜÜÛÛÛÜÜÜÛÛÛÒÒÒÍÍÍÉÉÉÝÝÝèèèâââÝÝÝäääçççàààÛÛÛÒÒÒÕÕÕÔÔÔÙÙÙÛÛÛÌÌÌÆÆÆÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÐÐÐÇÇÇ¿¿¿ÉÉÉÆÆÆ¾¾¾ÃÃÿ¿¿ÂÂÂÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÆÆÆÆÆÆÆÆÆÉÉÉÎÎÎÔÔÔØØØÛÛÛÜÜÜßßßÎÎÎÐÐÐÍÍÍÌÌÌÛÛÛÝÝÝØØØÙÙÙØØØ××××××ÜÜÜâââãããããããããäääâââÜÜÜÜÜÜßßßßßßÜÜÜßßßÛÛÛØØØ×××ØØØØØØØØØ×××ÛÛÛÜÜÜÜÜÜÝÝÝæææíííëëëæææäääêêêèèèãããâââÙÙÙÆÆÆ···ÂÂÂÂÂÂÅÅÅÊÊÊÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÐÐÐÍÍÍÒÒÒ¼¼¼ÆÆÆÅÅÅÆÆÆÌÌÌÅÅÅÛÛÛÕÕÕÐÐÐÍÍÍÕÕÕÝÝÝÌÌÌÎÎÎÛÛÛØØØÔÔÔ×××ØØØØØØÀÀÀÐÐÐÀÀÀÃÃÃÉÉÉÆÆÆÆÆÆ¾¾¾¸¸¸¾¾¾ÕÕÕ×××ÕÕÕÙÙÙÙÙÙÜÜÜÝÝÝâââÜÜÜßßßÜÜÜÎÎÎÒÒÒÉÉÉÉÉÉÉÉÉÃÃü¼¼¼¼¼ÇÇÇÔÔÔ×××ÝÝÝÝÝÝØØØÑÑÑÉÉÉÅÅÅÉÉÉÎÎÎÌÌÌÆÆÆÂÂÂÂÂÂÃÃÃÀÀÀ»»»¾¾¾»»»»»»¼¼¼»»»¸¸¸»»»ÀÀÀººº¾¾¾ººº¾¾¾¿¿¿»»»¼¼¼¸¸¸¸¸¸­­­©©©¬¬¬­­­³³³±±±¨¨¨¬¬¬­­­°°°µµµ»»»¾¾¾»»»···¿¿¿¿¿¿ÃÃÃÊÊÊÎÎÎÍÍÍÍÍÍÎÎÎÑÑÑÑÑÑÍÍÍÊÊÊÍÍÍÑÑÑ×××ÜÜÜàààãããêêêîîîêêêàààÙÙÙ×××»»»ÂÂÂÊÊÊÎÎÎÎÎÎÐÐÐÕÕÕÙÙÙÛÛÛãããæææçççêêêäääßßßàààñññâââÜÜÜ××××××ÔÔÔÇÇÇÅÅÅØØØßßßàààÜÜÜßßßçççããã×××ÔÔÔÑÑÑØØØØØØØØØ×××ÉÉÉÆÆÆÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÌÌÌÍÍÍÅÅźººÂÂÂÃÃþ¾¾ÃÃÃÀÀÀÇÇÇÃÃû»»»»»ÂÂÂÀÀÀ¾¾¾ÀÀÀÑÑÑÑÑÑÒÒÒÔÔÔÕÕÕ×××ØØØØØØæææÑÑÑÐÐÐÍÍÍÍÍÍØØØØØØÕÕÕÛÛÛÛÛÛÙÙÙ×××ÛÛÛâââææææææääääääãããÝÝÝÜÜÜààààààÜÜÜÝÝÝÛÛÛÙÙÙØØØØØØÙÙÙØØØØØØÛÛÛÛÛÛÜÜÜÝÝÝæææíííëëëããããããàààâââãããâââàààÑÑѸ¸¸¾¾¾»»»»»»¿¿¿ÃÃÃÆÆÆÇÇÇÌÌÌÉÉÉÇÇÇÐÐÐÐÐÐÜÜܾ¾¾ÅÅÅÅÅÅÍÍÍÑÑÑÍÍÍàààÕÕÕÑÑÑÐÐÐÑÑÑÜÜÜÑÑÑÐÐÐ×××ÜÜÜßßßßßßÝÝÝÌÌÌÆÆÆÒÒÒ¿¿¿ÃÃÃÇÇÇÇÇÇÃÃû»»···ÊÊÊÔÔÔÕÕÕÔÔÔ×××ØØØÛÛÛÜÜÜßßßÛÛÛÝÝÝÛÛÛÊÊÊÍÍÍÉÉÉÊÊÊÇÇÇ¿¿¿¼¼¼ÂÂÂÍÍÍÔÔÔÑÑÑÐÐÐÔÔÔÒÒÒÍÍÍÌÌÌÍÍÍÌÌÌÊÊÊÃÃÿ¿¿ÀÀÀÀÀÀ¼¼¼¸¸¸¸¸¸···µµµµµµ···µµµ´´´···¾¾¾ÆÆÆÂ···¿¿¿ÀÀÀ¸¸¸¼¼¼»»»¾¾¾´´´³³³µµµµµµººº»»»³³³´´´°°°­­­¯¯¯´´´ººº»»»»»»¼¼¼¼¼¼ÀÀÀÇÇÇÊÊÊÇÇÇÉÉÉÍÍÍÑÑÑÒÒÒÑÑÑÐÐÐÎÎÎÐÐÐÔÔÔ×××àààâââäääæææäääàààààààà຺ºÂÂÂÌÌÌÐÐÐÎÎÎÐÐÐÔÔÔÙÙÙØØØßßßàààæææïïïïïïêêêíííêêêÝÝÝÛÛÛÒÒÒÍÍÍÊÊÊÀÀÀÆÆÆßßßàààÝÝÝÛÛÛÜÜÜÜÜÜØØØÒÒÒÒÒÒÒÒÒÛÛÛÕÕÕÐÐÐÍÍÍÅÅÅÆÆÆÅÅÅÅÅÅÇÇÇÉÉÉÊÊÊÌÌÌÍÍÍÍÍÍÎÎÎÎÎÎÆÆÆÇÇÇÆÆÆ¿¿¿ÃÃÿ¿¿ÍÍÍÊÊʾ¾¾ÀÀÀ¼¼¼¼¼¼ÆÆÆÕÕÕ×××ØØØÙÙÙÙÙÙÙÙÙØØØØØØãããÐÐÐÍÍÍÎÎÎÔÔÔÙÙÙÕÕÕÛÛÛÜÜÜßßßÝÝÝÛÛÛÛÛÛàààäääãããàààãããâââÝÝÝÜÜÜßßßàààÝÝÝÛÛÛÜÜÜÛÛÛÛÛÛÙÙÙØØØÙÙÙÙÙÙÛÛÛÜÜÜÜÜÜßßßçççïïïíííæææàààÜÜÜãããëëëæææàààÝÝÝÙÙÙÍÍ͸¸¸···¸¸¸¼¼¼ÃÃÃÌÌÌÆÆÆÅÅÅÍÍÍÎÎÎßßß¾¾¾ÃÃÃÅÅÅÍÍÍÑÑÑÑÑÑâââÑÑÑÒÒÒÒÒÒÊÊÊÕÕÕÔÔÔÍÍÍÌÌÌØØØâââßßßØØØÂÂÂÊÊÊÔÔÔÂÂÂÆÆÆÆÆÆÌÌÌ»»»···ÔÔÔÑÑÑÕÕÕÑÑÑÔÔÔ×××ØØØÕÕÕÕÕÕÑÑÑØØØÙÙÙÊÊÊÊÊÊÌÌÌÌÌÌÅÅż¼¼¼¼¼ÇÇÇÐÐÐÑÑÑÙÙÙÊÊÊÅÅÅÅÅÅÀÀÀÅÅÅÆÆÆ»»»¼¼¼¾¾¾¿¿¿»»»µµµ°°°¯¯¯±±±´´´³³³³³³´´´³³³±±±´´´»»»µµµ³³³­­­ÀÀÀÆÆÆ¸¸¸ººº···¼¼¼······¸¸¸´´´···»»»···ººº±±±©©©¦¦¦¬¬¬µµµ¼¼¼¾¾¾¾¾¾¾¾¾ÂÂÂÉÉÉÊÊÊÇÇÇÉÉÉÎÎÎÍÍÍÐÐÐÔÔÔÕÕÕÑÑÑÑÑÑÕÕÕ×××äääçççâââÛÛÛâââíííëëëßßß»»»ÃÃÃÌÌÌÐÐÐÎÎÎÎÎÎÒÒÒØØØÝÝÝäääâââßßßãããäääçççòòòßßßÕÕÕÙÙÙÐÐÐÇÇÇÅÅÅÀÀÀÍÍÍßßßâââãããÝÝÝÔÔÔÍÍÍÎÎÎÔÔÔÒÒÒÒÒÒÙÙÙÐÐÐÆÆÆÃÃþ¾¾ÆÆÆÂÂÂÃÃÃÆÆÆÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÉÉÉÎÎÎÆÆÆÅÅÅÅÅÅÆÆÆÕÕÕÙÙÙÑÑÑÕÕÕÎÎÎÅÅÅ¿¿¿···¾¾¾ÔÔÔÍÍÍÐÐÐÒÒÒÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÝÝÝÍÍÍÌÌÌÒÒÒÜÜÜßßßÛÛÛäääÜÜÜââââââÝÝÝÜÜÜßßßâââàààÛÛÛààààààÝÝÝÜÜÜßßßàààßßßÛÛÛÜÜÜÜÜÜÛÛÛÙÙÙØØØÙÙÙÛÛÛÝÝÝÝÝÝÝÝÝàààêêêóóóòòòëëëäääãããêêêêêêÒÒÒ¸¸¸»»»ÑÑÑâââÐÐм¼¼´´´³³³···ÀÀÀÌÌÌÉÉÉÅÅÅÉÉÉÉÉÉÝÝݺººÂÂÂÅÅÅÉÉÉÌÌÌÐÐÐàààÌÌÌÐÐÐÒÒÒÃÃÃ×××ÛÛÛÍÍÍÀÀÀÎÎÎØØØÎÎÎÅÅÅÂÂÂÔÔÔ×××ÆÆÆÃÃÃÑÑÑÐÐп¿¿···¼¼¼ÐÐÐÙÙÙÑÑÑÐÐÐ×××ØØØÝÝÝÐÐÐÍÍÍÔÔÔÔÔÔÔÔÔÒÒÒÌÌÌÍÍÍÊÊÊÌÌ̼¼¼»»»ÑÑÑÕÕÕÍÍÍÊÊÊÆÆÆÅÅÅÇÇÇÊÊÊÆÆÆ¼¼¼µµµÂ¼¼¼¯¯¯»»»ÅÅÅ¿¿¿¾¾¾°°°¯¯¯¯¯¯¯¯¯¯¯¯­­­¬¬¬­­­¯¯¯´´´±±±ÃÃþ¾¾°°°´´´¬¬¬µµµ°°°¯¯¯¬¬¬¬¬¬µµµ»»»´´´´´´¯¯¯©©©©©©±±±ººº»»»¸¸¸¾¾¾¿¿¿ÃÃÃÆÆÆÉÉÉÊÊÊÌÌÌÌÌÌÎÎÎÐÐÐÕÕÕÎÎÎÕÕÕÙÙÙÐÐÐÛÛÛÕÕÕää䨨ØßßßòòòîîîííííííàààÂÂÂÊÊÊÍÍÍÐÐÐØØØÎÎÎÛÛÛØØØÛÛÛÝÝÝßßßàààâââããããããÝÝÝÒÒÒÌÌÌÉÉÉÍÍ;¾¾´´´ÙÙÙ×××ÝÝÝÔÔÔÉÉÉÌÌÌÌÌÌÆÆÆÇÇÇ×××ÒÒÒÛÛÛÕÕÕ¾¾¾ºººÃÃÿ¿¿¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÌÌÌÊÊÊÆÆÆÍÍÍÛÛÛØØØÐÐÐÒÒÒÒÒÒÎÎÎÐÐÐÕÕÕ×××ÑÑÑÐÐÐÑÑÑÑÑÑÔÔÔ×××ØØØØØØÕÕÕÒÒÒÐÐÐÝÝÝÝÝÝÕÕÕÛÛÛÝÝÝÜÜÜßßß×××ÜÜÜàààßßßßßßæææäääâââäääÜÜÜÛÛÛÙÙÙÙÙÙÛÛÛÝÝÝàààâââààààààßßßÝÝÝÛÛÛÙÙÙÙÙÙØØØààààààâââãããæææêêêíííïïïíííëëëëëëêêêÙÙÙººº···ÑÑÑÔÔÔµµµ°°°³³³³³³···¼¼¼ÊÊÊÂÂÂÀÀÀÀÀÀÊÊÊÊÊÊÎÎλ»»ÅÅÅÂÂÂÇÇÇØØØßßß×××ÒÒÒÑÑÑÉÉÉÇÇÇÙÙÙÙÙÙÍÍÍÉÉÉÅÅÅÃÃÃÊÊÊÍÍÍÍÍÍÎÎÎÐÐÐÎÎÎÉÉÉÅÅÅÅÅŵµµÊÊÊ×××ÕÕÕÐÐÐÐÐÐÔÔÔØØØÜÜÜÎÎÎÌÌÌÐÐÐÎÎÎÎÎÎÐÐÐÌÌÌÊÊÊÃÃÃÆÆÆ¾¾¾¾¾¾ÐÐÐÐÐÐÉÉÉÃÃÃÉÉÉÍÍÍÊÊʼ¼¼¼¼¼ÀÀÀººº­­­¯¯¯ÀÀÀÅÅÅÅÅÅÉÉÉ¿¿¿³³³¦¦¦¥¥¥°°°¸¸¸¸¸¸´´´ººº¾¾¾ÇÇÇ···±±±©©©³³³¯¯¯¬¬¬¥¥¥¥¥¥¨¨¨¨¨¨¬¬¬­­­¨¨¨³³³···±±±©©©¬¬¬···ººº³³³ºººººº»»»¼¼¼¿¿¿ÅÅÅÊÊÊÐÐÐÒÒÒÕÕÕÛÛÛÕÕÕØØØÙÙÙÐÐÐÙÙÙàààæææÛÛÛßßßïïïíííèèèîîîæææÃÃÃÊÊÊÎÎÎÐÐÐÕÕÕÎÎÎØØØ×××ÙÙÙÝÝÝàààââââââàààßßßÝÝÝÔÔÔÑÑÑÍÍÍÇÇǸ¸¸¸¸¸ÝÝÝØØØÕÕÕÌÌÌÇÇÇÍÍÍÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍØØØ×××¾¾¾Â»»»¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÐÐÐÆÆÆÃÃÃÍÍÍ×××ÛÛÛ×××ÎÎÎÑÑÑÎÎÎÎÎÎÐÐÐÎÎÎÊÊÊÍÍÍÑÑÑÎÎÎÎÎÎÑÑÑÔÔÔ×××ØØØ×××ÕÕÕ×××ßßßÜÜÜàààÝÝÝ×××ÝÝÝÛÛÛßßßææææææãããæææàààÜÜÜâââßßßÝÝÝÜÜÜÜÜÜÝÝÝßßßâââããããããâââàààßßßÝÝÝÜÜÜÜÜÜÜÜÜàààââââââãããæææèèèêêêëëëêêêçççäääêêêæææÑÑÑÍÍÍÝÝÝÜÜÜ´´´ªªª³³³···¸¸¸ºººÇÇÇÂÂÂÂÂÂÂÂÂÊÊÊÍÍÍÑÑÑ»»»¿¿¿ÇÇÇÇÇÇÔÔÔÛÛÛÕÕÕÒÒÒÔÔÔÐÐÐÅÅÅÐÐÐ×××ÕÕÕÒÒÒÌÌÌÆÆÆÆÆÆÒÒÒÍÍÍÍÍÍÑÑÑÑÑÑÉÉÉÂÂÂÀÀÀÀÀÀ×××ÙÙÙÎÎÎÑÑÑÔÔÔÒÒÒÔÔÔÕÕÕÌÌÌÍÍÍÒÒÒÐÐÐÐÐÐÒÒÒÎÎÎÎÎÎÅÅÅÉÉÉÅÅÅÇÇÇ×××ÒÒÒÊÊÊÀÀÀÉÉÉÍÍÍÇÇǼ¼¼¸¸¸¾¾¾ÃÃúºº©©©···ÃÃü¼¼¼¼¼ÀÀÀÀÀÀÊÊʺººªªªªªª¸¸¸Â¼¼¼¿¿¿ÆÆÆÆÆÆ°°°···¸¸¸ÀÀÀ¼¼¼¼¼¼µµµ···ºººµµµ´´´°°°¥¥¥¨¨¨´´´µµµ©©©©©©µµµ»»»´´´ººº»»»¾¾¾¿¿¿ÀÀÀÆÆÆÍÍÍÒÒÒÒÒÒÕÕÕÛÛÛ×××ØØØ×××ÎÎÎÔÔÔæææâââÛÛÛÝÝÝíííîîîçççòòòëëëÂÂÂÉÉÉÒÒÒÑÑÑÕÕÕÑÑÑÕÕÕÔÔÔØØØÜÜÜßßßàààßßßÜÜÜÙÙÙÑÑÑÍÍÍÎÎÎÅÅźºº»»»ÉÉÉãããäääÕÕÕÌÌÌÊÊÊÌÌÌÎÎÎÍÍÍÇÇÇÍÍÍÊÊÊÒÒÒÒÒÒÅÅÅÂÂÂÅÅž¾¾¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÅÅÅÍÍÍÕÕÕÕÕÕÙÙÙÙÙÙÌÌÌÔÔÔÔÔÔ×××ØØØÕÕÕÒÒÒÕÕÕÛÛÛÒÒÒÐÐÐÐÐÐÑÑÑÕÕÕÙÙÙÙÙÙÙÙÙÒÒÒÛÛÛÛÛÛßßßÛÛÛÔÔÔÙÙÙØØØÒÒÒÜÜÜàààâââæææäääâââçççâââààààààßßßßßßàààãããäääçççæææãããâââàààààààààâââããããããäääææææææçççççççççóóóíííçççëëëîîîäääÛÛÛßßßÐÐб±±­­­³³³´´´······ÀÀÀÀÀÀÃÃÃÂÂÂÉÉÉÍÍÍ×××¼¼¼ºººÇÇÇÆÆÆÐÐÐÜÜÜÙÙÙÒÒÒÐÐÐÍÍÍÊÊÊÎÎÎÙÙÙßßß×××ÍÍÍÉÉÉÆÆÆÍÍÍÕÕÕÒÒÒÉÉÉÉÉÉÎÎÎÇÇÇ···ÕÕÕÛÛÛÔÔÔÍÍÍÔÔÔÙÙÙÒÒÒÊÊÊÌÌÌÊÊÊÒÒÒÙÙÙ×××××××××ÑÑÑÐÐÐÉÉÉÌÌÌÅÅÅÉÉÉÜÜÜØØØÊÊÊÆÆÆÆÆÆÂ¼¼¼»»»¾¾¾¾¾¾¼¼¼¯¯¯©©©ºººººº³³³¸¸¸···¾¾¾ÀÀÀ¾¾¾»»»¼¼¼ÀÀÀÃÃÃÂÂÂÀÀÀ¿¿¿ÀÀÀººº¬¬¬ÅÅÅÊÊÊÊÊʾ¾¾¾¾¾ÃÃÃÅÅÅÅÅÅÉÉÉÅÅÅ´´´¤¤¤±±±µµµ­­­¨¨¨¯¯¯µµµµµµ···»»»ÀÀÀÅÅÅÅÅÅÆÆÆÊÊÊÍÍÍÎÎÎÑÑÑÕÕÕÒÒÒÑÑÑÎÎÎÍÍÍÑÑÑßßß×××ØØØÜÜÜëëëïïïæææóóóæææÀÀÀÇÇÇ×××ÔÔÔÕÕÕÔÔÔÒÒÒÕÕÕ×××ÙÙÙÜÜÜÝÝÝÜÜÜØØØÕÕÕÐÐÐÌÌÌÊÊÊÀÀÀ¼¼¼ÎÎÎàààãããÜÜÜÌÌÌÉÉÉÎÎÎÌÌÌÍÍÍÑÑÑÎÎÎÍÍÍÆÆÆÇÇÇÆÆÆ¾¾¾¾¾¾Â¾¾¾¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÌÌÌÊÊÊÂÂÂÍÍÍÜÜÜààà×××ÔÔÔÔÔÔÐÐÐÎÎÎÐÐÐÒÒÒ×××××××××ÕÕÕ×××ÙÙÙ×××ÔÔÔÔÔÔ×××ØØØØØØÕÕÕÛÛÛÝÝÝØØØÝÝÝàààÜÜÜßßßØØØÕÕÕÜÜÜÜÜÜàààçççäääßßßàààââââââââââââàààâââäääæææêêêèèèæææäääääääääæææçççæææççççççççççççæææäääãããúúúòòòííííííïïïêêêàààÜÜܵµµ°°°···±±±¬¬¬´´´···¸¸¸ÀÀÀÃÃÃÀÀÀÆÆÆÍÍÍÙÙÙ¿¿¿¸¸¸ÃÃÃÃÃÃÑÑÑãããäääÕÕÕÌÌÌÉÉÉÐÐÐÎÎÎÜÜÜää䨨ØÐÐÐÔÔÔÕÕÕÐÐÐÔÔÔÑÑÑÉÉÉÆÆÆÊÊÊÆÆÆ¼¼¼ããã×××ÒÒÒÒÒÒÔÔÔÕÕÕÒÒÒÉÉÉÌÌÌÍÍÍÔÔÔØØØÔÔÔÔÔÔÕÕÕÐÐÐÇÇÇÇÇÇÊÊʼ¼¼¿¿¿ØØØ×××ÇÇÇÉÉÉÅÅż¼¼···»»»ÀÀÀ¾¾¾µµµ°°°ºººÂ´´´³³³µµµ­­­µµµ³³³¸¸¸¾¾¾ÀÀÀÀÀÀ¿¿¿¿¿¿ÀÀÀ¼¼¼µµµ¯¯¯ªªªÅÅÅÃÃþ¾¾ÂÂÂÅÅÅÆÆÆ¿¿¿»»»Âººº¡¡¡ªªª±±±···´´´ªªª¤¤¤¨¨¨¯¯¯±±±´´´ººº¾¾¾ÀÀÀÃÃÃÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÌÌÌÊÊÊÑÑÑÔÔÔÔÔÔÐÐÐØØØÜÜÜçççëëëâââëëë×××¾¾¾ÉÉÉØØØ××××××ÕÕÕÒÒÒ×××ÕÕÕÕÕÕ×××ØØØØØØÕÕÕÑÑÑÕÕÕÇÇÇÇÇÇÑÑÑ×××âââèèèÝÝÝÔÔÔÉÉÉÍÍÍÑÑÑÉÉÉÆÆÆÌÌÌÌÌÌÉÉÉÂÂÂÀÀÀ¿¿¿»»»¼¼¼¿¿¿»»»¿¿¿ÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÉÉÉÉÉÉÌÌÌÙÙÙàààÝÝÝØØØÑÑÑÑÑÑÙÙÙÜÜÜØØØÒÒÒÒÒÒ×××ÙÙÙ×××ÒÒÒ×××ÕÕÕÒÒÒÒÒÒÔÔÔÔÔÔÒÒÒÑÑÑ×××ÙÙÙÑÑÑÕÕÕ×××ÔÔÔÙÙÙÕÕÕÜÜÜÝÝÝÛÛÛâââïïïñññçççäääâââãããäääãããââââââäääçççêêêêêêèèèççççççèèèèèèêêêêêêêêêêêêèèèçççæææãããâââïïïëëëêêêëëëëëëèèèäääàà຺º´´´ººº°°°©©©³³³µµµ···¾¾¾Â¾¾¾ÂÂÂÉÉÉÙÙÙ¾¾¾ÀÀÀÃÃÃÑÑÑäääêêêÝÝÝÔÔÔÕÕÕ×××ÎÎÎØØØäääàààßßßâââÝÝÝÛÛÛÎÎÎÌÌÌÒÒÒÍÍÍ¿¿¿ÀÀÀÑÑÑàààÕÕÕ×××ØØØÎÎÎÍÍÍÒÒÒÐÐÐÑÑÑÎÎÎÑÑÑÐÐÐÉÉÉÍÍÍÐÐÐÊÊÊÇÇÇÇÇÇÍÍ;¾¾¼¼¼ÔÔÔ×××ÎÎÎÆÆÆÇÇǺººººº¾¾¾¼¼¼µµµ¦¦¦¸¸¸ºººµµµÂÂÂÇÇÇÂÂÂÌÌÌ´´´´´´´´´···ººº¼¼¼¼¼¼¼¼¼´´´¯¯¯³³³±±±Â¾¾¾ÃÃÃÆÆÆººº¾¾¾ÀÀÀ»»»»»»ÃÃû»»¡¡¡©©©­­­´´´···°°°¦¦¦©©©³³³µµµµµµ···ººº¿¿¿ÆÆÆÌÌÌÐÐÐÊÊÊÍÍÍÍÍÍÐÐÐÊÊÊÉÉÉ××××××ÎÎÎÐÐÐ×××ÙÙÙßßßâââßßßâââÅÅÅÀÀÀÊÊÊÕÕÕ×××ÕÕÕÕÕÕÒÒÒ×××ÔÔÔÒÒÒÒÒÒÕÕÕÔÔÔÑÑÑÍÍÍÉÉɸ¸¸¼¼¼ÝÝÝêêêâââßßßÕÕÕÑÑÑÎÎÎÑÑÑÎÎÎÅÅž¾¾¿¿¿ÀÀÀÇÇÇÅÅÅÅÅÅÇÇÇÇÇÇÇÇÇÆÆÆÂÂÂÂÂÂÃÃÃÆÆÆÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅßßßßßßÕÕÕÒÒÒ×××ÔÔÔÔÔÔâââñññèèèÜÜÜÒÒÒÔÔÔÙÙÙÙÙÙÕÕÕÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÕÕÕÔÔÔÜÜÜØØØØØØÒÒÒÍÍÍÙÙÙÝÝÝââââââàààçççùùùÿÿÿõõõòòòæææèèèêêêçççäääâââãããæææèèèèèèèèèèèèêêêêêêêêêêêêêêêêêêèèèçççæææãããâââàààèèèäääçççêêêæææââââââßßßÒÒÒ¸¸¸³³³°°°­­­³³³´´´»»»¼¼¼ÀÀÀ¾¾¾ÃÃÃÇÇÇÒÒÒ¿¿¿ÀÀÀÃÃÃÇÇÇÎÎÎÛÛÛäääààààààèèèäääÛÛÛÙÙÙâââççççççßßßÔÔÔßßßÑÑÑÐÐÐÕÕÕÍÍ;¾¾ÇÇÇàààÙÙÙÙÙÙÙÙÙÔÔÔÍÍÍÎÎÎÒÒÒÒÒÒÍÍÍÌÌÌÐÐÐÎÎÎÊÊÊÎÎÎÎÎÎÆÆÆÊÊÊÅÅÅÎÎÎÇÇÇÀÀÀÍÍÍÔÔÔÙÙÙÇÇÇÍÍÍÊÊÊÀÀÀ¼¼¼¿¿¿¾¾¾······»»»···ÀÀÀÎÎÎÊÊÊÉÉÉÎÎÎÆÆÆ¿¿¿¸¸¸µµµ¸¸¸ººº¸¸¸µµµ¯¯¯¯¯¯¾¾¾¼¼¼ÅÅÅÂÂÂÇÇǾ¾¾»»»···»»»¿¿¿¿¿¿¾¾¾³³³¡¡¡¤¤¤ªªª´´´¸¸¸µµµ³³³´´´ºººÀÀÀ¼¼¼»»»¼¼¼ÃÃÃÉÉÉÌÌÌÌÌÌÆÆÆÊÊÊÌÌÌÐÐÐÇÇÇÆÆÆÕÕÕÔÔÔÊÊÊÔÔÔÔÔÔÒÒÒÔÔÔÛÛÛäääãã㸸¸ÆÆÆÍÍÍÐÐÐÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕÒÒÒÑÑÑÒÒÒÔÔÔÒÒÒÍÍÍÇÇÇÅÅÅÂÂÂÆÆÆßßßâââÒÒÒÒÒÒÐÐÐÇÇÇÌÌÌÉÉÉÂÂÂÂÂÂÀÀÀ¿¿¿ÀÀÀ¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÉÉÉÇÇÇÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÆÆÆÃÃÃÂÂÂæææØØØÎÎÎÑÑÑÔÔÔÑÑÑØØØæææëëëèèèßßßÒÒÒÍÍÍÐÐÐÒÒÒÑÑÑÐÐÐÒÒÒÒÒÒÒÒÒÒÒÒÕÕÕÜÜÜââââââëëëèèèèèèãããÝÝÝèèèëëëïïïñññîîîïïïøøøöööïïïïïïïïïñññòòòîîîçççââââââãããäääæææèèèêêêëëëêêêêêêèèèèèèèèèæææãããàààßßßÝÝÝÝÝÝíííâââäääêêêãããÝÝÝÜÜÜÙÙÙÔÔÔµµµ°°°°°°¯¯¯±±±´´´¾¾¾¼¼¼¿¿¿ÀÀÀÉÉÉÆÆÆÌÌ̸¸¸ÀÀÀÃÃÃÉÉÉÉÉÉÊÊÊÒÒÒÕÕÕÛÛÛçççêêêçççßßßÛÛÛàààâââÛÛÛÕÕÕÙÙÙÝÝÝÜÜÜÐÐÐÅÅÅÆÆÆÕÕÕãããÕÕÕÝÝÝÕÕÕÊÊÊÐÐÐ×××ÒÒÒÎÎÎÃÃÃÇÇÇÑÑÑ×××ÕÕÕ×××ÒÒÒÅÅÅÅÅÅ»»»ÇÇÇÉÉÉÀÀÀÀÀÀÉÉÉÙÙÙÌÌÌÐÐÐÍÍÍÃÃÃÂÂÂÅÅÅ¿¿¿´´´Â¸¸¸±±±ÊÊÊÔÔÔÇÇÇÌÌÌÎÎÎ×××ÑÑÑÇÇÇÀÀÀººº···´´´±±±¯¯¯°°°ÂÂÂÀÀÀÆÆÆÂ¼¼¼žžž¦¦¦›››¤¤¤···»»»´´´¬¬¬¡¡¡¦¦¦±±±¸¸¸¸¸¸···ºººººº···ÀÀÀ¾¾¾»»»¾¾¾ÃÃÃÃÃÿ¿¿»»»ÀÀÀÆÆÆÇÇÇÎÎÎÅÅÅÀÀÀÑÑÑÌÌÌÆÆÆÕÕÕÑÑÑÍÍÍÍÍÍØØØíííêêê±±±ÌÌÌÐÐÐÌÌÌÐÐÐÎÎÎÐÐÐÕÕÕÔÔÔÑÑÑÑÑÑÒÒÒÕÕÕÒÒÒÊÊÊÃÃÃ××׿ææãããßßßÒÒÒÆÆÆÍÍÍÊÊÊÎÎÎÔÔÔÆÆÆ»»»¿¿¿¿¿¿···µµµ°°°¯¯¯­­­¯¯¯´´´ººº¾¾¾ÂÂÂÆÆÆÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÂÂÂÀÀÀàààÎÎÎÑÑÑÙÙÙÑÑÑÌÌÌÙÙÙçççâââèèèèèèßßßÕÕÕÔÔÔ××××××ÙÙÙÛÛÛÛÛÛØØØ×××ÙÙÙãããëëëãããçççãããææææææâââçççäääèèèïïïïïïïïïóóóòòòïïïõõõöööøøøøøøòòòèèèâââàààâââãããäääçççêêêëëëêêêèèèççççççæææãããßßßÝÝÝÜÜÜÛÛÛÛÛÛíííÝÝÝßßßèèèæææßßßÝÝÝÛÛÛ¾¾¾°°°³³³°°°ªªª±±±´´´»»»»»»¿¿¿ÃÃÃÍÍÍÇÇÇÆÆÆ±±±¾¾¾ÂÂÂÉÉÉÅÅÅ¿¿¿ÃÃÃÆÆÆÌÌÌ×××ÝÝÝèèèâââÔÔÔÔÔÔÙÙÙàààíííÐÐÐØØØÙÙÙÌÌÌÎÎÎâââãããÛÛÛæææÝÝÝÕÕÕÑÑÑÒÒÒÔÔÔÎÎÎÊÊÊÑÑÑÒÒÒÔÔÔÕÕÕ×××ÕÕÕÕÕÕÔÔÔÎÎÎÆÆÆÂ¼¼¼ÂÂÂÅÅÅÆÆÆßßßÕÕÕÆÆÆÐÐо¾¾ÀÀÀ»»»­­­¿¿¿¿¿¿ÆÆÆÐÐÐÑÑÑÍÍÍÍÍÍÒÒÒØØØ×××ÕÕÕÑÑÑÇÇǸ¸¸°°°°°°©©©±±±¿¿¿ÉÉÉÉÉɵµµ­­­¥¥¥¤¤¤žžž¡¡¡©©©¨¨¨¦¦¦¯¯¯¯¯¯¸¸¸´´´°°°¢¢¢¯¯¯´´´¿¿¿¼¼¼»»»µµµ³³³ºººÆÆÆÊÊÊÇÇÇÇÇÇ···µµµºººÇÇÇÊÊÊÃÃÃ×××ØØØÐÐÐÍÍÍÕÕÕØØØÔÔÔ×××ÝÝÝßß߸¸¸ÉÉÉÐÐÐÊÊÊÔÔÔÍÍÍÔÔÔ×××ÑÑÑÑÑÑÕÕÕÎÎÎÅÅÅÉÉÉÕÕÕêêêØØØÌÌÌÊÊÊÆÆÆ¿¿¿ÃÃÃÎÎÎÀÀÀÇÇÇÀÀÀ»»»°°°­­­¼¼¼ÀÀÀ¿¿¿ÀÀÀÇÇÇÇÇǾ¾¾´´´±±±ºººµµµ¾¾¾ÉÉÉÉÉÉÇÇÇÆÆÆÀÀÀÛÛÛÑÑÑÍÍÍÑÑÑØØØÝÝÝæææïïïßßßâââãããßßßØØØÕÕÕØØØÜÜÜÑÑÑãããíííçççäääëëëîîîêêêèèèãããääääääøøøêêêääääääêêêíííïïïñññïïïïïïñññóóóøøøòòòõõõêêêâââãããÜÜÜãããæææÜÜÜäääñññêêêâââäääæææääääääâââßßßÜÜÜÙÙÙØØØ×××èèèæææãããâââââââââßßßÜÜÜØØØ¼¼¼¯¯¯°°°¬¬¬°°°¼¼¼Â¿¿¿ÀÀÀÉÉÉÒÒÒ×××ÔÔÔÑÑÑÑÑѺººººº¿¿¿ÆÆÆÇÇÇÆÆÆÇÇÇÌÌÌÙÙÙïïïæææØØØÝÝÝíííóóóßßßßßßÒÒÒÊÊÊÎÎÎÙÙÙàààÜÜÜ×××ÝÝÝÙÙÙ×××ÕÕÕÑÑÑÌÌÌÌÌÌÎÎÎÔÔÔÕÕÕ×××ØØØØØØØØØ×××ÕÕÕÒÒÒÊÊÊÇÇÇ¿¿¿»»»»»»ÒÒÒÕÕÕÆÆÆÐÐо¾¾¸¸¸»»»ººº¸¸¸ÀÀÀÍÍÍÒÒÒÕÕÕÒÒÒÎÎÎÊÊÊÌÌÌÍÍÍÒÒÒÕÕÕÎÎξ¾¾±±±¬¬¬´´´»»»ÃÃÃÉÉÉÉÉÉÃÃû»»´´´ººº´´´¨¨¨¢¢¢¦¦¦¥¥¥¨¨¨³³³³³³»»»¸¸¸³³³©©©­­­±±±···ÀÀÀÀÀÀ¼¼¼µµµ···¾¾¾ÅÅÅÇÇÇÇÇÇÅÅÅÃÃúºº¼¼¼ÅÅÅÅÅÅÕÕÕÉÉÉÌÌÌÔÔÔÜÜÜØØØÑÑÑ×××ääääää¾¾¾¾¾¾ÀÀÀÂÂÂÌÌÌÇÇÇÎÎÎÑÑÑÍÍÍÌÌÌÌÌÌÉÉÉÊÊÊ×××çççàààÕÕÕÎÎÎÎÎÎÎÎÎÊÊÊÌÌÌÑÑѵµµÂ¼¼¼µµµµµµ¼¼¼ÉÉÉÃÃÃÃÃÃÂÂÂÃÃÃÉÉÉÊÊÊÆÆÆÃÃÿ¿¿´´´ºººÉÉÉÊÊÊÅÅÅÃÃÃÂÂÂÝÝÝÕÕÕÑÑÑ×××àààãããâââààà×××ÛÛÛàààæææèèèêêêêêêêêêÝÝÝæææèèèääääääçççäääÝÝÝÛÛÛÛÛÛæææäääíííèèèîîîçççïïïíííèèèääääääçççíííñññòòòñññúúúõõõñññïïïæææèèèëëëäääççççççßßßÝÝÝââââââàààßßßÜÜÜÙÙÙØØØ×××××××××ààààààâââãããäääãããâââàààæææÍÍͺºº´´´±±±´´´ººº¼¼¼ÂÂÂÂÂÂÅÅÅÌÌÌÐÐÐÑÑÑÕÕÕÜÜÜàààâââçççëëëäää×××ÍÍÍÊÊÊÂÂÂÝÝÝäääãããæææÝÝÝÔÔÔÐÐÐÜÜÜÊÊÊÆÆÆÜÜÜêêêãããÝÝÝÝÝÝÔÔÔÕÕÕ×××ÕÕÕÍÍÍÅÅÅÊÊÊÔÔÔ×××ØØØÙÙÙÙÙÙÙÙÙÙÙÙ××××××ÎÎÎÇÇÇÊÊÊÆÆÆ¿¿¿µµµ···ÑÑÑØØØÆÆÆÌÌÌÀÀÀ¾¾¾´´´¼¼¼Â¸¸¸ÇÇÇÒÒÒÔÔÔÔÔÔÕÕÕÎÎÎÅÅÅÂÂÂÅÅÅÍÍÍÕÕÕÒÒÒÆÆÆ¸¸¸³³³¿¿¿ÀÀÀÃÃÃÅÅÅÃÃÃÀÀÀ¼¼¼ºººÂ¾¾¾±±±¨¨¨¨¨¨¤¤¤¦¦¦°°°µµµµµµµµµªªª©©©¨¨¨°°°³³³¿¿¿¿¿¿¼¼¼···´´´¸¸¸»»»»»»¿¿¿ÆÆÆÆÆÆ»»»¿¿¿ÇÇǼ¼¼¸¸¸ÀÀÀÆÆÆÑÑÑØØØÔÔÔÐÐÐØØØçççóóóÕÕÕ¾¾¾»»»ÀÀÀÃÃÃÂÂÂÆÆÆÌÌÌÇÇÇÃÃÃÃÃÃÉÉÉÒÒÒÜÜÜãããÔÔÔÎÎÎÇÇǼ¼¼¸¸¸´´´±±±ÃÃü¼¼³³³¼¼¼ÃÃÿ¿¿¾¾¾µµµ»»»¼¼¼¾¾¾¾¾¾¿¿¿ÃÃÃÇÇÇÉÉÉÆÆÆ´´´µµµÆÆÆÉÉÉÃÃÃÃÃÃÃÃÃ×××ÕÕÕÒÒÒÒÒÒÙÙÙãããæææäääÜÜÜÜÜÜÝÝÝãããçççêêêèèèæææíííèèèæææçççêêêèèèâââÛÛÛ³³³¼¼¼ÒÒÒ×××ÙÙÙâââñññèèèîîîíííëëëëëëíííïïïïïïñññîîîïïïùùùùùùøøøöööïïïñññóóóóóóóóóëëëààààààäääãããèèèæææâââÜÜÜÙÙÙ×××××××××ææææææäääâââàààßßßßßßààààààÒÒÒ»»»¯¯¯³³³¸¸¸¾¾¾ÅÅÅÃÃÃÅÅÅÊÊÊÐÐÐÐÐÐÍÍÍÎÎÎÔÔÔÕÕÕÕÕÕØØØÜÜÜÜÜÜØØØÙÙÙÝÝÝÊÊÊÑÑÑâââëëëæææ×××ÐÐÐÜÜÜÎÎÎÒÒÒÛÛÛíííîîîâââßßßÝÝÝÐÐÐÕÕÕ×××ÑÑÑÉÉÉÉÉÉÐÐÐ×××ØØØØØØÙÙÙÙÙÙÙÙÙØØØ×××ÕÕÕÍÍÍÇÇÇÍÍÍÇÇǼ¼¼´´´ºººÔÔÔÛÛÛÆÆÆÅÅÅ»»»¾¾¾¸¸¸¿¿¿¼¼¼ÆÆÆÎÎÎÔÔÔÒÒÒÑÑÑÐÐÐÌÌÌÆÆÆÅÅÅÃÃÃÇÇÇÐÐÐÒÒÒÌÌÌÅÅÅÂÂÂÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾Â¾¾¾···´´´­­­¨¨¨¬¬¬¼¼¼µµµ´´´¥¥¥¬¬¬ªªªººº¾¾¾¾¾¾¾¾¾»»»ººººººººº¸¸¸µµµºººÀÀÀ¼¼¼´´´¼¼¼ÉÉÉÅÅż¼¼»»»¾¾¾ÂÂÂÃÃÃÅÅÅÎÎÎÙÙÙäääØØØ»»»¸¸¸¿¿¿¸¸¸ººº¼¼¼µµµµµµ¸¸¸ÀÀÀÒÒÒâââäääÝÝÝÌÌÌÌÌÌÇÇÇÂÂÂÂÂÂÆÆÆÅÅÅÀÀÀººº´´´°°°ÂÂÂÆÆÆºººººº»»»¸¸¸¼¼¼¼¼¼¸¸¸···»»»ÀÀÀÃÃÃÉÉɸ¸¸µµµ¿¿¿ÃÃÃÅÅÅÆÆÆÂ¿¿¿ÉÉÉÎÎÎÊÊÊÉÉÉÐÐÐØØØÜÜÜàààÜÜÜ×××ÔÔÔÔÔÔ×××ÛÛÛÜÜÜëëëãããàààæææêêêçççâââààà°°°´´´¼¼¼¼¼¼¿¿¿ÐÐÐçççîîîäääæææèèèîîîòòòóóóñññîîîóóóòòòóóóòòòòòòöööùùùÿÿÿóóóöööùùùóóóèèèââââââäääßßßÝÝÝÛÛÛÛÛÛÜÜÜàààãããæææîîîëëëçççàààÜÜÜÝÝÝâââæææâââÝÝÝÆÆÆ°°°­­­¯¯¯³³³¿¿¿ÃÃÃÆÆÆÌÌÌÑÑÑÎÎÎÊÊÊÌÌÌÑÑÑÙÙÙÔÔÔÐÐÐÐÐÐÐÐÐÒÒÒÜÜÜæææÛÛÛÀÀÀÐÐÐÛÛÛÑÑÑÒÒÒØØØàààÉÉÉæææîîîëëëàààÙÙÙÛÛÛÍÍÍÑÑÑØØØÕÕÕÊÊÊÉÉÉÔÔÔÙÙÙÕÕÕ×××ØØØØØØØØØØØØÕÕÕÔÔÔÒÒÒÔÔÔÍÍÍÑÑÑÇÇǸ¸¸´´´¼¼¼ÔÔÔÔÔÔÉÉÉÆÆÆ¸¸¸»»»ºººÃÃø¸¸ÒÒÒÒÒÒÔÔÔ×××ÒÒÒÉÉÉÃÃÃÅÅÅÇÇÇÆÆÆÉÉÉÐÐÐÔÔÔÐÐÐÍÍÍÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅ¿¿¿ÇÇÇÉÉÉÅÅÅ···¬¬¬ªªª¸¸¸°°°¯¯¯¤¤¤ªªª¨¨¨µµµººº¾¾¾¾¾¾¿¿¿¾¾¾ºººººº¾¾¾Â¼¼¼ÇÇÇÅÅž¾¾»»»¸¸¸¼¼¼ÅÅÅÀÀÀ¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÍÍÍÕÕÕäääëëëÛÛÛÝÝÝæææÝÝÝâââäääçççíííîîîëëëëëëêêêàààÒÒÒÎÎÎÍÍÍÃÃõµµ°°°³³³±±±ªªª­­­ººº»»»¼¼¼µµµ±±±ÀÀÀÆÆÆÅÅÅÇÇÇÇÇǼ¼¼ººº»»»¿¿¿ÆÆÆ¿¿¿¼¼¼¸¸¸ºººÆÆÆÊÊÊ¿¿¿»»»ÌÌÌØØØÕÕÕÎÎÎÍÍÍÎÎÎÍÍÍÔÔÔÒÒÒÐÐÐÌÌÌÉÉÉÎÎÎÙÙÙãããàààÜÜÜÝÝÝääääääßßßßßßäääßßßÔÔÔ¾¾¾³³³±±±¾¾¾ÔÔÔîîîïïïîîîîîîñññõõõùùùùùùùùùæææèèèëëëïïïòòòñññïïïíííïïïîîîïïïñññêêêÝÝÝÝÝÝçççææææææäääæææèèèíííñññóóóèèèèèèçççäääããããããèèèíííâââçççÙÙÙÃÃ÷··­­­­­­ºººÂÂÂÂÂÂÅÅÅÇÇÇÉÉÉÊÊÊÔÔÔÝÝÝãããàààßßßÝÝÝÙÙÙÕÕÕ×××ÛÛÛæææÂÂÂÅÅÅÍÍÍÎÎÎÛÛÛÙÙÙÕÕÕÃÃÃêêêëëëÝÝÝÔÔÔØØØàààÆÆÆ×××ØØØÑÑÑÉÉÉÎÎÎÛÛÛÝÝÝÕÕÕ×××ØØØØØØØØØ×××ÔÔÔÑÑÑÐÐÐÑÑÑÌÌÌÎÎη··¾¾¾ÉÉÉØØØÉÉÉÊÊÊÌÌ̼¼¼¸¸¸µµµÊÊÊÀÀÀ×××ÔÔÔ×××ÙÙÙÔÔÔÆÆÆ¿¿¿ÀÀÀÇÇÇÆÆÆÌÌÌÒÒÒÔÔÔÐÐÐÊÊÊÊÊÊÀÀÀÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÀÀÀÉÉÉÇÇÇ¿¿¿¸¸¸­­­ªªª¾¾¾»»»¼¼¼ººº»»»µµµººº¼¼¼µµµ¸¸¸»»»···¯¯¯¬¬¬¸¸¸ÆÆÆºººÂ¿¿¿ÀÀÀ¾¾¾­­­­­­³³³»»»¿¿¿ÅÅÅÆÆÆÆÆÆÆÆÆÌÌÌÒÒÒÕÕÕäääßßßäääêêêãããææææææàààêêêïïïçççÝÝÝØØØÒÒÒÎÎÎÇÇÇÆÆÆ¾¾¾µµµ´´´ººº»»»¸¸¸ººº¼¼¼µµµ······¸¸¸ÇÇÇÌÌÌÐÐÐÎÎÎÍÍÍÊÊʸ¸¸µµµ»»»ÂÂÂÃÃ÷··³³³ÃÃÃÌÌÌ¿¿¿ÃÃÃÊÊÊÐÐÐÑÑÑÐÐÐÑÑÑÑÑÑÎÎÎÉÉÉÍÍÍÑÑÑÑÑÑÎÎÎÒÒÒÜÜÜäääßßßßßßäääèèèçççâââãããèèèñññèèèÍÍÍÀÀÀ······¾¾¾ØØØëëëíííïïïñññòòòòòòïïïîîîöööõõõíííîîîïïïñññùùùøøøòòòîîîëëëïïïíííâââäääõõõõõõóóóñññîîîíííííííííîîîçççèèèëëëëëëêêêçççæææäääãããçççäää×××ÆÆÆ···´´´¼¼¼ÂÂÂÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÐÐÐØØØÕÕÕÕÕÕÙÙÙÝÝÝÝÝÝØØØØØØÛÛÛêêê×××ÅÅÅÃÃÃÔÔÔßßßÔÔÔÍÍ;¾¾ãããäääßßßÙÙÙÜÜÜæææÎÎÎØØØÒÒÒÎÎÎÐÐÐÕÕÕÙÙÙÙÙÙØØØØØØÙÙÙÙÙÙØØØ×××ÔÔÔÑÑÑÐÐÐÌÌÌÆÆÆÊÊʼ¼¼µµµÇÇÇÔÔÔÙÙÙÇÇÇÇÇÇÇÇÇÀÀÀ¿¿¿¸¸¸ÑÑÑÎÎÎØØØØØØ×××ÔÔÔÍÍÍÆÆÆÂÂÂÂÂÂÆÆÆÆÆÆÊÊÊÐÐÐÎÎÎÆÆÆÂÂÂÃÃø¸¸¸¸¸¸¸¸¸¸¸»»»¿¿¿ÂÂÂÅÅÅÀÀÀÇÇÇÅÅÅ¿¿¿ÂÂÂÀÀÀ¸¸¸´´´³³³´´´µµµ»»»µµµ´´´±±±···´´´³³³´´´µµµ³³³¯¯¯°°°µµµ°°°···¯¯¯µµµ»»»´´´ººº¾¾¾­­­­­­°°°´´´ººº¿¿¿ÃÃÃÅÅÅÎÎÎØØØ×××ØØØÜÜÜÛÛÛÛÛÛÕÕÕÔÔÔÙÙÙÝÝÝÜÜÜØØØÕÕÕÔÔÔÒÒÒ¾¾¾¼¼¼ºººººº»»»¿¿¿¿¿¿¾¾¾ººº···±±±¿¿¿ÊÊÊÌÌÌÔÔÔÒÒÒÑÑÑÊÊÊÉÉÉÌÌÌÅÅŵµµ³³³»»»ÀÀÀÅÅÅÅÅźºº±±±¼¼¼ÉÉÉÃÃÃÀÀÀ¾¾¾»»»¼¼¼¾¾¾ÂÂÂÉÉÉÑÑÑÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÐÐÐÔÔÔ×××ÙÙÙÜÜÜâââççççççææææææèèèßßßäääÛÛÛÒÒÒºººµµµ´´´ÀÀÀäääèèèíííïïïïïïëëëèèèæææèèèàààÇÇÇÀÀÀÃÃÃÌÌÌâââçççñññòòòïïïñññóóóïïïïïïüüüíííëëëëëëêêêèèèêêêêêêêêêëëëëëëëëëêêêèèèæææâââÝÝÝîîîâââÙÙÙÑÑÑÀÀÀ´´´µµµ¸¸¸ÃÃÃÃÃÃÇÇÇÎÎÎÐÐÐÊÊÊÉÉÉÊÊÊÕÕÕÕÕÕÙÙÙÝÝÝÝÝÝÛÛÛÛÛÛßßßàààÝÝÝÇÇÇÃÃÃÒÒÒÒÒÒÌÌÌÇÇǼ¼¼âââèèèïïïæææÙÙÙâââÑÑÑØØØÍÍÍÌÌÌØØØÜÜÜÕÕÕÒÒÒÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØÔÔÔÑÑÑÐÐÐÎÎÎÊÊÊÍÍÍ»»»´´´ÉÉÉÑÑÑÐÐÐÎÎÎÃÃþ¾¾ÀÀÀÇÇÇ¿¿¿ØØØÕÕÕÛÛÛÜÜÜ×××ÉÉÉÃÃÃÆÆÆÉÉÉÇÇÇÇÇÇÆÆÆÇÇÇÉÉÉÅÅž¾¾¼¼¼ÀÀÀ¾¾¾¼¼¼¼¼¼¾¾¾ÀÀÀÆÆÆÍÍÍÐÐÐÅÅÅÍÍÍÍÍÍÊÊÊÑÑÑÒÒÒÌÌÌÇÇÇÅÅÅÇÇÇÅÅÅÐÐÐÇÇÇÌÌÌÊÊÊÕÕÕ¿¿¿µµµµµµÀÀÀÊÊʱ±±¥¥¥¯¯¯ÅÅÅÆÆÆÉÉÉÅÅÅ···»»»¾¾¾µµµ¬¬¬¥¥¥ªªª¼¼¼ÊÊÊÍÍÍÇÇÇÔÔÔÕÕÕÔÔÔÔÔÔÙÙÙââââââÙÙÙßßßØØØÔÔÔ×××ÙÙÙÕÕÕÊÊÊÀÀÀÃÃÃÂÂÂÀÀÀÀÀÀ¿¿¿ººº´´´°°°°°°ÇÇÇÐÐÐÒÒÒÐÐÐÎÎÎÒÒÒÉÉÉÒÒÒÇÇÇÆÆÆÎÎÎÉÉɸ¸¸···ÂÂÂÂÂÂÃÃÃÅÅž¾¾±±±···ÅÅÅÉÉÉÅÅÅÅÅÅÆÆÆÆÆÆ¿¿¿»»»ÅÅÅÒÒÒÉÉÉÆÆÆÅÅÅÆÆÆÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÎÎÎÔÔÔÙÙÙßßßãããâââßßßÜÜÜææææææÙÙÙ³³³³³³¸¸¸¾¾¾¼¼¼¼¼¼¼¼¼ºººººº¼¼¼ÂÂÂÆÆÆÃÃÃÉÉÉÂÂÂÊÊÊÍÍÍÇÇÇÊÊÊÂÂÂäääïïïññññññöööõõõïïïòòòÿÿÿÿÿÿúúúøøøõõõòòòñññïïïëëëçççãããâââãããææææææææææææÊÊʼ¼¼ººº³³³³³³¿¿¿ÅÅÅÆÆÆÃÃÃÃÃÃÇÇÇÊÊÊÊÊÊÍÍÍÑÑÑÒÒÒÕÕÕÜÜÜããããããÝÝÝÛÛÛÜÜÜØØØàààÛÛÛßßßßßßÕÕÕÔÔÔÌÌ̼¼¼ÀÀÀæææêêêÙÙÙääääää×××ÛÛÛÎÎÎÐÐÐØØØØØØÛÛÛÝÝÝÙÙÙÕÕÕØØØÙÙÙÛÛÛØØØÒÒÒÎÎÎÌÌÌÑÑÑÎÎο¿¿ºººÎÎÎÛÛÛÔÔÔÎÎÎÉÉÉÂÂÂÎÎÎÊÊÊÅÅÅÑÑÑ×××ÝÝÝäääÛÛÛÑÑÑÍÍÍÉÉÉÅÅÅÆÆÆÌÌÌÊÊÊÊÊÊÊÊÊÇÇÇÅÅž¾¾¼¼¼Â¿¿¿¾¾¾ÃÃÃÍÍÍÑÑÑÐÐÐÊÊÊÍÍÍÂÂÂÂÂÂÌÌÌÐÐÐÒÒÒÔÔÔÎÎÎÎÎÎÍÍÍÑÑÑ×××ØØØÔÔÔÒÒÒÔÔÔÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÃÃÃÅÅÅÉÉÉÌÌÌÊÊÊÃÃ÷··¯¯¯···ÀÀÀÇÇÇÀÀÀ···µµµÀÀÀÌÌÌÅÅÅÀÀÀÅÅÅÆÆÆÜÜÜÐÐÐÊÊÊÅÅÅÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÃÃþ¾¾ÀÀÀºººººº³³³¬¬¬ÅÅÅÍÍÍÍÍÍÐÐÐÑÑÑÒÒÒÒÒÒÒÒÒÑÑÑÇÇÇÉÉÉÎÎÎÉÉɸ¸¸³³³¼¼¼ÂÂÂÀÀÀÉÉÉÇÇÇÃÃþ¾¾°°°¯¯¯¾¾¾ÉÉÉÇÇÇÇÇÇÅÅÅ¿¿¿»»»ººº»»»ÕÕÕÐÐÐÊÊÊÇÇÇÃÃÃÂÂÂÇÇÇÎÎÎÊÊÊÐÐÐÒÒÒÒÒÒÙÙÙãããäääàààâââÒÒÒàààÔÔÔ···µµµººº¼¼¼¾¾¾ÂÂÂÆÆÆÅÅÅÂÂÂÀÀÀÃÃÃÆÆÆÆÆÆÉÉÉÎÎÎÎÎÎÌÌÌÇÇÇÆÆÆÆÆÆÇÇÇÜÜÜíííïïïëëëíííñññóóóöööõõõòòòòòòóóóöööúúúÿÿÿöööïïïèèèçççëëëëëëäääßßß´´´¸¸¸¾¾¾ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÅÅÅÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÑÑÑÐÐÐÑÑÑÕÕÕÛÛÛàààâââàààÝÝÝÛÛÛÛÛÛØØØÛÛÛààààààØØØÑÑÑÐÐÐÃÃÃÒÒÒïïïëëëßßßäääßßß×××ÜÜÜÒÒÒÔÔÔÜÜÜÛÛÛÛÛÛÛÛÛÕÕÕÛÛÛÙÙÙÙÙÙ×××ÔÔÔÒÒÒÑÑÑÐÐÐÍÍÍÉÉɼ¼¼¾¾¾ÐÐÐÙÙÙÔÔÔÐÐÐÒÒÒÆÆÆÍÍÍÇÇÇÅÅÅÒÒÒ×××ÜÜÜÙÙÙÒÒÒÎÎÎÎÎÎÍÍÍÉÉÉÇÇÇÊÊÊÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÀÀÀ¿¿¿ÅÅÅÂÂÂÃÃÃÇÇÇÐÐÐÔÔÔÒÒÒÐÐÐÒÒÒÉÉÉÇÇÇÍÍÍÌÌÌÎÎÎÔÔÔÔÔÔÒÒÒÌÌÌÅÅÅÅÅÅÅÅÅÇÇÇÐÐÐØØØ××××××ÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÍÍÍÅÅÅÇÇÇÌÌÌÑÑÑÔÔÔÐÐÐÉÉÉÃÃû»»¼¼¼¿¿¿ÃÃþ¾¾µµµµµµ¼¼¼ÎÎÎÌÌÌÍÍÍÉÉÉÕÕÕÌÌÌÐÐÐÔÔÔÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÊÊÊÆÆÆÃÃû»»´´´»»»¿¿¿ÉÉÉÌÌÌÉÉÉÙÙÙÐÐÐÒÒÒÕÕÕØØØØØØ×××ÕÕÕÒÒÒÕÕÕÎÎÎÌÌÌÃÃ÷··¸¸¸¿¿¿¼¼¼ÃÃÃÆÆÆÆÆÆÆÆÆÅÅż¼¼···¸¸¸ÂÂÂÆÆÆÅÅÅÀÀÀ¿¿¿ÂÂÂÀÀÀ»»»¿¿¿¿¿¿ÃÃÃÉÉÉÉÉÉÆÆÆÇÇÇÍÍÍÒÒÒÑÑÑÐÐÐÍÍÍÍÍÍÑÑÑÒÒÒÒÒÒÜÜÜØØØäääàààÆÆÆ¸¸¸ººº¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÉÉÉÃÃÃÀÀÀÇÇÇÌÌÌÎÎÎÐÐÐÍÍÍÊÊÊÇÇÇÇÇÇÂÂÂÔÔÔãããççççççêêêïïïòòòóóóñññîîîîîîîîîñññòòòòòòëëëÜÜÜÇÇǺºº···ººº¾¾¾¿¿¿ÀÀÀÃÃÃÇÇÇÇÇÇÆÆÆÃÃÃÃÃÃÃÃÿ¿¿ÂÂÂÆÆÆÊÊÊÎÎÎÐÐÐÎÎÎÎÎÎÒÒÒ×××ÛÛÛßßßàààßßßÜÜÜÙÙÙÛÛÛØØØÙÙÙÝÝÝÝÝÝÕÕÕÎÎÎÍÍÍÃÃÃàààòòòçççãããâââ×××ÙÙÙÙÙÙÔÔÔÕÕÕÛÛÛÙÙÙ×××ÔÔÔÎÎÎØØØØØØØØØ×××ÕÕÕÒÒÒÑÑÑÎÎÎÉÉɼ¼¼ÅÅÅÔÔÔØØØÒÒÒÑÑÑÕÕÕÉÉÉÉÉÉÆÆÆÇÇÇÒÒÒØØØÝÝÝÐÐÐÍÍÍÌÌÌÎÎÎÐÐÐÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÊÊÊÎÎÎÒÒÒÑÑÑÐÐÐÐÐÐÊÊÊÐÐÐÔÔÔÎÎÎÍÍÍÕÕÕØØØÊÊÊÃÃÿ¿¿ÀÀÀÀÀÀÀÀÀÅÅÅÊÊÊÇÇÇÇÇÇÆÆÆÃÃÿ¿¿¾¾¾¾¾¾»»»¾¾¾ÃÃÃÉÉÉÎÎÎÑÑÑÑÑÑÐÐл»»¼¼¼ÊÊÊÐÐÐÊÊÊÉÉÉÐÐЯ¯¯´´´ººº¸¸¸Â¾¾¾ÉÉÉ××××××ÒÒÒÌÌÌÅÅÅ¿¿¿¾¾¾¿¿¿ÂÂÂÉÉɼ¼¼ÃÃÃÌÌÌÑÑÑÕÕÕÑÑÑÒÒÒÑÑÑÒÒÒ×××ÙÙÙÙÙÙ×××ÔÔÔÑÑÑÒÒÒÍÍÍÇÇÇ»»»³³³»»»ÃÃÿ¿¿Â¿¿¿¿¿¿ÃÃÃÆÆÆÇÇÇÀÀÀ´´´»»»ÅÅÅÇÇÇÀÀÀ¾¾¾ÃÃÃÃÃü¼¼ººº¼¼¼ÂÂÂÊÊÊÌÌÌÇÇÇÇÇÇÌÌÌÉÉÉÇÇÇÉÉÉÊÊÊÌÌÌÊÊÊÌÌÌÎÎÎÕÕÕÜÜÜâââäääÎÎγ³³³³³»»»ÀÀÀÃÃÃÉÉÉÎÎÎÒÒÒÑÑÑÌÌÌÆÆÆÊÊÊÍÍÍÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉ¿¿¿ÇÇÇÍÍÍÊÊÊÅÅÅÂÂÂÂÂÂÂÂÂÛÛÛØØØÒÒÒÐÐÐÎÎÎÌÌÌÇÇÇÃÃÃÌÌÌÉÉÉÆÆÆÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÍÍÍÎÎÎÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆÆÆÆ¿¿¿ÂÂÂÇÇÇÌÌÌÎÎÎÐÐÐÐÐÐÐÐÐÕÕÕØØØÜÜÜßßßßßßÝÝÝÙÙÙ×××ÙÙÙ×××ØØØÛÛÛÙÙÙÒÒÒÌÌÌÉÉÉ»»»ãããëëëÜÜÜâââÜÜÜÐÐÐÛÛÛÕÕÕÑÑÑÑÑÑÔÔÔÒÒÒÑÑÑÎÎÎÊÊÊÎÎÎÑÑÑÔÔÔØØØØØØÔÔÔÎÎÎÉÉÉÇÇÇ¿¿¿ÀÀÀÎÎÎÙÙÙÕÕÕÐÐÐÒÒÒÐÐÐÇÇÇÆÆÆÆÆÆÇÇÇÎÎÎ×××ßßßÑÑÑÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÅÅÅÇÇÇÔÔÔÛÛÛÑÑÑÍÍÍÒÒÒÕÕÕÆÆÆÂÂÂÀÀÀÃÃÃÃÃÿ¿¿¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾»»»ººº¸¸¸···µµµ±±±´´´···¼¼¼ÃÃÃÉÉÉÍÍÍÐÐÐÐÐÐÆÆÆÀÀÀÂÂÂÅÅÅÃÃÃÃÃÃÆÆÆÆÆÆÌÌÌÎÎÎÌÌÌÉÉɼ¼¼¸¸¸ÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾ÂÂÂÉÉÉÐÐÐÅÅż¼¼ÆÆÆÑÑÑÒÒÒØØØÙÙÙÒÒÒ××××××ØØØÙÙÙÙÙÙØØØ×××ÕÕÕÊÊÊÍÍÍÌÌ̼¼¼­­­´´´¾¾¾ºººÀÀÀººººººººº¸¸¸¾¾¾»»»©©©µµµÀÀÀÉÉÉÅÅÅ¿¿¿¿¿¿ÀÀÀ¿¿¿ººº¸¸¸¸¸¸ººº···´´´µµµººº¼¼¼¾¾¾ÆÆÆÐÐÐÒÒÒÎÎÎÌÌÌÎÎÎÎÎÎÛÛÛÛÛÛâââÒÒÒ±±±³³³ÀÀÀÃÃÃÆÆÆÉÉÉÍÍÍÎÎÎÐÐÐÎÎÎÎÎÎÌÌÌÎÎÎÑÑÑÔÔÔÒÒÒÐÐÐÍÍÍÌÌÌÍÍÍÎÎÎÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÅÅÅÎÎÎÍÍÍÍÍÍÐÐÐÒÒÒÔÔÔÑÑÑÍÍÍÌÌÌÍÍÍÑÑÑÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÌÌÌÉÉÉÇÇÇÇÇÇÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÑÑÑÒÒÒÔÔÔØØØÙÙÙÜÜÜßßßÝÝÝÜÜÜØØØÕÕÕ×××ÕÕÕ×××××××××ÑÑÑÌÌÌÇÇÇ¿¿¿äääãããØØØààà×××ÍÍÍÛÛÛÔÔÔÔÔÔÑÑÑÐÐÐÑÑÑÒÒÒÐÐÐÎÎÎÊÊÊÌÌÌÎÎÎÒÒÒÔÔÔÒÒÒÍÍÍÇÇÇÇÇÇÀÀÀÆÆÆ×××ÜÜÜÕÕÕÐÐÐÑÑÑÉÉÉÉÉÉÇÇÇÉÉÉÇÇÇÅÅÅÍÍÍ×××ÕÕÕÕÕÕÒÒÒÎÎÎÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÇÇÇÉÉÉÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÇÇÇÔÔÔÙÙÙÍÍÍÆÆÆÌÌÌÐÐÐÒÒÒÉÉÉ¿¿¿¿¿¿¾¾¾¾¾¾ÀÀÀ¾¾¾¾¾¾¼¼¼»»»ººº¸¸¸······µµµ···¸¸¸»»»¿¿¿ÅÅÅÊÊÊÎÎÎÒÒÒÔÔÔÍÍÍ»»»¾¾¾¿¿¿¼¼¼¼¼¼ÀÀÀÀÀÀÆÆÆÉÉÉÀÀÀ¸¸¸¼¼¼···¾¾¾ÅÅÅÊÊÊÊÊÊÉÉÉÇÇÇÇÇǺºº¾¾¾ÌÌÌÕÕÕÒÒÒØØØàààÙÙÙÜÜÜÛÛÛØØØ××××××ØØØÙÙÙÛÛÛÒÒÒ××××××ÆÆÆµµµµµµµµµªªª···´´´······µµµÂÂÂÉÉÉÀÀÀµµµµµµ¼¼¼ÅÅÅÆÆÆÂ¿¿¿ÂÂÂÇÇÇÃÃÃÀÀÀÀÀÀ¼¼¼¸¸¸»»»ÀÀÀ¿¿¿¿¿¿ÆÆÆÐÐÐÑÑÑÌÌÌÇÇÇÉÉÉÉÉÉ×××ÕÕÕàààÙÙÙ¸¸¸µµµÂÂÂÂÂÂÆÆÆÌÌÌÍÍÍÊÊÊÉÉÉÊÊÊÎÎÎÌÌÌÎÎÎÑÑÑÔÔÔÔÔÔÒÒÒÐÐÐÎÎÎÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÇÇÇÉÉÉÊÊÊÆÆÆÇÇÇÌÌÌÑÑÑÕÕÕØØØ×××ÔÔÔ××××××ÕÕÕÒÒÒÑÑÑÒÒÒÔÔÔ×××ÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔÕÕÕÙÙÙÛÛÛÝÝÝßßßÝÝÝÛÛÛØØØÕÕÕÕÕÕÕÕÕÕÕÕÕÕÕÔÔÔÑÑÑÍÍÍÇÇÇÔÔÔèèèàààÜÜÜàààÒÒÒÍÍÍØØØ×××ÛÛÛ×××ÔÔÔ×××ØØØ××××××ÎÎÎÌÌÌÉÉÉÉÉÉÌÌÌÍÍÍÌÌÌÉÉÉÅÅÅ¿¿¿ÊÊÊÛÛÛÜÜÜÔÔÔÑÑÑÐÐÐÉÉÉÌÌÌÆÆÆÊÊÊÉÉɾ¾¾ÂÂÂÌÌÌÔÔÔØØØ×××ÑÑÑÌÌÌÌÌÌÎÎÎÎÎÎÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÉÉÉÉÉÉÑÑÑÑÑÑÅÅÅ¿¿¿ÇÇÇÍÍÍÕÕÕÊÊÊÀÀÀ¿¿¿¿¿¿¾¾¾¿¿¿Â¸¸¸¸¸¸······µµµµµµµµµµµµ¸¸¸¸¸¸ººº»»»¼¼¼¿¿¿ÅÅÅÇÇÇÇÇÇ×××ÜÜÜÒÒÒÎÎÎÒÒÒÕÕÕÒÒÒÊÊÊÉÉɾ¾¾ÆÆÆÌÌÌÎÎÎÆÆÆÌÌÌÉÉÉÌÌÌÎÎÎÎÎÎÌÌÌÅÅÅ¿¿¿»»»»»»ÊÊÊÔÔÔØØØÔÔÔÔÔÔÜÜÜ×××ØØØÔÔÔÎÎÎÊÊÊÊÊÊÎÎÎÔÔÔØØØÛÛÛØØØ×××ÐÐÐÉÉÉÇÇÇ¿¿¿­­­¥¥¥¦¦¦©©©ªªªªªª´´´¿¿¿Âººº­­­¬¬¬¼¼¼ÉÉÉÇÇÇÃÃÃÃÃþ¾¾¼¼¼¾¾¾¿¿¿¾¾¾ººº»»»¿¿¿ÅÅÅÂÂÂÀÀÀÅÅÅÇÇÇÉÉÉÇÇÇÉÉÉÇÇÇÑÑÑÔÔÔÝÝÝØØØºººªªª¯¯¯´´´¼¼¼ÆÆÆÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÊÊÊÌÌÌÎÎÎÒÒÒÕÕÕÕÕÕÒÒÒÐÐÐÔÔÔÐÐÐÍÍÍÌÌÌÉÉÉÆÆÆÅÅÅÇÇÇÑÑÑÔÔÔØØØÛÛÛÜÜÜÛÛÛÙÙÙØØØ×××ØØØÛÛÛÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝÕÕÕÕÕÕÕÕÕ×××ØØØØØØÕÕÕÔÔÔÐÐÐÎÎÎÎÎÎÐÐÐÔÔÔÕÕÕ×××ÕÕÕÛÛÛÜÜÜÝÝÝßßßÝÝÝÛÛÛØØØ×××ÕÕÕÕÕÕÕÕÕÒÒÒÑÑÑÐÐÐÊÊÊÅÅÅäääçççÜÜÜßßßÝÝÝÎÎÎÐÐÐÔÔÔØØØßßßÜÜÜ×××ÛÛÛÜÜÜØØØØØØÕÕÕÐÐÐÉÉÉÇÇÇÉÉÉÊÊÊÉÉÉÆÆÆ¾¾¾¼¼¼ÌÌÌÛÛÛØØØÔÔÔÒÒÒÎÎÎÌÌÌÌÌÌ¿¿¿ÇÇÇÍÍÍÀÀÀÂÂÂÆÆÆÉÉÉÔÔÔÛÛÛ×××ÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÉÉÉÉÉÉÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÇÇÇÅÅÅÊÊÊÍÍÍÃÃÃÀÀÀÇÇÇÌÌÌÉÉɾ¾¾ÀÀÀ¿¿¿¼¼¼¼¼¼¸¸¸¸¸¸¸¸¸ºººººººººººººººµµµ¸¸¸ººººººººº»»»¿¿¿ÂÂÂÂÂÂÑÑÑÜÜÜÛÛÛ×××××××××ÕÕÕÔÔÔÎÎλ»»ÀÀÀÃÃÃÌÌÌÅÅÅÎÎÎÊÊÊÇÇÇÅÅÅÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ´´´ÌÌÌÐÐÐÔÔÔÕÕÕÕÕÕÜÜÜ×××ÒÒÒÍÍÍÇÇÇÃÃÃÃÃÃÉÉÉÐÐÐÕÕÕÙÙÙÒÒÒÒÒÒÔÔÔÒÒÒÒÒÒÍÍÍÀÀÀÇÇÇÉÉÉÆÆÆÂ¿¿¿¸¸¸···¼¼¼¼¼¼³³³­­­´´´¾¾¾ÀÀÀÃÃÃÅÅÅÅÅÅÃÃÃÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÆÆÆÅÅÅ¿¿¿¿¿¿ÅÅÅÌÌÌÍÍÍÉÉÉÉÉÉÊÊÊÔÔÔÙÙÙØØØÇÇÇ´´´±±±µµµ¸¸¸¼¼¼ÃÃÃÊÊÊÎÎÎÎÎÎÌÌÌÆÆÆÇÇÇÌÌÌÑÑÑÕÕÕ×××ÔÔÔÑÑÑÌÌÌÇÇÇÆÆÆÉÉÉÇÇÇÅÅÅÅÅÅÉÉÉÇÇÇÍÍÍÔÔÔØØØÙÙÙÛÛÛÝÝÝàààÝÝÝÜÜÜÙÙÙØØØØØØÙÙÙÛÛÛÛÛÛØØØ×××ØØØÛÛÛÜÜÜÜÜÜÙÙÙ×××ÔÔÔÑÑÑÒÒÒ×××ßßßâââßßßÛÛÛÜÜÜÝÝÝßßßßßßßßßÜÜÜÙÙÙØØØÕÕÕ×××ÕÕÕÐÐÐÍÍÍÌÌÌÆÆÆ¾¾¾ëëëàààÔÔÔßßßÛÛÛÌÌÌÒÒÒÑÑÑÕÕÕàààÝÝÝØØØÜÜÜÛÛÛÔÔÔÔÔÔ×××ÑÑÑÍÍÍÍÍÍÍÍÍÊÊÊÅÅÅ¿¿¿···ºººÊÊÊØØØÕÕÕÒÒÒÔÔÔÎÎÎÌÌÌÇÇǵµµÃÃÃÑÑÑÇÇÇÇÇÇÉÉɼ¼¼ÍÍÍÛÛÛÛÛÛÒÒÒÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¼¼¼ÆÆÆÎÎÎÉÉÉÆÆÆÌÌÌÍÍÍ»»»···»»»¾¾¾¾¾¾»»»»»»µµµµµµ······¸¸¸¸¸¸ºººººº¸¸¸»»»¾¾¾¾¾¾¾¾¾¿¿¿ÂÂÂÅÅÅÂÂÂÊÊÊÔÔÔÛÛÛÙÙÙ××××××ÙÙÙÕÕÕÎÎθ¸¸»»»ºººÀÀÀ»»»ÅÅÅÃÃÃÀÀÀ¾¾¾¾¾¾¾¾¾¼¼¼¸¸¸µµµµµµÐÐÐÌÌÌÍÍÍÔÔÔÒÒÒÕÕÕÎÎÎØØØÒÒÒÍÍÍÉÉÉÊÊÊÐÐÐØØØÜÜÜØØØÒÒÒÕÕÕ×××ÐÐÐÍÍÍÎÎÎÊÊÊÇÇÇÊÊÊÆÆÆÆÆÆÆÆÆ¸¸¸­­­´´´¾¾¾¾¾¾ººº±±±¯¯¯´´´¿¿¿ÇÇÇÊÊÊÆÆÆÂ¿¿¿»»»µµµ···¼¼¼ÉÉÉÇÇÇÅÅÅÃÃÃÉÉÉÑÑÑÍÍÍÃÃÃÉÉÉÃÃÃÒÒÒÛÛÛâââäää×××ÔÔÔÊÊÊ»»»¼¼¼ÅÅÅÊÊÊÇÇÇÀÀÀÅÅÅÆÆÆÊÊÊÐÐÐÕÕÕØØØÕÕÕÒÒÒÐÐÐÌÌÌÊÊÊÍÍÍÌÌÌÇÇÇÉÉÉÎÎÎÌÌÌÒÒÒÙÙÙÛÛÛÙÙÙØØØÛÛÛßßß×××××××××ÙÙÙÛÛÛÜÜÜÛÛÛØØØ××××××ØØØÛÛÛÜÜÜÜÜÜØØØÔÔÔ×××ÕÕÕØØØàààëëëîîîèèèâââÝÝÝÝÝÝßßßàààßßßÝÝÝÛÛÛÙÙÙ×××ØØØÕÕÕÍÍÍÉÉÉÇÇÇÀÀÀ¸¸¸îîîïïïÙÙÙâââââââââÕÕÕÐÐÐÕÕÕÕÕÕ×××ÙÙÙÛÛÛÙÙÙ×××ÔÔÔÔÔÔÐÐÐÎÎÎÐÐÐÎÎÎÇÇÇÃÃÃÅÅŵµµÌÌÌÙÙÙÕÕÕÔÔÔÙÙÙÔÔÔÉÉÉÎÎÎÇÇǾ¾¾´´´±±±µµµÀÀÀÇÇÇÇÇÇÆÆÆÌÌÌÜÜÜãããÎÎÎÅÅÅÒÒÒÊÊÊÊÊÊÆÆÆÀÀÀÃÃÃÉÉÉÆÆÆ¿¿¿ÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾ÂÂÂÀÀÀ¾¾¾¼¼¼ÅÅÅÌÌÌÇÇÇ¿¿¿¸¸¸¸¸¸ººº»»»»»»»»»ºººººº¸¸¸···µµµµµµµµµ···¸¸¸ºººººº¾¾¾»»»ºººÀÀÀÀÀÀÃÃÃÑÑÑ×××ÙÙÙÛÛÛ×××ØØØÛÛÛÙÙÙÕÕÕØØØÉÉÉ»»»ººº¾¾¾¾¾¾¿¿¿ÀÀÀ¿¿¿¼¼¼»»»¼¼¼¿¿¿¾¾¾»»»¸¸¸´´´ÅÅÅÐÐÐÎÎÎÊÊÊÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÌÌÌÅÅÅÊÊÊ×××ÙÙÙÕÕÕ××××××ÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÎÎÎÊÊÊÌÌÌÆÆÆÇÇÇÉÉɺºº©©©¬¬¬±±±»»»ÀÀÀ»»»¯¯¯ªªª³³³¾¾¾ÅÅž¾¾¸¸¸µµµ±±±¯¯¯´´´¾¾¾ÍÍ;¾¾ÉÉÉÒÒÒÒÒÒÎÎÎÍÍÍÆÆÆÇÇÇÊÊÊÐÐÐ×××ÜÜÜßßßßßßâââØØØÀÀÀ´´´¼¼¼¿¿¿¼¼¼ÀÀÀ¿¿¿ÂÂÂÆÆÆÉÉÉÎÎÎÔÔÔÑÑÑÌÌÌÉÉÉÆÆÆÊÊÊÊÊÊÊÊÊÌÌÌÉÉÉÇÇÇÌÌÌÎÎÎÒÒÒÔÔÔÕÕÕ×××ÙÙÙÛÛÛÙÙÙ××××××ØØØÜÜÜÝÝÝÝÝÝÜÜÜÙÙÙÛÛÛÜÜÜÝÝÝßßßÝÝÝÜÜÜÛÛÛÝÝÝÙÙÙÙÙÙãããîîîñññçççÜÜÜßßßÛÛÛØØØÙÙÙÝÝÝßßßÛÛÛ×××ÑÑÑ×××ÅÅż¼¼ÆÆÆäääâââäääèèèíííÙÙÙâââàààâââØØØÔÔÔÛÛÛÙÙÙØØØØØØØØØ×××ÔÔÔÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÉÉÉÃÃÿ¿¿¾¾¾¿¿¿ÐÐÐÙÙÙÕÕÕÔÔÔ×××ÑÑÑÆÆÆÊÊÊÇÇÇÀÀÀºººµµµ···¼¼¼ÀÀÀÇÇÇÃÃÃÀÀÀÌÌÌÛÛÛ×××ÊÊÊÉÉÉÇÇÇÊÊÊÉÉÉÅÅÅÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÀÀÀ¿¿¿¼¼¼»»»»»»»»»»»»»»»»»»¸¸¸···¼¼¼Â¿¿¿¸¸¸µµµ···¸¸¸ººº»»»»»»ºººººº···············¸¸¸ººº»»»···µµµºººÆÆÆÍÍÍÇÇÇÉÉÉÔÔÔÍÍÍÎÎÎÐÐÐÒÒÒÙÙÙßßßØØØÍÍÍÃÃúºº´´´···¾¾¾¿¿¿ÀÀÀÃÃþ¾¾¾¾¾¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»°°°¸¸¸ÀÀÀÅÅÅÊÊÊÍÍÍÍÍÍÌÌÌ×××ÜÜÜÕÕÕÉÉÉÌÌÌÙÙÙÛÛÛÐÐÐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÆÆÆÅÅŵµµ©©©¥¥¥³³³ºººÀÀÀÀÀÀ»»»······ººº±±±±±±±±±±±±­­­¬¬¬¯¯¯´´´ÉÉÉÆÆÆÀÀÀ¿¿¿ÃÃÃÊÊÊÉÉÉÅÅÅÊÊÊÊÊÊÉÉÉÉÉÉÊÊÊÎÎÎÒÒÒÕÕÕÝÝÝããããããÝÝÝ×××ÉÉɺºº´´´³³³µµµ¸¸¸¸¸¸¾¾¾ÆÆÆÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÉÉÉÊÊÊÍÍÍÑÑÑÒÒÒÔÔÔÔÔÔ×××ØØØØØØ××××××ØØØÛÛÛÝÝÝÝÝÝÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÜÜÜÙÙÙÙÙÙÙÙÙßßßãããäääàààÜÜÜÜÜÜÙÙÙÙÙÙÛÛÛßßßßßßÛÛÛ×××ÐÐÐÒÒÒÉÉÉÒÒÒÛÛÛëëëãããçççÜÜÜãããÔÔÔßßßâââçççãããäääçççâââÙÙÙÔÔÔÒÒÒÔÔÔÔÔÔÕÕÕÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÌÌÌÒÒÒØØØ×××ÔÔÔÒÒÒÍÍÍÃÃÃÇÇÇÇÇÇÆÆÆÂ¼¼¼¸¸¸······ÆÆÆÇÇÇÀÀÀÀÀÀÐÐÐÛÛÛÔÔÔÊÊÊÇÇÇÉÉÉÊÊÊÉÉɾ¾¾¿¿¿ÅÅÅÀÀÀ¿¿¿¼¼¼»»»¸¸¸¸¸¸······¸¸¸¸¸¸···µµµ···ººº¸¸¸´´´³³³´´´µµµ¸¸¸ºººººººººººº······¸¸¸¸¸¸¸¸¸ººº»»»»»»¿¿¿µµµ¼¼¼ÊÊÊÅÅŵµµ°°°µµµººº¿¿¿ÇÇÇÎÎÎÔÔÔÒÒÒÇÇÇ»»»¾¾¾»»»»»»¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿ÃÃÃÆÆÆÅÅÅÂÂÂÀÀÀ¾¾¾¾¾¾´´´¯¯¯¯¯¯¸¸¸ÅÅÅÉÉÉÊÊÊÊÊÊÑÑÑØØØÕÕÕÇÇÇÌÌÌÝÝÝàààÒÒÒÑÑÑÑÑÑÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÉÉÉÉÉÉÇÇÇÃÃÿ¿¿µµµ¨¨¨¬¬¬°°°···¾¾¾Â¿¿¿¼¼¼ÀÀÀÂÂÂÃÃÃÂÂÂÂÂÂÀÀÀ»»»µµµ¿¿¿ÇÇÇÇÇǼ¼¼¾¾¾ÌÌÌÑÑÑÌÌÌÆÆÆÆÆÆÃÃÃÂÂÂÂÂÂÇÇÇÒÒÒÛÛÛâââãããëëëîîîçççäääãããßßßââââââÙÙÙÉÉɾ¾¾¾¾¾¿¿¿ÀÀÀÂÂÂÆÆÆÅÅÅÆÆÆÇÇÇÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÕÕÕ×××ÕÕÕÕÕÕØØØÛÛÛÜÜÜÜÜÜÜÜÜßßßÜÜÜÙÙÙ××××××ØØØÛÛÛÜÜÜÙÙÙÛÛÛÜÜÜÛÛÛÙÙÙÙÙÙÜÜÜßßßØØØØØØÙÙÙÜÜÜàààßßßÙÙÙÕÕÕÐÐÐÌÌÌÇÇÇãããëëëíííãããëëëæææíííÙÙÙßßßÜÜÜàààßßßãããçççäääßßßÜÜÜÙÙÙØØØÔÔÔÑÑÑÒÒÒÑÑÑÊÊÊÅÅÅÅÅÅÌÌÌÑÑÑÒÒÒÕÕÕÔÔÔ××××××ÒÒÒÒÒÒÎÎÎÅÅÅÇÇÇÊÊÊÊÊÊÇÇÇÀÀÀººº³³³°°°ÆÆÆÎÎÎÍÍÍÅÅÅÉÉÉÔÔÔÙÙÙØØØÎÎÎÊÊÊÇÇÇÇÇǼ¼¼¿¿¿ÆÆÆÀÀÀ¿¿¿¾¾¾»»»¸¸¸······µµµººººººººº······µµµµµµ´´´°°°±±±³³³µµµ···¸¸¸ººº»»»¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¿¿¿ºººÅÅÅÎÎÎÀÀÀ´´´µµµ···ººº¾¾¾¾¾¾ºººµµµµµµ¸¸¸¼¼¼ÀÀÀÂÂÂÅÅÅÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÃÃÃÃÃÃÃÃÿ¿¿ººº»»»­­­¨¨¨³³³¿¿¿ÂÂÂÆÆÆÌÌÌÌÌÌÌÌÌÉÉÉÃÃÃÇÇÇØØØßßßÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÆÆÆÇÇÇÆÆÆ¿¿¿ÀÀÀ»»»©©©¬¬¬­­­°°°´´´¸¸¸»»»¼¼¼¼¼¼Â¿¿¿¿¿¿ÅÅÅÉÉÉÀÀÀ´´´µµµÃÃÃÉÉÉÀÀÀ¿¿¿ÉÉÉÐÐÐÍÍÍÎÎÎÎÎÎÌÌÌÅÅÅ¿¿¿ÂÂÂÊÊÊÔÔÔßßß×××ÛÛÛàààßßßçççíííçççèèèêêêâââÐÐÐÀÀÀ»»»¼¼¼¿¿¿µµµ¿¿¿¼¼¼ÂÂÂÉÉÉÅÅÅÅÅÅÃÃÃÊÊÊÍÍÍÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÕÕÕ×××ÙÙÙÛÛÛÜÜÜÜÜÜßßßÜÜÜØØØÕÕÕÔÔÔÕÕÕ×××ÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØÙÙÙÜÜÜàààÕÕÕ×××ÙÙÙÝÝÝàààßßßÙÙÙÔÔÔÎÎÎÇÇÇÂÂÂãããëëëëëëçççïïïëëëñññÛÛÛßßßÛÛÛßßßßßßæææÝÝÝâââæææêêêèèèàààÔÔÔÌÌÌÎÎÎÌÌÌÇÇÇÉÉÉÍÍÍÕÕÕÙÙÙÛÛÛ×××ÒÒÒÕÕÕ×××ÑÑÑÔÔÔÔÔÔÉÉÉÉÉÉÌÌÌÍÍÍÉÉɺºº³³³¯¯¯ÆÆÆÌÌÌÑÑÑÍÍÍÇÇÇÌÌÌÕÕÕÛÛÛØØØÍÍÍÅÅÅÃÃÃÃÃÃÀÀÀÀÀÀÆÆÆÃÃÿ¿¿¼¼¼»»»ººº¸¸¸¸¸¸»»»ºººººº¸¸¸µµµ³³³³³³´´´°°°°°°±±±³³³µµµ¸¸¸ººº»»»ºººººº¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸»»»ÀÀÀÌÌÌÊÊʺºº¸¸¸ÂÂÂÃÃÃÃÃÃÆÆÆÉÉÉÇÇǼ¼¼¼¼¼¿¿¿ÀÀÀÅÅÅÉÉÉÇÇÇÃÃÃÃÃÃÃÃÃÅÅźººººº¸¸¸¸¸¸¿¿¿ÅÅÅÀÀÀµµµµµµªªªªªª¸¸¸ÂÂÂÂÂÂÅÅÅÍÍÍÒÒÒÅÅÅÂÂÂÅÅÅÅÅÅÍÍÍØØØ×××ÎÎÎÍÍÍÌÌÌÍÍÍÐÐÐÑÑÑÐÐÐÎÎÎÌÌÌÇÇÇÉÉÉÇÇÇÀÀÀÅÅÅÃÃô´´¾¾¾¼¼¼¸¸¸±±±­­­¯¯¯´´´ºººªªª°°°´´´´´´ºººÃÃÃÅÅÅÀÀÀ³³³»»»ÂÂÂÃÃÃÀÀÀ¾¾¾¿¿¿ÀÀÀÍÍÍÐÐÐÐÐÐÊÊÊÂÂÂÀÀÀÆÆÆÍÍÍÊÊÊÉÉÉ×××ããããããäääâââÕÕÕäääëëëîîîçççàààßßßâââäää¿¿¿ÆÆÆººº¼¼¼ÆÆÆÂÂÂÅÅÅÅÅÅÉÉÉÌÌÌÎÎÎÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÑÑÑÒÒÒÔÔÔ×××ØØØÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛØØØ×××ÔÔÔÒÒÒÒÒÒÒÒÒÔÔÔÔÔÔÒÒÒÔÔÔØØØÛÛÛÜÜÜÜÜÜÕÕÕ×××ÙÙÙÜÜÜÝÝÝÜÜÜØØØÔÔÔÌÌÌÉÉÉÂÂÂäääëëëîîîïïïñññçççîîîÙÙÙàààÝÝÝäääæææíííãããããããããäääãããßßßÙÙÙÕÕÕÇÇÇÂÂÂÃÃÃÎÎÎØØØÙÙÙ×××ÕÕÕÔÔÔÑÑÑÕÕÕÕÕÕÐÐÐØØØÛÛÛÍÍÍÊÊÊÌÌÌÌÌÌÉÉɺºº´´´±±±ÃÃÃÂÂÂÇÇÇÍÍÍÊÊÊÊÊÊÎÎÎÎÎÎÜÜÜÑÑÑÇÇÇÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼¼¼¼»»»»»»ººº·········´´´°°°°°°±±±°°°°°°±±±³³³´´´···ººº»»»»»»ººº¸¸¸¸¸¸¸¸¸ººº¼¼¼¾¾¾ÆÆÆÍÍÍÑÑÑÅÅŵµµ···¾¾¾¿¿¿ÍÍÍÅÅž¾¾¿¿¿ÂÂÂÃÃÃÃÃÃÃÃð°°´´´µµµ°°°ªªª©©©ªªªªªª°°°°°°¯¯¯¯¯¯¸¸¸Â¿¿¿´´´ªªª¦¦¦¬¬¬¾¾¾ÇÇÇÆÆÆÆÆÆÌÌÌÔÔÔ¿¿¿¿¿¿ÉÉÉÉÉÉÍÍÍÙÙÙÝÝÝ×××ÔÔÔÑÑÑÑÑÑÔÔÔÔÔÔÑÑÑÍÍÍÍÍÍÊÊÊÊÊÊÇÇÇÅÅÅÇÇÇÉÉÉÅÅÅÊÊÊÉÉÉÃÃúºº³³³³³³¼¼¼ÆÆÆÇÇÇÐÐÐÒÒÒÉÉÉ»»»µµµººº¿¿¿µµµ´´´»»»ÆÆÆÇÇÇÀÀÀ¾¾¾ÃÃÿ¿¿ÆÆÆÌÌÌÊÊÊÆÆÆÂÂÂÅÅÅÉÉÉ¿¿¿ÆÆÆÔÔÔÝÝÝßßßâââæææäääÝÝÝæææíííëëëèèèèèèçççää䨨ØÙÙÙ»»»···ÀÀÀ¼¼¼ÅÅÅÆÆÆÆÆÆÉÉÉÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÎÎÎÑÑÑÔÔÔÕÕÕ×××ØØØÛÛÛÜÜÜÛÛÛÛÛÛØØØ×××ÔÔÔÑÑÑÎÎÎÍÍÍÍÍÍÊÊÊÉÉÉÍÍÍÒÒÒ××××××ÕÕÕØØØØØØÙÙÙÛÛÛÛÛÛÙÙÙ×××ÕÕÕÌÌÌÍÍÍÇÇÇëëëñññóóóøøøòòòñññöööâââçççâââãããßßßàààêêêäääÝÝÝÙÙÙÙÙÙÛÛÛÜÜÜÜÜÜÎÎÎÂÂÂÀÀÀÑÑÑÛÛÛ×××ÑÑÑÑÑÑÑÑÑÑÑÑØØØÕÕÕÎÎÎÛÛÛàààÎÎÎÊÊÊÌÌÌÌÌÌÉÉÉ»»»···´´´ººº¸¸¸ÂÂÂÍÍÍÎÎÎÐÐÐÍÍÍÂÂÂÙÙÙ×××ÐÐÐÉÉÉÆÆÆÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼ºººµµµ´´´···µµµ±±±¯¯¯±±±±±±±±±±±±±±±´´´µµµ¸¸¸ººº»»»ººº¸¸¸ººº»»»ÀÀÀÅÅÅÉÉÉÍÍÍÐÐÐÌÌÌÅÅÅÂÂÂÀÀÀÀÀÀÅÅźºº±±±¯¯¯´´´ººººººµµµ³³³ÀÀÀÆÆÆÆÆÆ¾¾¾¸¸¸······µµµ³³³¸¸¸···±±±´´´¾¾¾¾¾¾···¬¬¬¦¦¦©©©···ÃÃÃÇÇÇÇÇÇÉÉÉÎÎξ¾¾ÀÀÀÊÊÊÉÉÉÑÑÑÜÜÜÛÛÛÙÙÙÕÕÕÐÐÐÎÎÎÎÎÎÍÍÍÉÉÉÃÃÃÀÀÀÀÀÀ¼¼¼»»»¼¼¼¼¼¼¿¿¿ÇÇÇÊÊÊÊÊÊÊÊÊÆÆÆÃÃÃÅÅÅÌÌÌÑÑÑÎÎÎÔÔÔØØØÕÕÕÇÇǾ¾¾¿¿¿ÆÆÆ»»»³³³´´´ÀÀÀÊÊÊÇÇÇÆÆÆÊÊÊÃÃÃÉÉÉÎÎÎÎÎÎÇÇÇÀÀÀ¾¾¾¼¼¼ÅÅÅÇÇÇÆÆÆÉÉÉÐÐÐ×××ÝÝÝæææÛÛÛàààæææçççêêêíííêêêäääãããââ⺺º³³³¾¾¾¸¸¸¿¿¿¿¿¿ÂÂÂÅÅÅÇÇÇÊÊÊÊÊÊÌÌÌÍÍÍÎÎÎÍÍÍÐÐÐÒÒÒÕÕÕÕÕÕ×××ÙÙÙÜÜÜÛÛÛÛÛÛØØØÕÕÕÑÑÑÎÎÎÍÍÍÌÌÌÉÉÉÇÇÇÇÇÇÊÊÊÎÎÎÒÒÒÕÕÕÕÕÕÛÛÛÛÛÛÙÙÙØØØ×××ÕÕÕÕÕÕÕÕÕÐÐÐÎÎÎÆÆÆïïïóóóóóóüüüöööîîîõõõãããêêêççççççßßßÝÝÝãããàààßßßÝÝÝÜÜÜÛÛÛ×××ÔÔÔÝÝÝÇÇÇÀÀÀÐÐÐÛÛÛÕÕÕÐÐÐÔÔÔÎÎÎÑÑÑÛÛÛÕÕÕÍÍÍÜÜÜâââÎÎÎÉÉÉÊÊÊÌÌÌÉÉÉÃÃü¼¼¸¸¸µµµ°°°···ÆÆÆÐÐÐÐÐÐÔÔÔÎÎξ¾¾ÔÔÔÙÙÙØØØÎÎÎÆÆÆÆÆÆÇÇÇÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾···µµµ¸¸¸¸¸¸´´´±±±´´´±±±±±±±±±±±±³³³µµµ¸¸¸ººº»»»ººº¸¸¸ººº¿¿¿ÆÆÆÍÍÍÑÑÑÉÉÉÆÆÆ»»»»»»ÃÃû»»±±±µµµÇÇÇ¿¿¿ºººººººººººº¿¿¿ÆÆÆ¿¿¿ÆÆÆÉÉÉÅÅÅÂÂÂÅÅÅÅÅÅÃÃÿ¿¿ÇÇÇÇÇÇ»»»µµµººº¼¼¼ººº¸¸¸ªªª¢¢¢©©©¸¸¸ÃÃÃÆÆÆÆÆÆÎÎÎÂÂÂÆÆÆÌÌÌÆÆÆÎÎÎÕÕÕÌÌÌÇÇÇÃÃÿ¿¿¿¿¿Â¾¾¾ººº¿¿¿¿¿¿ººº¸¸¸¾¾¾ººº¾¾¾ÎÎÎÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÙÙÙÕÕÕÕÕÕ×××ÑÑÑÃÃúºº¸¸¸Âµµµ¯¯¯µµµÀÀÀÃÃÃÂÂÂÀÀÀ¾¾¾ÅÅÅÍÍÍÐÐÐÌÌÌÇÇÇÃÃÃÃÃÃÀÀÀÅÅÅÂÂÂÌÌÌàààæææßßßàààÜÜÜàààâââãããèèèíííêêêäääÝÝÝÝÝݵµµ±±±¿¿¿···ºººµµµ¾¾¾ÀÀÀÅÅÅÆÆÆÇÇÇÉÉÉÊÊÊÍÍÍÍÍÍÐÐÐÒÒÒÔÔÔÕÕÕ×××ÙÙÙÜÜÜÜÜÜÛÛÛ×××ÔÔÔÐÐÐÍÍÍÌÌÌÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÐÐÐÕÕÕÛÛÛÝÝÝÜÜÜÙÙÙÕÕÕÔÔÔÔÔÔÕÕÕ×××ÕÕÕÍÍÍÀÀÀîîîñññîîîüüüüüüöööúúúúúúòòòçççâââãããèèèãããàààÝÝÝÛÛÛÙÙÙØØØÙÙÙÙÙÙÕÕÕÆÆÆÂÂÂÐÐÐÛÛÛ×××ÑÑÑÒÒÒÒÒÒÎÎÎ×××ÒÒÒØØØàààÎÎÎÅÅÅÆÆÆÇÇÇÇÇÇÆÆÆÃÃþ¾¾ºººµµµ±±±···¾¾¾³³³ºººÎÎÎÍÍÍÇÇǸ¸¸×××àààÔÔÔÍÍÍÇÇÇÃÃÃÆÆÆÀÀÀÂÂÂÃÃÿ¿¿¾¾¾¾¾¾¿¿¿ººººººººº¸¸¸···µµµµµµµµµ±±±···ºººµµµ´´´······´´´´´´···ºººÀÀÀÆÆÆÉÉÉÉÉÉÇÇÇ¿¿¿¸¸¸¼¼¼Â¼¼¼ºººÀÀÀÅÅÅÆÆÆÅÅÅÃÃÃÃÃÃÆÆÆÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÂÂÂÂÂÂÃÃÃÅÅÅ´´´¬¬¬¼¼¼¿¿¿»»»´´´ªªª¦¦¦©©©´´´¿¿¿ÇÇÇÉÉÉÍÍÍÂÂÂÃÃÃÊÊÊÆÆÆÊÊÊÊÊÊÉÉÉÆÆÆÃÃÿ¿¿¼¼¼¼¼¼¼¼¼¾¾¾Â¾¾¾»»»»»»»»»»»»»»»¼¼¼ÍÍÍÐÐÐÎÎÎÉÉÉÂÂÂÂÂÂÊÊÊÒÒÒÙÙÙ×××ÛÛÛÔÔÔÌÌÌÔÔÔÊÊʨ¨¨ÀÀÀ¼¼¼±±±­­­µµµ¿¿¿Â¾¾¾¾¾¾ÅÅÅÍÍÍÑÑÑÎÎÎÌÌÌÍÍÍÀÀÀ¾¾¾ÊÊÊÙÙÙàààçççæææÛÛÛØØØßßßßßßàààëëëïïïèèèäääâââãããÕÕÕ»»»°°°µµµ»»»···¸¸¸¼¼¼¼¼¼ÇÇÇÆÆÆ¼¼¼ÅÅÅÇÇÇÌÌÌÒÒÒÕÕÕÒÒÒÒÒÒ×××ÕÕÕÑÑÑÙÙÙÙÙÙØØØ×××ÔÔÔÐÐÐÍÍÍÊÊÊÊÊÊÊÊÊÊÊÊÌÌÌÎÎÎÑÑÑÔÔÔÕÕÕ×××ÝÝÝÙÙÙÒÒÒÔÔÔÑÑÑÐÐÐ×××ØØØÅÅÅÆÆÆëëëõõõñññÿÿÿõõõõõõùùùúúúõõõëëëãããàààâââààààààÝÝÝÜÜÜÛÛÛÛÛÛÙÙÙÙÙÙ×××ÎÎÎÍÍÍØØØàààÜÜÜ×××ÔÔÔÑÑÑÐÐÐÒÒÒÑÑÑ×××ÙÙÙÐÐÐÉÉÉÆÆÆÇÇÇÉÉÉÉÉÉÆÆÆ¿¿¿ºººµµµ¬¬¬¯¯¯···³³³´´´ÂÂÂÉÉÉÔÔÔÆÆÆ×××ÝÝÝÕÕÕÎÎÎÊÊÊÆÆÆÆÆÆÇÇÇÉÉÉÇÇÇÆÆÆÃÃÿ¿¿¾¾¾¼¼¼ÃÃÃÀÀÀ»»»···´´´µµµ¸¸¸ºººººº¼¼¼ººº´´´³³³¸¸¸¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÆÆÆÌÌÌÍÍÍÌÌÌÉÉɺºººººÀÀÀÀÀÀººº¾¾¾ÅÅÅÃÃþ¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀ¾¾¾¼¼¼ÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿ÂÂÂÀÀÀÃÃø¸¸¯¯¯¼¼¼Â¼¼¼ººº´´´¯¯¯¬¬¬°°°ºººÂÂÂÉÉÉÍÍÍÂÂÂÃÃÃÊÊÊÆÆÆÉÉÉÊÊÊÇÇÇÆÆÆÂ¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼ººººººººº¼¼¼ÅÅÅÌÌÌÐÐÐÎÎÎÀÀÀÃÃÃÆÆÆÃÃÿ¿¿ÀÀÀÆÆÆÌÌÌÜÜÜÕÕÕ×××ÔÔÔÎÎÎÕÕÕÎÎΰ°°³³³¼¼¼ÀÀÀ¸¸¸­­­¬¬¬´´´¼¼¼ºººººº¿¿¿ÆÆÆÊÊÊÊÊÊÍÍÍÒÒÒÉÉÉÂÂÂÆÆÆÍÍÍÑÑÑÛÛÛâââÝÝÝßßßãããÝÝÝÜÜÜçççîîîêêêèèèÜÜÜßßßÜÜÜÎÎμ¼¼³³³³³³···ºººÀÀÀ¼¼¼¾¾¾»»»ºººÅÅÅÆÆÆÆÆÆÆÆÆÊÊÊÑÑÑ×××ÙÙÙßßßâââÜÜÜÛÛÛØØØÕÕÕÒÒÒÎÎÎÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÕÕÕÙÙÙÕÕÕÔÔÔÕÕÕÎÎÎÇÇÇÌÌÌÀÀÀ¾¾¾ÉÉÉæææîîîñññÿÿÿïïïóóóöööùùùöööïïïæææßßßÜÜÜßßßÝÝÝÜÜÜÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÑÑÑÒÒÒÕÕÕÙÙÙÝÝÝÛÛÛÕÕÕÐÐÐÑÑÑÐÐÐÍÍÍÒÒÒÒÒÒÎÎÎÎÎÎÌÌÌÅÅÅÇÇÇÊÊÊÊÊÊÇÇÇÀÀÀºººµµµ±±±³³³»»»···µµµ¿¿¿ÃÃÃÎÎÎÃÃÃÍÍÍÙÙÙÜÜÜÒÒÒÌÌÌÍÍÍÌÌÌÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀÀÀÀ¿¿¿¼¼¼»»»»»»¾¾¾ÃÃÃÇÇÇÊÊÊÉÉÉÉÉÉÆÆÆÀÀÀ¿¿¿ÃÃÃÉÉÉÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÊÊÊÅÅÅÀÀÀ¼¼¼¼¼¼¼¼¼¸¸¸¸¸¸ÅÅÅÌÌÌÂÂÂÀÀÀ¾¾¾»»»»»»»»»¼¼¼»»»»»»¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÀÀÀÇÇÇÀÀÀ¾¾¾³³³ºººÀÀÀ¾¾¾¿¿¿¿¿¿¸¸¸±±±¯¯¯´´´ºººÉÉÉÎÎÎÂÂÂÅÅÅÊÊÊÆÆÆÉÉÉÉÉÉÇÇÇÅÅÅ¿¿¿¼¼¼»»»»»»»»»ººº¼¼¼¼¼¼¾¾¾ÇÇÇÒÒÒÕÕÕÎÎθ¸¸»»»¿¿¿ÀÀÀÂÂÂÂÂÂÅÅÅÇÇÇ×××ÒÒÒ×××ØØØÑÑÑÒÒÒÑÑÑÀÀÀ´´´µµµººº»»»¸¸¸±±±¯¯¯¯¯¯¼¼¼»»»¼¼¼¿¿¿ÀÀÀ¿¿¿ÆÆÆÍÍÍÉÉÉÃÃÃÂÂÂÂÂÂÅÅÅÎÎÎÜÜÜßßßâââäääÝÝÝÜÜÜçççîîîêêêçççâââßßßââââââÑÑѸ¸¸­­­°°°ºººÆÆÆÂ»»»µµµ¸¸¸ÅÅÅÂÂÂÊÊÊÆÆÆÇÇÇÐÐÐÔÔÔÐÐÐÑÑÑØØØÜÜÜÛÛÛ×××ÒÒÒÐÐÐÌÌÌÊÊÊÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÐÐÐÔÔÔÒÒÒÎÎÎÐÐÐÐÐÐÉÉÉÇÇÇÎÎÎÆÆÆÎÎÎÜÜÜêêêëëëöööÿÿÿñññóóóõõõööööööòòòëëëãããÝÝÝÝÝÝÜÜÜÙÙÙØØØØØØØØØÙÙÙÛÛÛÎÎÎ×××ÜÜÜÛÛÛÙÙÙÙÙÙÕÕÕÎÎÎÐÐÐÒÒÒÌÌÌÔÔÔÑÑÑÅÅÅÊÊÊÉÉÉÆÆÆÇÇÇÉÉÉÇÇÇÅÅÅÀÀÀ»»»¸¸¸¸¸¸¼¼¼Âººº¾¾¾ÍÍÍÇÇÇ»»»ÂÂÂ×××ããã×××ÌÌÌÍÍÍÌÌÌÎÎÎÍÍÍÌÌÌÍÍÍÎÎÎÑÑÑÒÒÒÔÔÔÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÆÆÆÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÆÆÆÃÃÿ¿¿¼¼¼ºººÀÀÀººº´´´³³³¸¸¸ÉÉÉÍÍÍÀÀÀ¼¼¼»»»»»»¼¼¼¾¾¾¼¼¼ºººµµµ¿¿¿¾¾¾¼¼¼»»»¾¾¾ÀÀÀÅÅÅÇÇÇÅÅÅÎÎÎÅÅÅÃÃô´´µµµ¼¼¼ÀÀÀÂÂÂÀÀÀ¾¾¾¸¸¸³³³±±±°°°ÉÉÉÎÎÎÃÃÃÅÅÅÌÌÌÇÇÇÉÉÉÉÉÉÆÆÆÅÅÅ¿¿¿¼¼¼»»»»»»»»»»»»¿¿¿¼¼¼»»»ÃÃÃÎÎÎÍÍÍ»»»¾¾¾ÀÀÀÃÃÃÆÆÆÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎØØØÜÜÜÒÒÒÐÐÐÒÒÒÐÐÐÀÀÀµµµ°°°¸¸¸¿¿¿»»»±±±­­­´´´µµµººº¼¼¼¼¼¼»»»¿¿¿ÇÇÇ¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÊÊÊ×××ÝÝÝßßßãããààààààëëëîîîçççãããçççßßßÝÝÝæææàààÍÍͼ¼¼¸¸¸ÛÛÛäääàààØØØÉÉɼ¼¼¾¾¾···¾¾¾¼¼¼ÀÀÀÉÉÉÍÍÍÌÌÌÎÎÎÒÒÒ×××ÕÕÕÒÒÒÎÎÎÌÌÌÉÉÉÉÉÉÉÉÉÇÇÇÊÊÊÎÎÎÑÑÑÒÒÒÒÒÒÒÒÒÑÑÑÔÔÔÎÎÎÊÊÊÉÉÉÆÆÆÆÆÆÑÑÑãããäääèèèîîîîîîíííöööÿÿÿñññóóóóóóóóóóóóòòòîîîèèèäääÝÝÝÛÛÛ×××ÔÔÔÒÒÒÔÔÔ×××ÙÙÙÔÔÔßßßäääàààÜÜÜÜÜÜÙÙÙÔÔÔÐÐÐÒÒÒÍÍÍÔÔÔÎÎο¿¿ÅÅÅÃÃÃÇÇÇÇÇÇÆÆÆÃÃÃÀÀÀ¾¾¾¼¼¼»»»ººº¼¼¼Â¼¼¼ÀÀÀÐÐÐÌÌÌÊÊÊÆÆÆÂÂÂÐÐÐßßßÛÛÛÔÔÔÑÑÑÍÍÍÐÐÐÒÒÒÕÕÕØØØ×××ÔÔÔÐÐÐÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÅÅž¾¾´´´¬¬¬ªªªªªª¬¬¬¬¬¬©©©¨¨¨¨¨¨ªªª©©©¨¨¨¦¦¦¨¨¨¬¬¬¯¯¯±±±±±±ººº´´´···¼¼¼¾¾¾ÅÅÅÇÇÇ¿¿¿ÂÂÂÉÉÉÎÎÎÐÐÐÌÌÌÃÃü¼¼¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾ÆÆÆÐÐÐÆÆÆÆÆÆÅÅÅ···¸¸¸ÀÀÀÅÅÅÀÀÀ¾¾¾¿¿¿ÀÀÀ¼¼¼³³³ªªªÊÊÊÐÐÐÅÅÅÇÇÇÍÍÍÇÇÇÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÀÀÀ¾¾¾¼¼¼»»»»»»µµµ»»»»»»ºººÂÂÂÎÎÎÌÌÌÀÀÀÃÃÃÂÂÂÃÃÃÅÅÅÇÇÇÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÐÐÐ×××ÕÕÕÔÔÔÔÔÔÑÑÑÇÇǸ¸¸¯¯¯±±±···¸¸¸······¢¢¢¨¨¨³³³¼¼¼¿¿¿¾¾¾ÀÀÀÇÇǼ¼¼ÀÀÀÂÂÂÂÂÂÂÂÂÇÇÇÐÐÐÙÙÙÝÝÝäääâââàààêêêíííçççäääãããßßßÝÝÝàààâââÝÝÝ×××ÐÐÐØØØÝÝÝÙÙÙÛÛÛÎÎλ»»ººº¸¸¸ÂÂÂÆÆÆÆÆÆÃÃÃÃÃÃÉÉÉÎÎÎÐÐÐÐÐÐÎÎÎÌÌÌÉÉÉÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÊÊÊÎÎÎÒÒÒÕÕÕÕÕÕÔÔÔÒÒÒÒÒÒÐÐÐÍÍÍÉÉÉÀÀÀÆÆÆÜÜÜòòòòòòíííîîîîîîíííòòòñññêêêòòòñññïïïïïïîîîíííëëëêêêàààÜÜÜ×××ÒÒÒÑÑÑÑÑÑÒÒÒÕÕÕÑÑÑÜÜÜãããßßßÙÙÙØØØÕÕÕÒÒÒÎÎÎÒÒÒÑÑÑÑÑÑÊÊÊÀÀÀÀÀÀÂÂÂÇÇÇÅÅÅ¿¿¿¼¼¼»»»»»»¼¼¼¿¿¿¼¼¼ÃÃÿ¿¿¼¼¼¿¿¿ÂÂÂÐÐÐÐÐÐÃÃÃÃÃÃÐÐÐÛÛÛàààßßßÙÙÙÐÐÐÕÕÕÙÙÙÙÙÙÑÑÑÅÅŸ¸¸³³³³³³°°°¯¯¯±±±µµµ···µµµ´´´»»»¸¸¸µµµµµµ³³³±±±´´´ºººµµµ´´´³³³µµµººº¾¾¾ÀÀÀ°°°µµµÅÅÅÊÊÊÂÂÂÀÀÀÅÅÅÅÅÅÌÌÌÌÌÌÌÌÌÎÎÎÐÐÐÐÐÐÍÍÍÊÊÊÒÒÒÔÔÔ×××ØØØÕÕÕÐÐÐÊÊÊÆÆÆÃÃÃÌÌÌÆÆÆÉÉÉÆÆÆ¼¼¼ÅÅÅÌÌÌÉÉɾ¾¾ÀÀÀÅÅÅÃÃø¸¸­­­ÌÌÌÑÑÑÇÇÇÊÊÊÎÎÎÉÉÉÊÊÊÉÉÉÆÆÆÆÆÆÃÃÿ¿¿¾¾¾¼¼¼»»»ººº¾¾¾¿¿¿ÀÀÀÇÇÇÐÐÐÎÎÎÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÌÌÌÃÃÃÃÃÃÌÌÌÕÕÕÙÙÙÔÔÔÌÌÌÎÎμ¼¼ªªª©©©±±±¸¸¸¸¸¸···¤¤¤±±±¾¾¾Â¿¿¿¾¾¾ÀÀÀÀÀÀÆÆÆÅÅÅÀÀÀÀÀÀÂÂÂÉÉÉÔÔÔßßßäääàààÜÜÜâââçççèèèëëëäääêêêèèèàààÜÜÜÝÝÝßßßÝÝÝÛÛÛÜÜÜÙÙÙãããâââÙÙÙâââæææâââäääÝÝÝÌÌÌÀÀÀÂÂÂÇÇÇÇÇÇÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇÊÊÊÎÎÎÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÎÎÎÎÎÎÑÑÑÌÌÌÃÃÃÌÌÌâââïïïîîîçççíííïïïòòòóóóíííëëëïïïïïïíííëëëèèèçççèèèèèèâââßßßÛÛÛ×××ÔÔÔÑÑÑÐÐÐÐÐÐÊÊÊÔÔÔÝÝÝÝÝÝØØØÒÒÒÎÎÎÍÍÍÎÎÎÐÐÐÒÒÒÊÊÊÅÅÅÅÅÅÂÂÂÅÅÅÃÃÿ¿¿¾¾¾»»»ºººººººººÂ¾¾¾ÆÆÆÃÃþ¾¾»»»ºººÆÆÆÐÐÐÊÊÊÃÃÃÆÆÆÒÒÒÙÙÙÛÛÛÝÝÝÛÛÛÝÝÝÝÝÝÕÕÕÉÉɾ¾¾¸¸¸···¾¾¾ººº´´´µµµººº¿¿¿ÀÀÀÀÀÀ»»»¸¸¸···¸¸¸µµµ±±±³³³¸¸¸···µµµ´´´´´´·········µµµµµµ¿¿¿ÊÊÊÉÉÉÂÂÂÇÇÇÍÍÍÇÇÇÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÊÊÊÌÌÌÎÎÎÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÉÉÉÉÉÉÍÍÍÅÅž¾¾ÍÍÍÒÒÒÎÎÎÇÇÇÃÃÃÅÅÅÇÇÇÆÆÆ¿¿¿···ÍÍÍÔÔÔÊÊÊÌÌÌÑÑÑÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼»»»¿¿¿ÀÀÀÅÅÅÉÉÉÎÎÎÑÑÑÎÎÎÉÉÉÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÃÃÿ¿¿ÂÂÂÌÌÌÔÔÔÒÒÒÍÍÍÐÐÐÃÃô´´¬¬¬±±±ºººººº´´´¤¤¤¨¨¨±±±¼¼¼ÀÀÀ¼¼¼ººº»»»¾¾¾ÆÆÆÆÆÆÃÃÃÅÅÅÂÂÂÅÅÅÎÎÎÛÛÛãããâââÛÛÛßßßäääèèèïïïêêêîîîíííãããÜÜÜÛÛÛÛÛÛÛÛÛßßßàààÛÛÛààààààßßßçççççççççíííëëëßßßÎÎÎÇÇÇÉÉÉÍÍÍÉÉÉÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÎÎÎÐÐÐÎÎÎÍÍÍÍÍÍÉÉÉÇÇÇÊÊÊÆÆÆÅÅÅ×××çççèèèëëëêêêóóóïïïïïïòòòëëëïïïîîîíííëëëèèèæææãããääääääãããâââßßßÜÜÜØØØÒÒÒÎÎÎÌÌÌÌÌÌÕÕÕàààäääßßßÕÕÕÐÐÐÎÎÎÎÎÎÍÍÍÒÒÒÅÅÅÀÀÀÉÉÉÅÅÅÉÉÉÀÀÀÀÀÀ¿¿¿¾¾¾»»»ººº······¸¸¸»»»ÆÆÆÅÅÅÇÇÇÍÍÍÀÀÀ»»»ÎÎÎ×××ÑÑÑÇÇÇÆÆÆÃÃÃÅÅÅÐÐÐÛÛÛÙÙÙÑÑÑÅÅŸ¸¸µµµ¾¾¾ÆÆÆÂ¼¼¼······»»»¿¿¿¿¿¿¾¾¾ºººººº¼¼¼Â¿¿¿···´´´···µµµµµµ···ººº»»»»»»¸¸¸µµµÆÆÆÇÇÇÅÅż¼¼¿¿¿ÒÒÒØØØÇÇÇÕÕÕ×××ÙÙÙÜÜÜÜÜÜ×××ÐÐÐÊÊÊÎÎÎÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒ×××ØØØÉÉÉÊÊÊÍÍÍÑÑѼ¼¼ÐÐÐÒÒÒÑÑÑÍÍÍÊÊÊÇÇÇÇÇÇÆÆÆÃÃÿ¿¿ÎÎÎÕÕÕÊÊÊÍÍÍÒÒÒÌÌÌÌÌÌÉÉÉÇÇÇÇÇÇÆÆÆÅÅÅ¿¿¿¾¾¾¼¼¼»»»¼¼¼ÂÂÂÌÌÌÑÑÑÒÒÒÑÑÑÑÑÑÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÃÃÃÅÅÅÆÆÆ¿¿¿ÆÆÆÅÅÅ¿¿¿¿¿¿ÇÇÇÐÐÐÔÔÔÉÉÉÎÎÎÊÊʼ¼¼±±±³³³¸¸¸»»»¤¤¤¥¥¥­­­¸¸¸¿¿¿¿¿¿¿¿¿ÀÀÀ´´´ÀÀÀÅÅÅÆÆÆÊÊÊÆÆÆÃÃÃÊÊÊÒÒÒàààãããàààâââäääæææíííäääããããããããããããâââßßßÜÜÜÜÜÜäääÝÝÝÝÝÝàààãããèèèßßßàààçççñññïïïßßßÌÌÌÆÆÆÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÉÉÉÊÊÊÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÀÀÀ¾¾¾»»»ÃÃÃÝÝÝîîîçççíííñññøøøèèèàààçççäääíííóóóâââêêêæææàààèèèäääàààÝÝÝßßßÛÛÛãããÝÝÝÎÎÎÐÐÐÐÐÐÃÃÃÙÙÙßßßÙÙÙÙÙÙ×××ÎÎÎÊÊÊÊÊÊÔÔÔÔÔÔÆÆÆ¿¿¿ÅÅÅÉÉÉÅÅž¾¾»»»ººº¸¸¸······¸¸¸»»»±±±¸¸¸ÂÂÂÊÊÊÎÎÎÌÌÌÆÆÆÂ¾¾¾ÇÇÇÑÑÑÕÕÕÑÑÑÌÌÌÉÉÉÉÉɸ¸¸µµµµµµººº¾¾¾¿¿¿¿¿¿¿¿¿ººº¸¸¸¸¸¸ººº¾¾¾ÀÀÀ¿¿¿¾¾¾ÀÀÀ¸¸¸¸¸¸¿¿¿¿¿¿···±±±´´´´´´µµµµµµ³³³°°°³³³»»»ÂÂÂÃÃÃÇÇÇÌÌÌÃÃÃÂÂÂÉÉÉÌÌÌÎÎÎ×××ÒÒÒ×××ÛÛÛÑÑÑÎÎÎÕÕÕØØØàààÝÝÝÝÝÝÒÒÒÆÆÆÌÌÌØØØØØØÙÙÙÐÐÐÌÌÌÉÉÉÇÇÇÍÍÍÒÒÒÐÐÐÔÔÔÒÒÒÆÆÆÉÉÉÌÌÌÉÉÉÌÌÌÃÃÃÐÐÐØØØÝÝÝÔÔÔÉÉÉÐÐÐÒÒÒÉÉÉÇÇÇÉÉÉÉÉÉÅÅÅÀÀÀ¾¾¾¾¾¾¿¿¿¾¾¾ÂÂÂÍÍÍ×××ÐÐÐÀÀÀ¼¼¼ÃÃÃÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼¾¾¾¿¿¿ÂÂÂÂÂÂÐÐÐÒÒÒÎÎÎÉÉÉÅÅźºº´´´¼¼¼µµµ´´´©©©´´´Â¿¿¿ÀÀÀÀÀÀ¼¼¼¼¼¼ÐÐÐÃÃÃÂÂÂÍÍÍÀÀÀÆÆÆÍÍÍÔÔÔÛÛÛÝÝÝßßßâââçççíííóóóîîîçççâââßßßßßßààààààßßßßßßßßßÝÝÝÝÝÝßßßãããçççèèèçççíííîîîàààÌÌÌÇÇÇÑÑÑÎÎÎÌÌÌÇÇÇÅÅÅÅÅÅÆÆÆÅÅÅÂÂÂÇÇÇÊÊÊÉÉÉÃÃÃÂÂÂÅÅÅÅÅÅÀÀÀÃÃúººÇÇÇÅÅÅÝÝÝèèèêêêêêêñññëëëäääâââãããçççëëëîîîëëëçççíííëëëçççèèèäääâââÝÝÝßßßØØØÛÛÛØØØÎÎÎÐÐÐÊÊÊÌÌÌÜÜÜâââÝÝÝàààßßßÕÕÕÐÐÐÌÌÌÒÒÒÐÐÐÆÆÆÀÀÀÅÅÅÆÆÆÀÀÀ­­­±±±´´´´´´±±±¯¯¯ªªª¦¦¦±±±···ÀÀÀÉÉÉÎÎÎÎÎÎÌÌÌÉÉÉÃÃÃÃÃÿ¿¿¾¾¾ÀÀÀÆÆÆÌÌÌÃÃÃÉÉÉÉÉÉÅÅÅÃÃÃÆÆÆÃÃü¼¼ÂÂÂÀÀÀÀÀÀÂÂÂÃÃÃÀÀÀ¼¼¼ºººÀÀÀ···´´´ººº»»»···¸¸¸¾¾¾žžžžžž¡¡¡©©©´´´¾¾¾ÀÀÀ¾¾¾ÃÃÃÇÇÇÇÇÇÇÇÇÎÎÎÔÔÔØØØãããÙÙÙÙÙÙÙÙÙÔÔÔÔÔÔÝÝÝâââÜÜÜÛÛÛÝÝÝÛÛÛÒÒÒ×××ÙÙÙÑÑÑÛÛÛØØØÙÙÙØØØÎÎÎÊÊÊÊÊÊÃÃû»»ÂÂÂÂÂÂÌÌÌÐÐÐÍÍÍÐÐÐÊÊÊÅÅÅÎÎÎÝÝÝÝÝÝÐÐÐÐÐÐÒÒÒÉÉÉÉÉÉÉÉÉÉÉÉÆÆÆÂ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÉÉÉÑÑÑÌÌÌÀÀÀ¿¿¿ÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼»»»¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÇÇÇÊÊÊÍÍÍÌÌÌ¿¿¿µµµ¸¸¸»»»¸¸¸ªªª³³³ÂÂÂÀÀÀÂÂÂÀÀÀÅÅÅÀÀÀÐÐÐÆÆÆÃÃÃÊÊʾ¾¾ÅÅÅÃÃÃÑÑÑßßßàààÛÛÛØØØÝÝÝäääÙÙÙÝÝÝäääçççæææâââßßßÝÝÝßßßßßßßßßÝÝÝÝÝÝßßßãããæææîîîëëëíííîîîãããÑÑÑÇÇÇÆÆÆÒÒÒÌÌÌÆÆÆÅÅÅÀÀÀ¾¾¾ÃÃÃÌÌÌÅÅÅÇÇÇÆÆÆÂÂÂÂÂÂÅÅž¾¾ÇÇÇÃÃÃØØØÛÛÛçççãããäääëëëòòòîîîçççããããããäääæææçççãããîîîïïïïïïëëëÝÝÝØØØ×××ÝÝÝãããÛÛÛÛÛÛØØØÔÔÔÕÕÕÌÌÌÌÌÌ×××ÙÙÙ×××ÛÛÛÜÜÜÒÒÒÉÉÉÍÍÍÎÎÎÊÊÊÃÃÃÂÂÂÅÅÅÀÀÀººº···ÀÀÀÉÉÉÉÉÉÆÆÆÃÃø¸¸¬¬¬°°°µµµ¿¿¿ÇÇÇÎÎÎÐÐÐÑÑÑÐÐÐÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÃÃÃÂÂÂÃÃÃÂÂÂÌÌÌÌÌÌÀÀÀ»»»ÀÀÀ¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀ¿¿¿¼¼¼ººº±±±¬¬¬­­­¬¬¬¦¦¦¥¥¥©©©¯¯¯¯¯¯³³³ºººÀÀÀÅÅž¾¾ÉÉÉÌÌÌÎÎÎÒÒÒÑÑÑÐÐÐÕÕÕÛÛÛÝÝÝÕÕÕÛÛÛÜÜÜÜÜÜØØØÜÜÜ×××ÜÜÜÛÛÛÝÝÝßßßÝÝÝßßßÝÝÝÔÔÔÕÕÕÙÙÙäääæææÛÛÛ×××ÙÙÙ×××ÍÍÍÌÌÌÂÂÂÊÊÊÒÒÒÒÒÒÑÑÑÇÇÇÆÆÆÆÆÆÙÙÙâââÔÔÔÒÒÒÕÕÕÊÊÊÊÊÊÊÊÊÊÊÊÇÇÇÃÃÃÀÀÀÀÀÀÀÀÀÅÅÅÂÂÂÃÃÃÉÉÉÆÆÆÀÀÀÂÂÂÉÉÉÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¼¼¼»»»ººººººººº»»»¼¼¼¾¾¾ºººÀÀÀÆÆÆÍÍÍÐÐеµµµµµÀÀÀ¼¼¼ªªª±±±ÀÀÀÂÂÂÅÅÅÃÃÃÉÉÉÂÂÂÍÍÍÇÇÇÆÆÆÇÇǼ¼¼ÅÅÅ¿¿¿ÌÌÌÙÙÙàààßßßÛÛÛÜÜÜàààßßßäääèèèêêêçççãããããããããàààààààààßßßÝÝÝßßßãããçççîîîíííííííííèèèÝÝÝÐÐÐÃÃÃÎÎÎÇÇÇÊÊÊÕÕÕÕÕÕÇÇÇÀÀÀÂÂÂÆÆÆÅÅÅÀÀÀ¾¾¾¿¿¿ÃÃÃÃÃÃÀÀÀ»»»ÂÂÂàààíííñññäääçççõõõîîîêêêæææããããããääääääãããßßßöööïïïëëëæææÌÌÌÂÂÂÃÃÃÐÐÐààààààÝÝÝØØØÕÕÕØØØÎÎÎ×××ÛÛÛÙÙÙÙÙÙÜÜÜÝÝÝÔÔÔÉÉÉÎÎÎÊÊÊÅÅÅÂÂÂÃÃü¼¼µµµ¯¯¯»»»ÃÃõµµ¥¥¥±±±¸¸¸ÂÂÂÊÊÊÐÐÐÒÒÒÒÒÒÒÒÒ××××××ØØØÙÙÙ×××ÐÐÐÇÇÇÀÀÀ¾¾¾ÂÂÂÀÀÀµµµ°°°···ÂÂÂÇÇǼ¼¼¾¾¾ÀÀÀÀÀÀ¾¾¾···°°°¬¬¬µµµ±±±³³³······°°°­­­¯¯¯±±±µµµººº¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÅÅÅÇÇÇÔÔÔÕÕÕÒÒÒÜÜÜââââââÕÕÕØØØÔÔÔØØØÕÕÕÝÝÝ×××ßßßÝÝÝÝÝÝßßßßßßâââãããâââÛÛÛÝÝÝäääâââÑÑÑÌÌÌÑÑÑÒÒÒÛÛÛÒÒÒÀÀÀÃÃÃÊÊÊÎÎÎÕÕÕÐÐÐÔÔÔÆÆÆÒÒÒßßßÕÕÕÔÔÔØØØÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÆÆÆÃÃÃÂÂÂÂÂÂÅÅÅÀÀÀ¿¿¿ÃÃÃÃÃÃÂÂÂÃÃÃÉÉÉÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾»»»ººº¸¸¸······¸¸¸ººº»»»¾¾¾ÃÃÃÆÆÆÌÌÌÎÎεµµµµµÀÀÀ¼¼¼©©©­­­¾¾¾ÂÂÂÇÇÇÆÆÆÆÆÆ¾¾¾ÅÅÅÅÅÅÆÆÆÆÆÆ¿¿¿ÇÇÇÃÃÃÅÅÅÍÍÍÛÛÛäääæææææææææííííííëëëêêêèèèçççççççççãããããããããààààààâââäääèèèëëëîîîîîîííííííëëëßßßÒÒÒÊÊÊÇÇÇÎÎÎâââîîîæææÑÑÑÃÃÃÃÃÿ¿¿ººº···ººº¿¿¿ÀÀÀÀÀÀ³³³ÃÃÃßßßîîîïïïèèèíííøøøäääâââââââââäääçççççççççßßßøøøîîîçççàààÃÃ÷··ººº»»»×××àààÝÝÝÕÕÕÒÒÒÙÙÙÔÔÔÝÝÝÛÛÛÙÙÙØØØØØØ×××ÎÎÎÃÃÃÍÍÍÆÆÆÂ¿¿¿¸¸¸´´´···ÂÂÂÆÆÆÃÃÃÆÆÆÉÉÉÀÀÀ³³³´´´¼¼¼ÇÇÇÐÐÐÒÒÒÒÒÒÒÒÒÑÑÑÕÕÕÔÔÔÒÒÒÔÔÔ×××ÕÕÕÒÒÒÎÎÎÆÆÆÃÃÃÀÀÀ¾¾¾···µµµ¿¿¿ÍÍÍÆÆÆ¿¿¿µµµ­­­¬¬¬°°°¸¸¸¿¿¿¿¿¿¾¾¾¿¿¿ÀÀÀ¿¿¿ººº···¸¸¸»»»ºººººº······¸¸¸¼¼¼¿¿¿¼¼¼ÃÃÃÂÂÂÐÐÐÒÒÒÌÌÌÙÙÙÝÝÝçççÛÛÛÝÝÝÒÒÒØØØÔÔÔàààÙÙÙÝÝÝàààââââââààààààæææîîîââââââæææàààÐÐÐÌÌÌÑÑÑÔÔÔÑÑÑÔÔÔÊÊÊÆÆÆ¿¿¿»»»ÇÇÇÌÌÌ×××ÌÌÌ×××àààÕÕÕÐÐÐÕÕÕÑÑÑÎÎÎÍÍÍÌÌÌÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÃÃÃÀÀÀ¿¿¿ÂÂÂÃÃÃÃÃÃÃÃÃÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼ººº¸¸¸···µµµ···¸¸¸ººº»»»ÀÀÀÆÆÆÉÉÉÍÍÍÐÐÐÃÃ÷·····¾¾¾»»»¨¨¨ªªª»»»ÂÂÂÇÇÇÆÆÆÅÅÅ»»»¾¾¾ÀÀÀÃÃÃÃÃÿ¿¿ÅÅÅÆÆÆÂÂÂÆÆÆÒÒÒÝÝÝâââçççëëëëëëèèèçççêêêîîîïïïêêêäääèèèèèèçççæææääääääèèèëëëëëëòòòóóóïïïîîîñññíííæææíííêêêææææææíííëëëÙÙÙÆÆÆÀÀÀ¿¿¿¾¾¾¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿ÅÅÅ×××ãããêêêèèèëëëíííêêêÝÝÝÝÝÝßßßâââæææèèèèèèèèèàààóóóîîîæææàààÉÉɺºº¾¾¾¸¸¸ÔÔÔßßßÝÝÝÕÕÕÕÕÕâââàààÝÝÝØØØØØØÕÕÕÎÎÎÌÌÌÇÇÇ¿¿¿ÌÌÌÃÃÃÀÀÀÂÂÂÀÀÀººº···¸¸¸¼¼¼ÀÀÀÂÂÂÀÀÀÃÃÃÇÇÇÃÃúºº¸¸¸ÀÀÀÌÌÌÒÒÒÔÔÔÒÒÒÑÑÑÑÑÑÕÕÕÔÔÔÒÒÒÔÔÔ×××ØØØÕÕÕÔÔÔÎÎÎÉÉÉÉÉÉÌÌÌÃÃ÷··µµµ¿¿¿±±±µµµ»»»¿¿¿ÀÀÀÂÂÂÂÂÂÃÃÃÅÅÅ¿¿¿»»»µµµ±±±±±±´´´¾¾¾···³³³···ÅÅÅÐÐÐÕÕÕÕÕÕÍÍÍÕÕÕÐÐÐØØØ×××ÎÎÎÜÜÜÜÜÜãããØØØÜÜÜÊÊÊÎÎÎÉÉÉÙÙÙÒÒÒÙÙÙàààæææççççççãããæææñññÝÝÝÝÝÝãããäääÝÝÝßßßæææäääÐÐÐ×××ÒÒÒÒÒÒÌÌÌÀÀÀ¼¼¼ÊÊÊÎÎÎÜÜÜãããØØØÎÎÎÐÐÐÒÒÒÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÆÆÆÅÅÅÂÂÂÂÂÂÀÀÀÀÀÀÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼»»»»»»······µµµµµµ···¸¸¸»»»¼¼¼¿¿¿ÆÆÆÌÌÌÑÑÑÒÒÒÅÅÅ···¸¸¸»»»¼¼¼ªªª¬¬¬ºººÀÀÀÇÇÇÅÅÅÆÆÆ¿¿¿»»»¼¼¼ÀÀÀ¿¿¿¿¿¿ÃÃÃÂÂÂÅÅÅÌÌÌÍÍÍÎÎÎÙÙÙèèèöööïïïêêêëëëïïïòòòïïïíííîîîîîîíííëëëèèèêêêîîîñññòòòøøøøøøòòòïïïñññòòòïïïíííóóóòòòêêêêêêñññîîîäääæææääääääâââØØØÉÉɼ¼¼¸¸¸ÛÛÛêêêæææêêêèèèñññîîîâââàààßßßßßßâââäääææææææäääâââëëëîîîæææàààÑÑѾ¾¾ÀÀÀ¼¼¼ÎÎÎÑÑÑÑÑÑÎÎÎÑÑÑãããæææãããßßßàààÝÝÝÑÑÑÍÍÍÎÎÎÉÉÉÉÉÉ¿¿¿Â¾¾¾´´´µµµ¾¾¾ÂÂÂÂÂÂÂÂÂÃÃÃÇÇÇÇÇÇÃÃü¼¼¾¾¾ÅÅÅÎÎÎÒÒÒÒÒÒÑÑÑÒÒÒÔÔÔÔÔÔÕÕÕØØØÙÙÙÛÛÛØØØÕÕÕÑÑÑÐÐÐÌÌÌÍÍÍÐÐÐÊÊÊ¿¿¿¸¸¸¸¸¸¿¿¿ÃÃÃÉÉÉÊÊÊÇÇÇÃÃÃÀÀÀ¿¿¿Â¾¾¾»»»»»»¾¾¾ÀÀÀÃÃü¼¼···»»»ÆÆÆÐÐÐÑÑÑÐÐÐÒÒÒàààØØØßßßßßßÛÛÛíííçççêêêÙÙÙÔÔÔ±±±³³³´´´ÕÕÕÛÛÛÛÛÛàààâââæææëëëçççæææïïïäääÜÜÜÜÜÜÝÝÝÛÛÛßßßàààÛÛÛÕÕÕÒÒÒÉÉÉÐÐÐ×××ÔÔÔÑÑÑÅÅÅÀÀÀÊÊÊÒÒÒÙÙÙÝÝÝØØØÐÐÐÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»ººº···µµµµµµµµµ¸¸¸ººº¼¼¼¾¾¾ÆÆÆÌÌÌÎÎÎÐÐÐÍÍÍ¿¿¿´´´¸¸¸»»»ÀÀÀ±±±±±±»»»¿¿¿ÅÅÅÂÂÂÅÅÅÀÀÀºººººº¿¿¿ÅÅÅÅÅž¾¾Â¿¿¿ÂÂÂÇÇÇÆÆÆÃÃÃÎÎÎÝÝÝöööóóóñññïïïïïïòòòõõõøøøóóóóóóòòòïïïîîîïïïòòòõõõùùùøøøöööóóóòòòòòòóóóòòòîîîóóóõõõïïïíííîîîîîîêêêçççèèèíííîîîèèèàààÜÜÜßßßçççñññæææïïïëëëñññíííàààâââààààààâââäääæææäääããããããæææîîîæææßßßÔÔÔ¼¼¼¾¾¾ºººÀÀÀ»»»»»»¾¾¾ÆÆÆÙÙÙÝÝÝßßßÜÜÜßßßÜÜÜÍÍÍÉÉÉÍÍÍÊÊÊÇÇÇÀÀÀÀÀÀ¼¼¼±±±µµµÀÀÀ¿¿¿¼¼¼¼¼¼ÂÂÂÅÅÅ»»»µµµÀÀÀÇÇÇÎÎÎÒÒÒÑÑÑÑÑÑÔÔÔ×××ÍÍÍÍÍÍÐÐÐÑÑÑÔÔÔ××××××ØØØÐÐÐÐÐÐÎÎÎÎÎÎÐÐÐÎÎÎÇÇÇÂÂÂÇÇÇÊÊÊÊÊÊÉÉÉÅÅÅÃÃÃÃÃÃÅÅÅÇÇÇÊÊÊÊÊÊÇÇǾ¾¾»»»ººº¸¸¸ººº¼¼¼ÂÂÂÉÉÉÐÐÐÕÕÕØØØØØØçççÛÛÛÜÜÜÙÙÙÕÕÕæææÜÜÜëëëÜÜÜØØØ±±±°°°°°°×××ÝÝÝââââââÜÜÜàààëëëèèèçççñññòòòãããÛÛÛÙÙÙÛÛÛàààâââÙÙÙâââÛÛÛÇÇÇÆÆÆÉÉÉÉÉÉÎÎÎÉÉÉÂÂÂÅÅÅÀÀÀÊÊÊâââäääÔÔÔÍÍÍÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼»»»ººººººµµµµµµµµµ···¸¸¸»»»¾¾¾ÀÀÀÒÒÒÔÔÔÐÐÐÉÉÉÃÃ÷··±±±¸¸¸¼¼¼ÅÅŸ¸¸µµµ¼¼¼¾¾¾ÃÃÃÀÀÀÀÀÀ¿¿¿¸¸¸¸¸¸ÀÀÀÊÊÊÌÌÌÃÃÃÃÃü¼¼¼¼¼ÆÆÆÉÉÉÇÇÇÌÌÌÕÕÕÙÙÙãããïïïõõõõõõóóóõõõùùùøøøøøøöööóóóñññòòòõõõøøøùùùõõõñññòòòõõõöööóóóòòòöööñññëëëëëëëëëíííííííííèèèææææææäääàààÜÜÜâââëëëîîîóóóæææõõõíííêêêâââÙÙÙâââààààààâââäääææææææäääâââêêêæææèèèßßßÇÇÇÀÀÀ···¾¾¾ÀÀÀÅÅÅÃÃÃÀÀÀ¿¿¿ÂÂÂÆÆÆÝÝÝßßß×××ÑÑÑÒÒÒÍÍÍÉÉÉÐÐп¿¿Â¾¾¾······¼¼¼ÀÀÀ¿¿¿¾¾¾¿¿¿»»»ÆÆÆÅÅÅÍÍÍÀÀÀ»»»¼¼¼ÀÀÀÉÉÉÐÐÐÕÕÕ×××ÕÕÕÔÔÔÐÐÐÑÑÑÔÔÔ×××ØØØØØØ×××ÕÕÕÕÕÕÐÐÐÍÍÍÎÎÎÔÔÔ×××ÒÒÒÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÆÆÆÅÅÅÆÆÆÆÆÆÇÇÇÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÀÀÀ¾¾¾»»»¸¸¸ÅÅÅÕÕÕ××××××ÙÙÙØØØàààäääÝÝÝäää×××ÔÔÔíííÝÝÝçççààà×××ÀÀÀ¬¬¬³³³ÒÒÒçççÜÜÜæææäääãããèèèæææäääíííãããîîîíííßßßÙÙÙÝÝÝßßßÜÜÜØØØÛÛÛÜÜÜÙÙÙÔÔÔÍÍÍÉÉÉÇÇÇÇÇÇÉÉÉÅÅÅÐÐÐÒÒÒêêêãããÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÊÊÊÇÇÇÇÇÇÉÉÉÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ¿¿¿¼¼¼»»»ºººººº¸¸¸¸¸¸ººº¸¸¸¸¸¸µµµµµµ»»»ÅÅÅÍÍÍÌÌÌÌÌÌÍÍÍÊÊÊÀÀÀµµµ³³³µµµ¸¸¸¿¿¿¸¸¸±±±ºººÀÀÀ¾¾¾¼¼¼¼¼¼¼¼¼»»»³³³¯¯¯¿¿¿ÉÉÉ¿¿¿ÀÀÀÃÃÃÆÆÆÆÆÆÇÇÇÇÇÇÊÊÊÌÌÌÕÕÕ×××ÝÝÝêêêöööúúúõõõîîîîîîøøøüüüõõõîîîïïïöööúúúòòòòòòòòòòòòóóóõõõööööööóóóòòòïïïîîîíííííííííîîîãããâââãããæææäääßßßâââçççîîîïïïñññîîîèèèãããßßßßßßààà×××ÛÛÛãããâââãããæææâââíííîîîãããÝÝÝÌÌ̵µµµµµ±±±¾¾¾ÀÀÀÃÃÃÆÆÆÉÉÉÉÉÉÆÆÆÅÅÅÕÕÕÙÙÙÕÕÕÔÔÔØØØÒÒÒÌÌÌÎÎÎÃÃÃÃÃþ¾¾¸¸¸¸¸¸¾¾¾ÀÀÀ¾¾¾ÀÀÀ¿¿¿ÇÇÇÃÃÃÇÇǼ¼¼¸¸¸¾¾¾ÂÂÂÊÊÊÑÑÑ×××ØØØØØØ×××××××××ÕÕÕ××××××ÕÕÕÔÔÔÒÒÒÔÔÔÕÕÕ××××××ÕÕÕÔÔÔÔÔÔÔÔÔÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÊÊÊÉÉÉÆÆÆÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÃÃÃÀÀÀ¿¿¿ÇÇÇÎÎÎÌÌÌÑÑÑÜÜÜààààààäääÝÝÝâââÕÕÕ×××íííÜÜÜîîîèèèãããÒÒÒ¿¿¿ÀÀÀÕÕÕâââàààâââØØØÑÑÑÜÜÜëëëñññïïïññññññïïïíííæææÜÜÜ×××ÕÕÕÕÕÕØØØÛÛÛÛÛÛØØØÒÒÒÌÌÌÉÉÉÑÑÑÇÇÇÂÂÂÑÑÑÌÌÌØØØØØØÛÛÛâââÝÝÝÕÕÕÌÌÌÉÉÉÊÊÊÉÉÉÅÅÅ¿¿¿¿¿¿¼¼¼»»»ºººººº¸¸¸¸¸¸···¸¸¸ººº»»»¼¼¼ÂÂÂÊÊÊÒÒÒÍÍÍÎÎÎÎÎÎÊÊÊ¿¿¿µµµºººÂ¸¸¸³³³¼¼¼Â¿¿¿Â¿¿¿···´´´³³³¸¸¸ÆÆÆÉÉÉ»»»ÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÇÇÇÉÉÉÊÊÊÍÍÍÐÐÐ×××ßßßçççïïïõõõøøøïïïöööøøøóóóïïïñññóóóóóóïïïïïïïïïïïïñññóóóõõõöööóóóòòòïïïíííëëëëëëíííîîîèèèææææææçççæææãããæææëëëöööóóóîîîçççãããààààààâââãããÛÛÛßßßæææãããããããããàààëëëãããÒÒÒÉÉɸ¸¸¬¬¬´´´ººº¿¿¿¿¿¿ÃÃÃÊÊÊÑÑÑÑÑÑÊÊÊÅÅÅÇÇÇÍÍÍÎÎÎÐÐÐ×××ÕÕÕÍÍÍÊÊÊÅÅÅÃÃþ¾¾»»»»»»¿¿¿¾¾¾»»»¿¿¿ÂÂÂÀÀÀÇÇǺºººººÀÀÀÆÆÆÍÍÍÒÒÒ×××ÙÙÙÙÙÙÙÙÙÙÙÙ×××ÕÕÕÔÔÔÕÕÕÕÕÕÔÔÔÑÑÑÕÕÕÕÕÕÕÕÕÔÔÔÑÑÑÑÑÑÔÔÔ×××ÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÆÆÆÉÉÉÊÊÊÉÉÉÆÆÆÂÂÂÀÀÀ¿¿¿ÉÉÉØØØÝÝÝ×××ÙÙÙààààààßßßäääÝÝÝÝÝÝÕÕÕÛÛÛíííÛÛÛêêêçççèèèããã××××××ßßßâââçççÒÒÒ¾¾¾···ÂÂÂØØØæææãããäääçççïïïóóóíííäääßßßÝÝÝÕÕÕÔÔÔÕÕÕØØØÛÛÛØØØÒÒÒÌÌÌÃÃÃÅÅÅÆÆÆÑÑÑÅÅÅÌÌÌÊÊÊÊÊÊÝÝÝàààÜÜÜÑÑÑÌÌÌÌÌÌÊÊÊÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÃÃÿ¿¿¾¾¾¼¼¼»»»ººººººººººººµµµººº¼¼¼¼¼¼¾¾¾ÃÃÃÌÌÌÑÑÑÌÌÌÉÉÉÅÅż¼¼±±±¬¬¬µµµÃÃû»»³³³µµµ¾¾¾¾¾¾»»»¾¾¾¼¼¼³³³±±±¸¸¸ÀÀÀÉÉÉÇÇǾ¾¾ÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÌÌÌÐÐÐÑÑÑÔÔÔÝÝÝíííùùùïïïóóóõõõñññïïïïïïîîîëëëëëëëëëëëëíííîîîñññòòòóóóõõõòòòîîîëëëêêêêêêíííîîîîîîëëëêêêêêêèèèçççêêêîîîóóóïïïêêêæææããããããããããããçççàààãããèèèçççãããâââßßßäääÐÐп¿¿ººº±±±°°°ººº¿¿¿¾¾¾ÀÀÀÆÆÆÍÍÍÑÑÑÐÐÐÊÊÊÅÅž¾¾ÀÀÀÂÂÂÅÅÅÍÍÍÑÑÑÍÍÍÆÆÆÂ¿¿¿¼¼¼¼¼¼¿¿¿ÀÀÀ»»»µµµººº¼¼¼ÂÂÂÇÇǾ¾¾»»»¾¾¾ÆÆÆÊÊÊÐÐÐÕÕÕØØØØØØØØØÙÙÙÔÔÔÑÑÑÐÐÐÑÑÑÔÔÔÕÕÕÔÔÔÑÑÑÐÐÐÐÐÐÑÑÑ×××ÜÜÜÛÛÛÔÔÔÍÍÍÒÒÒÐÐÐÌÌÌÉÉÉÉÉÉÌÌÌÐÐÐÒÒÒÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÆÆÆÂ¿¿¿¾¾¾ÊÊÊÝÝÝãããÝÝÝßßßàààØØØÝÝÝãããÝÝÝÙÙÙÕÕÕÝÝÝëëëÛÛÛæææãããèèèêêêââââââäääàààÜÜÜ¿¿¿µµµÀÀÀÅÅÅÆÆÆÇÇÇÃÃÃÇÇÇØØØêêêîîîèèèëëëîîîçççÙÙÙÔÔÔÐÐÐÑÑÑØØØÛÛÛ×××ÒÒÒÌÌÌÌÌÌÇÇÇÌÌ̾¾¾ÇÇÇÊÊÊÍÍÍÅÅÅÎÎÎ×××ØØØÔÔÔÍÍÍÉÉÉÇÇÇÊÊÊÊÊÊÊÊÊÉÉÉÆÆÆÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼»»»ºººººººººººº¸¸¸¼¼¼¼¼¼ººº»»»ÀÀÀÆÆÆÉÉÉÊÊÊ···¯¯¯¦¦¦¦¦¦±±±¿¿¿¿¿¿´´´°°°ºººÃÃÿ¿¿¸¸¸ºººµµµ±±±µµµ¿¿¿ÅÅÅÅÅÅÃÃÃÅÅÅÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÅÅÅÅÅÅÆÆÆÇÇÇÊÊÊÊÊÊÉÉÉÇÇÇÎÎÎÜÜÜèèèëëëïïïòòòñññíííêêêççççççççççççèèèêêêëëëîîîñññòòòõõõòòòíííêêêèèèêêêíííîîîñññïïïííííííëëëêêêëëëíííæææææææææèèèêêêêêêæææâââçççãããæææêêêèèèäääââââââæææÆÆÆ···µµµ³³³´´´······¼¼¼ÂÂÂÉÉÉÍÍÍÌÌÌÉÉÉÇÇÇÇÇǼ¼¼¼¼¼»»»»»»ÂÂÂÌÌÌÎÎÎÉÉɼ¼¼ººº»»»¿¿¿Â¿¿¿¸¸¸³³³¸¸¸»»»ÃÃÃÆÆÆÃÃø¸¸ººº¾¾¾ÇÇÇÍÍÍÔÔÔ××××××ÕÕÕÕÕÕÕÕÕÎÎÎÍÍÍÍÍÍÐÐÐÑÑÑÒÒÒÑÑÑÎÎÎÊÊÊÑÑÑßßßëëëïïïèèèÛÛÛÐÐÐÑÑÑÐÐÐÎÎÎÎÎÎÑÑÑ×××ÜÜÜàààßßßÙÙÙÐÐÐÆÆÆ¿¿¿¿¿¿ÃÃÃÇÇÇÆÆÆÇÇÇÎÎÎÎÎÎÍÍÍ×××ÜÜÜ×××ÜÜÜàààÜÜÜØØØÕÕÕÝÝÝçççÜÜÜëëëçççêêêëëëäääãããäääÝÝÝÛÛÛÃÃþ¾¾ÇÇÇÇÇÇÆÆÆÉÉÉÇÇÇÂÂÂÉÉÉÙÙÙãããæææíííîîîãããâââØØØÎÎÎÌÌÌÒÒÒØØØÛÛÛÙÙÙÜÜÜÎÎÎÆÆÆ×××ÊÊÊÌÌÌÌÌÌÔÔÔÀÀÀÂÂÂÌÌÌ×××ÙÙÙÒÒÒÊÊÊÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¼¼¼»»»ºººººº»»»»»»¼¼¼¾¾¾¼¼¼¸¸¸»»»ÃÃÃÆÆÆÅÅÅÉÉÉ»»»­­­¨¨¨©©©­­­···ÀÀÀ¿¿¿°°°­­­ºººÂ¾¾¾»»»¾¾¾´´´±±±´´´¿¿¿ÆÆÆÃÃÃÂÂÂÆÆÆÀÀÀÃÃÃÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÉÉÉÐÐÐÔÔÔæææëëëññññññêêêäääãããçççääääääæææçççèèèëëëîîîïïïóóóñññíííêêêèèèêêêíííïïïïïïïïïïïïîîîîîîíííêêêçççàààâââäääèèèëëëèèèäääßßßããããããäääèèèêêêäääãããæææããã¾¾¾´´´······»»»¸¸¸´´´»»»ÂÂÂÉÉÉÌÌÌÉÉÉÆÆÆÆÆÆÉÉÉÃÃÃÀÀÀ¾¾¾ººº¼¼¼ÊÊÊÑÑÑÌÌ̼¼¼»»»¼¼¼ÀÀÀ¼¼¼···³³³¼¼¼¼¼¼ÅÅÅÅÅÅÃÃó³³´´´ºººÅÅÅÌÌÌÔÔÔØØØ×××ÔÔÔÑÑÑÑÑÑÍÍÍÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÍÍÍÍÍÍØØØâââíííñññïïïëëëêêêêêêÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜÛÛÛÛÛÛØØØßßßàààØØØÊÊÊÂÂÂÃÃÃÉÉÉÎÎÎÉÉÉÇÇÇÆÆÆÆÆÆÒÒÒÝÝÝÜÜÜÜÜÜÝÝÝÜÜÜØØØ×××ÜÜÜâââàààêêêæææêêêëëëæææçççêêêæææÂÂÂÃÃÃÉÉÉÎÎÎÑÑÑÕÕÕÒÒÒÊÊÊÉÉɺººÅÅÅßßßêêêîîîíííâââèèèàààÕÕÕÐÐÐÒÒÒ×××ÛÛÛÜÜÜÕÕÕÎÎÎÊÊÊ×××ÍÍÍÑÑÑÊÊÊÆÆÆÑÑÑÇÇÇÃÃÃÍÍÍØØØØØØÐÐÐÆÆÆÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»ººº»»»»»»»»»¿¿¿¿¿¿¼¼¼ºººÀÀÀÌÌÌÊÊÊÃÃúºº¯¯¯¥¥¥¥¥¥ªªª±±±¸¸¸ÀÀÀ¼¼¼¬¬¬¦¦¦°°°´´´µµµ¸¸¸»»»ººº´´´°°°¸¸¸ÅÅÅÅÅÅÀÀÀÃÃÃÂÂÂÃÃÃÆÆÆÆÆÆÅÅÅÅÅÅÇÇÇÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊãããçççëëëîîîêêêããããããçççäääääääääæææèèèêêêííííííñññïïïíííêêêêêêíííïïïñññïïïññññññïïïîîîîîîèèèãããææææææäääããããããâââßßßÝÝÝàààââââââäääçççãããâââèèèÛÛÛ···µµµ»»»¸¸¸¼¼¼»»»¼¼¼ººº¿¿¿ÅÅÅÊÊÊÌÌÌÊÊÊÉÉÉÇÇÇÃÃÃÃÃü¼¼ºººÆÆÆÎÎÎÆÆÆÅÅÅÀÀÀÀÀÀÂÂÂÀÀÀºººµµµµµµ¾¾¾»»»ÅÅÅÃÃÃÃÃñ±±´´´¸¸¸¿¿¿ÇÇÇÑÑÑ×××ÕÕÕÒÒÒÑÑÑÐÐÐÍÍÍÎÎÎÍÍÍÊÊÊÇÇÇÉÉÉÎÎÎÔÔÔæææèèèèèèæææâââãããíííóóóèèèçççæææãããßßßÙÙÙÕÕÕÒÒÒ×××ÝÝÝäääæææßßßÕÕÕÍÍÍÉÉÉÎÎÎÉÉÉÌÌÌÐÐÐÌÌÌÑÑÑÝÝÝâââÜÜÜÛÛÛÛÛÛÙÙÙØØØÙÙÙÝÝÝäääßßßßßßçççëëëæææçççíííëëë¾¾¾ÆÆÆÆÆÆÃÃÃÍÍÍÕÕÕÕÕÕÐÐÐÉÉɺººÇÇÇãããëëëîîîñññçççíííèèèãããÜÜÜØØØØØØØØØÙÙÙØØØÙÙÙÑÑÑÎÎÎÀÀÀÑÑÑÎÎÎÆÆÆÎÎÎÎÎÎÇÇÇÂÂÂÌÌÌÙÙÙØØØÍÍÍÐÐÐÍÍÍÉÉÉÅÅÅÀÀÀÀÀÀÀÀÀÀÀÀ¼¼¼¼¼¼»»»»»»»»»»»»»»»¼¼¼¿¿¿¿¿¿¼¼¼¼¼¼ÆÆÆÎÎÎÇÇǸ¸¸¬¬¬©©©¨¨¨ªªª¬¬¬­­­´´´¼¼¼»»»­­­ªªª±±±±±±³³³···µµµ¼¼¼»»»³³³´´´¾¾¾ÀÀÀ¿¿¿ÅÅÅÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÊÊÊÍÍÍÊÊÊÌÌÌÌÌÌÊÊÊÇÇÇÆÆÆÇÇÇÉÉÉäääââââââèèèëëëèèèääääääææææææææææææçççêêêëëëëëëîîîííííííëëëíííïïïñññóóóòòòóóóòòòîîîîîîïïïêêêãããçççæææãããßßßÜÜÜÜÜÜÜÜÜßßßßßßâââààààààäääàààßßßèèèÛÛÛ···ººº¼¼¼´´´···¸¸¸¾¾¾»»»¼¼¼ÀÀÀÉÉÉÐÐÐÐÐÐÌÌÌÆÆÆÀÀÀÀÀÀÃÃþ¾¾¸¸¸ÂÂÂÉÉɾ¾¾ÍÍÍÇÇÇÃÃþ¾¾···µµµ¸¸¸ºººµµµÂÂÂÂÂÂÅÅų³³···»»»ºººÃÃÃÐÐÐ×××ÕÕÕÒÒÒÑÑÑÐÐÐÌÌÌÌÌÌÌÌÌÇÇÇÆÆÆÊÊÊÕÕÕÝÝÝâââßßßÝÝÝÜÜÜÝÝÝßßßààààààæææãããàààÜÜÜÙÙÙØØØØØØØØØæææßßßÙÙÙÝÝÝäääæææÜÜÜÑÑÑÌÌÌÆÆÆÌÌÌÎÎÎÆÆÆÉÉÉÙÙÙæææÜÜÜØØØÛÛÛÛÛÛÙÙÙ×××ÛÛÛèèèÜÜÜßßßèèèëëëâââàààãããâââÃÃÃÊÊÊÇÇÇÌÌÌØØØÕÕÕÊÊÊÊÊÊÆÆÆÇÇÇÜÜÜêêêäääêêêòòòèèèîîîîîîíííçççßßßÙÙÙ××××××ÝÝÝßßßÝÝÝâââÐÐÐÔÔÔÎÎÎÌÌ̺ººÌÌÌÍÍ;¾¾ÀÀÀ×××ààà×××ßßßÛÛÛÔÔÔÌÌÌÆÆÆÂ¼¼¼¼¼¼»»»»»»»»»»»»»»»¼¼¼¿¿¿¿¿¿¼¼¼¼¼¼ÅÅÅÌÌÌ¿¿¿ªªª¯¯¯±±±···¸¸¸³³³¯¯¯´´´¾¾¾¿¿¿···¼¼¼ÃÃÃÀÀÀ¾¾¾¼¼¼µµµ¸¸¸¿¿¿»»»´´´···¸¸¸¾¾¾ÊÊÊÅÅÅÅÅÅÅÅÅÃÃÃÃÃÃÆÆÆÌÌÌÐÐÐÎÎÎÑÑÑÑÑÑÌÌÌÅÅÅÀÀÀÅÅÅÊÊÊçççÝÝÝÛÛÛäääîîîîîîçççãããççççççæææççççççèèèêêêëëëííííííííííííîîîñññòòòóóóõõõöööòòòííííííïïïíííæææâââââââââàààÜÜÜÛÛÛÜÜÜßßßßßßâââßßßÝÝÝâââÜÜÜÜÜÜèè謬¬¾¾¾¿¿¿ººº»»»»»»···ººººººÃÃÃÊÊÊÌÌÌÌÌÌÌÌÌÉÉÉÃÃÃÆÆÆÅÅÅÇÇÇÂÂÂÀÀÀ¼¼¼µµµÃÃÃÎÎÎÍÍÍÇÇǾ¾¾ººº»»»¸¸¸³³³³³³µµµÂÂÂÆÆÆ¼¼¼¸¸¸¸¸¸³³³¸¸¸ÂÂÂÎÎÎÔÔÔÒÒÒÎÎÎÍÍÍÌÌÌÇÇÇÐÐÐÍÍÍÀÀÀÀÀÀÐÐÐÝÝÝàààØØØÙÙÙÛÛÛÛÛÛÙÙÙÙÙÙÜÜÜßßßÜÜÜâââæææäääßßßÙÙÙ×××ØØØÜÜÜÝÝÝÜÜÜÙÙÙÙÙÙÝÝÝçççîîîÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÎÎÎÑÑÑÒÒÒÐÐÐÎÎÎÙÙÙÝÝÝÝÝÝÛÛÛÒÒÒØØØâââèèèæææçççãããÝÝÝæææäääÂÂÂÆÆÆÊÊÊÐÐÐÑÑÑÑÑÑÐÐÐÍÍÍÇÇÇ¿¿¿ççççççïïïóóóêêêîîîñññèèèàààÜÜÜÜÜÜÜÜÜÛÛÛ×××ÙÙÙ×××ÝÝÝäääÛÛÛÊÊÊÉÉÉÔÔÔÒÒÒÀÀÀÎÎÎÊÊʺºº¿¿¿ÊÊÊ××××××ØØØÙÙÙÕÕÕÉÉÉ¿¿¿ÅÅÅÐÐÐÐÐÐÀÀÀµµµ···ºººººº»»»¿¿¿ÅÅÅ¿¿¿ÊÊÊÊÊÊÅÅż¼¼©©©ªªª¸¸¸···¸¸¸ººº¾¾¾¾¾¾ºººµµµ¸¸¸¼¼¼ÀÀÀÀÀÀ¼¼¼»»»¾¾¾ÀÀÀªªªÀÀÀ¾¾¾´´´»»»¸¸¸´´´¿¿¿¼¼¼¸¸¸ÀÀÀÎÎÎÑÑÑÉÉÉÉÉÉÑÑÑÊÊÊÐÐÐÑÑÑÊÊÊÃÃÃÅÅÅÆÆÆÅÅÅÇÇÇÆÆÆ××׿ææäääæææëëëêêêèèèççççççæææææææææææææææççççççæææçççëëëñññöööúúúõõõöööøøøöööóóóñññòòòòòòâââäääÝÝÝßßßîîîñññíííïïïïïïîîîëëëêêêíííïïïæææÙÙÙººº···»»»¿¿¿¾¾¾ºººººº»»»¼¼¼ÅÅÅÌÌÌÊÊÊÊÊÊÊÊÊÇÇÇÃÃÃÅÅÅÂÂÂÅÅÅÀÀÀ¿¿¿µµµÂÂÂÂÂÂÆÆÆÆÆÆ¿¿¿ººº···´´´¯¯¯¸¸¸···¿¿¿ÅÅÅÃÃÃÆÆÆÆÆÆ¼¼¼µµµ¿¿¿ÊÊÊÑÑÑÑÑÑÎÎÎÌÌÌÌÌÌÉÉÉÉÉÉÆÆÆÅÅÅÍÍÍÙÙÙÛÛÛÕÕÕÙÙÙÛÛÛÝÝÝÜÜÜÙÙÙÙÙÙÛÛÛÝÝÝàààãããæææãããÝÝÝÙÙÙÙÙÙÜÜÜÙÙÙÙÙÙØØØÔÔÔÒÒÒØØØàààèèèÌÌÌÍÍÍÎÎÎÑÑÑÑÑÑÐÐÐÍÍÍÌÌÌÐÐÐÊÊÊÒÒÒ×××ÙÙÙÙÙÙÐÐÐÔÔÔØØØããããããçççëëëëëëëëëÜÜÜÀÀÀÃÃÃÉÉÉÍÍÍÐÐÐÎÎÎÍÍÍÌÌÌÃÃÃÃÃÃæææçççñññòòòîîîêêêäääàààÜÜÜÛÛÛÜÜÜÝÝÝÝÝÝÛÛÛ×××ØØØÙÙÙÜÜÜÛÛÛØØØÕÕÕÕÕÕÔÔÔÀÀÀÐÐÐÒÒÒ¾¾¾ºººÅÅÅ×××ÔÔÔÕÕÕØØØØØØÒÒÒÎÎÎÐÐÐÒÒÒÊÊÊÇÇÇÃÃþ¾¾¸¸¸¸¸¸¾¾¾ÃÃÃÐÐÐÅÅÅÅÅż¼¼´´´±±±©©©±±±¸¸¸ººº»»»»»»ººº¸¸¸¸¸¸¸¸¸³³³µµµ······µµµµµµººº¼¼¼ªªªººº¼¼¼»»»¿¿¿¼¼¼ºººÀÀÀÐÐÐÅÅž¾¾ÆÆÆÑÑÑÒÒÒÊÊÊÂÂÂÍÍÍÑÑÑÐÐÐÉÉÉÃÃÃÃÃÃÃÃÃÂÂÂÅÅÅÃÃÃÌÌÌ×××ÜÜÜàààçççëëëêêêèèèçççæææääääääääääääææææææçççèèèëëëïïïòòòõõõòòòóóóõõõõõõòòòòòòòòòóóóçççãããÜÜÜÝÝÝçççëëëèèèçççëëëíííêêêèèèêêêëëëãããÙÙÙÌÌ̵µµµµµÂ¿¿¿ººº¾¾¾¾¾¾ÂÂÂÇÇÇÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÅÅÅÆÆÆÂÂÂÃÃÃÀÀÀÃÃÿ¿¿³³³ººº¸¸¸ÂÂÂÇÇÇÃÃû»»µµµ±±±°°°³³³¸¸¸ÂÂÂÅÅÅÂÂÂÉÉÉÎÎÎÊÊÊ´´´¼¼¼ÇÇÇÍÍÍÎÎÎÌÌÌÊÊÊÊÊÊÆÆÆÅÅÅÆÆÆÍÍÍØØØÜÜÜ×××ÐÐÐÙÙÙÜÜÜàààßßßÛÛÛÙÙÙÛÛÛßßßãããääääääâââÜÜÜÛÛÛÝÝÝàààÛÛÛÛÛÛØØØÔÔÔÑÑÑÔÔÔÝÝÝäääÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÊÊÊÑÑÑÔÔÔÙÙÙÛÛÛÑÑÑÔÔÔÙÙÙèèèäääãããèèèëëëÝÝÝ»»»¾¾¾ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÊÊÊÉÉÉÅÅÅÎÎÎèèèêêêòòòòòòõõõæææßßßÝÝÝÝÝÝßßßßßßßßßÝÝÝÝÝÝ×××ÛÛÛÙÙÙÕÕÕÛÛÛäääàààÒÒÒØØØÀÀÀÌÌÌÕÕÕÇÇǼ¼¼¿¿¿ÍÍÍÔÔÔÔÔÔÒÒÒÑÑÑÑÑÑÐÐÐÌÌÌÇÇÇÍÍÍÑÑÑÌÌ̼¼¼···¿¿¿ÇÇÇÊÊÊÎÎÎÃÃü¼¼¯¯¯¨¨¨©©©¬¬¬···µµµ······ººº»»»ººº···´´´³³³´´´´´´µµµ···¸¸¸¼¼¼¾¾¾¸¸¸»»»¾¾¾ÀÀÀ¿¿¿ÂÂÂÆÆÆÆÆÆÇÇÇÆÆÆÆÆÆÊÊÊÒÒÒÒÒÒÎÎÎÇÇÇÊÊÊÊÊÊÇÇÇÆÆÆÉÉÉÊÊÊÉÉÉÅÅÅÃÃÃÃÃÃÍÍÍÙÙÙßßßàààçççêêêèèèçççæææããããããââââââãããäääçççêêêíííîîîïïïïïïòòòóóóóóóóóóïïïîîîíííîîîçççßßßÛÛÛÜÜÜßßßäääçççâââèèèèèèèèèççççççæææàààÛÛÛØØØÀÀÀ···¾¾¾¿¿¿¼¼¼¿¿¿ÂÂÂÆÆÆÉÉÉÊÊÊÉÉÉÆÆÆÆÆÆÆÆÆÆÆÆÌÌÌÅÅÅÅÅÅÀÀÀÃÃü¼¼­­­±±±¼¼¼ÅÅÅÊÊÊÆÆÆ»»»´´´µµµ¸¸¸´´´µµµ¾¾¾ÂÂÂÀÀÀÇÇÇÌÌÌÆÆÆ¸¸¸¿¿¿ÆÆÆÌÌÌÌÌÌÊÊÊÇÇÇÇÇÇÅÅÅÇÇÇÎÎÎ××××××ÑÑÑÑÑÑÕÕÕ×××ÛÛÛßßßßßßÜÜÜÛÛÛÝÝÝàààäääæææäääâââßßßÝÝÝàààããããããâââßßßÙÙÙÕÕÕØØØàààçççÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÕÕÕÕÕÕÒÒÒÐÐÐÙÙÙÙÙÙÛÛÛÝÝÝÕÕÕØØØ×××êêêçççàààçççîîîÝÝݵµµººº¼¼¼ÀÀÀÅÅÅÇÇÇÇÇÇÆÆÆÅÅÅÑÑÑàààñññîîîóóóñññúúúããããããäääææææææâââÝÝÝÜÜÜÛÛÛÛÛÛÝÝÝÛÛÛ×××ÛÛÛäääßßßÑÑÑÙÙÙÃÃÃÃÃÃÑÑÑÑÑÑÉÉÉÃÃÿ¿¿ÑÑÑÑÑÑÐÐÐÌÌÌÌÌÌÌÌÌÉÉÉÅÅÅÍÍÍÒÒÒÍÍÍÂÂÂÂÂÂÍÍÍÌÌÌÀÀÀ¼¼¼¸¸¸´´´­­­©©©ªªª°°°¸¸¸³³³­­­ªªª³³³¾¾¾ÀÀÀ···­­­³³³³³³´´´···ººº¼¼¼¾¾¾¾¾¾ÇÇǺººµµµ···­­­¬¬¬³³³´´´¸¸¸ÃÃÃÍÍÍÌÌÌÇÇÇÌÌÌÕÕÕÝÝÝÔÔÔÑÑÑÍÍÍÇÇÇÅÅÅÂÂÂÀÀÀ¿¿¿ÅÅÅÅÅÅÃÃÃÍÍÍßßßàààÙÙÙßßßêêêèèèæææãããâââàààààààààâââäääçççêêêíííïïïïïïïïïòòòóóóóóóñññëëëæææäääãããâââÛÛÛÝÝÝàààÜÜÜàààçççãããäääççççççæææäääãããàààÝÝÝßßßÔÔÔÀÀÀ···¼¼¼ÀÀÀÂÂÂÆÆÆÇÇÇÇÇÇÉÉÉÇÇÇÅÅÅÃÃÃÅÅÅÆÆÆÉÉÉÃÃþ¾¾¿¿¿»»»¬¬¬³³³ÃÃÃÇÇÇÉÉɸ¸¸³³³¸¸¸ÀÀÀÃÃõµµ´´´¾¾¾ÇÇÇÍÍÍÆÆÆ´´´¾¾¾ÂÂÂÇÇÇÊÊÊÊÊÊÇÇÇÅÅÅÃÃÃÌÌÌÎÎÎÔÔÔ×××ÐÐÐÇÇÇÍÍÍÙÙÙÔÔÔØØØÜÜÜÜÜÜÜÜÜÜÜÜàààããããããäääääääääãããâââââââââççççççäääßßßÛÛÛÛÛÛâââçççÑÑÑÒÒÒÔÔÔÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÔÔÔàààÝÝÝÛÛÛÛÛÛÕÕÕÛÛÛÔÔÔèèèãããÙÙÙÜÜÜäääÙÙÙµµµ···¸¸¸¼¼¼ÀÀÀÂÂÂÃÃÃÃÃÃÂÂÂãããóóóùùùòòòóóóñññÿÿÿãããäääçççèèèçççâââÜÜÜÛÛÛÛÛÛÜÜÜÝÝÝÜÜÜÜÜÜÝÝÝÝÝÝÛÛÛ×××ÒÒÒÇÇÇÅÅÅÍÍÍÐÐÐÎÎÎÉÉɾ¾¾ÃÃÃÊÊÊÑÑÑÒÒÒÐÐÐÍÍÍÍÍÍÍÍÍÇÇÇÑÑÑÔÔÔÎÎÎÎÎÎÎÎÎÀÀÀ¯¯¯±±±³³³±±±°°°¯¯¯¯¯¯´´´µµµ­­­¨¨¨¤¤¤ªªª···¾¾¾ººº³³³¯¯¯°°°±±±´´´···ºººººº¸¸¸»»»¬¬¬­­­´´´±±±···ÃÃÃÅÅÅÀÀÀÂÂÂÉÉÉÎÎÎÐÐÐÌÌÌÌÌÌÐÐÐÕÕÕÑÑÑÌÌÌÇÇÇÅÅÅÀÀÀ¿¿¿¿¿¿ÂÂÂÃÃÃÀÀÀÊÊÊÜÜÜßßßÙÙÙßßßæææäääãããâââàààßßßßßßßßßãããäääçççêêêîîîñññòòòòòòîîîïïïïïïíííèèèãããàààßßßßßßßßßçççèèèÜÜÜÜÜÜääääääãããäääææææææäääâââââââââàààâââÍÍ͸¸¸»»»ÀÀÀÂÂÂÆÆÆÇÇÇÆÆÆÆÆÆÆÆÆÅÅÅÂÂÂÂÂÂÆÆÆÀÀÀ¼¼¼¾¾¾ººº»»»ººº³³³¿¿¿ÆÆÆÅÅž¾¾···´´´»»»ÅÅÅÍÍÍ»»»¸¸¸ÅÅÅÉÉÉÆÆÆ¿¿¿µµµÂÂÂÅÅÅÇÇÇÉÉÉÉÉÉÆÆÆÂÂÂÀÀÀØØØÒÒÒÐÐÐÑÑÑÎÎÎÌÌÌÎÎÎ×××ÒÒÒÔÔÔ×××ØØØÙÙÙÝÝÝàààäääâââãããäääææææææäääãããâââääääääãããßßßÛÛÛÙÙÙÝÝÝâââãããÝÝÝÕÕÕÎÎÎÍÍÍÎÎÎÒÒÒÕÕÕÒÒÒ×××ãããÜÜÜØØØÙÙÙÕÕÕÙÙÙßßßëëëãããÛÛÛÜÜÜàààÙÙÙ¾¾¾´´´µµµººº¼¼¼¿¿¿¿¿¿ÀÀÀ¿¿¿îîîùùùÿÿÿóóóóóóïïïÿÿÿæææàààãããäääãããâââààààààãããâââÝÝÝÝÝÝàààßßßÛÛÛÛÛÛßßßÉÉÉÎÎÎÌÌÌÍÍÍÊÊÊÇÇÇÍÍÍÆÆÆ»»»ÂÂÂÍÍÍÒÒÒÌÌÌÂÂÂÀÀÀÆÆÆÎÎÎÑÑÑÒÒÒÍÍÍÆÆÆ¾¾¾µµµ°°°³³³···³³³³³³³³³±±±´´´¯¯¯¬¬¬ªªªªªª©©©¬¬¬±±±¸¸¸¼¼¼³³³µµµ···¸¸¸¸¸¸ºººººº»»»Â»»»¿¿¿ÆÆÆÂÂÂÅÅÅÌÌÌÉÉÉÂÂÂÂÂÂÇÇÇÑÑÑÔÔÔÎÎÎÇÇÇÅÅÅÍÍÍÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÆÆÆÊÊÊÀÀÀ¾¾¾¼¼¼ÅÅÅÒÒÒÙÙÙÜÜÜãããàààßßßßßßÝÝÝÝÝÝÝÝÝßßßßßßäääæææèèèëëëîîîïïïñññòòòçççèèèëëëëëëèèèäääããããããäääçççíííëëëàààÜÜÜßßßààààààßßßâââääääääããããããæææâââæææÛÛÛÆÆÆ»»»¾¾¾ÂÂÂÃÃÃÅÅÅÃÃÃÃÃÃÆÆÆÅÅÅÀÀÀÂÂÂÆÆÆºººººº¼¼¼µµµµµµ···µµµÉÉÉÇÇÇÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾ÂÂÂÊÊÊÌÌ̼¼¼ÀÀÀÌÌÌÃÃ÷··ºººÀÀÀÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÃÃÃÀÀÀ¿¿¿ÜÜÜÔÔÔÍÍÍÍÍÍÐÐÐÑÑÑÑÑÑÒÒÒÕÕÕÒÒÒÒÒÒÔÔÔ×××ÜÜÜßßßâââââââââäääæææææææææäääãããßßßââââââÝÝÝÙÙÙØØØÙÙÙÝÝÝïïïèèèàààØØØÕÕÕØØØßßßãããÝÝÝÜÜÜâââÙÙÙØØØßßßØØØØØØëëëîîîäääæææííííííæææÑÑѳ³³´´´···ººº¼¼¼¾¾¾¾¾¾¾¾¾ëëëòòòúúúòòòóóóïïïùùùçççââââââãããäääæææèèèîîîñññïïïçççàààßßßßßßÜÜÜÜÜÜßßßÊÊÊÑÑÑÌÌÌÍÍÍÇÇÇ¿¿¿ÌÌÌÐÐо¾¾ÀÀÀÅÅÅ¿¿¿³³³µµµÂÂÂÐÐÐÆÆÆÂÂÂÅÅÅÀÀÀµµµ±±±µµµ´´´»»»µµµ¸¸¸ºººµµµµµµ©©©¬¬¬±±±´´´³³³­­­¬¬¬°°°µµµ»»»¼¼¼¼¼¼ººº···¸¸¸¼¼¼¿¿¿¸¸¸ººº¿¿¿ÀÀÀÀÀÀÆÆÆÉÉÉÆÆÆ¸¸¸ÃÃÃÎÎÎÔÔÔÒÒÒÐÐÐÊÊÊÆÆÆÔÔÔÐÐÐÌÌÌÉÉɼ¼¼¾¾¾ÃÃÃÅÅÅÀÀÀÅÅÅÍÍÍÐÐÐÕÕÕÜÜÜâââÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜÝÝÝßßßàààäääçççêêêíííîîîíííëëëêêêæææèèèííííííëëëèèèçççæææëëëíííèèèææææææâââÝÝÝÝÝÝÜÜÜÙÙÙÛÛÛàààãããâââãããæææããããããâââÒÒÒ»»»ºººÂÂÂÀÀÀÃÃÃÂÂÂÂÂÂÆÆÆÅÅÅ¿¿¿ÀÀÀÆÆÆ»»»»»»¾¾¾´´´±±±±±±µµµÌÌÌÉÉÉÃÃÃÂÂÂÆÆÆÉÉÉÇÇÇÊÊÊÐÐÐÍÍ͸¸¸ºººÇÇÇÀÀÀ±±±···ÃÃþ¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾ØØØÔÔÔÐÐÐÍÍÍÐÐÐÒÒÒÒÒÒÑÑÑ×××ÔÔÔÐÐÐÐÐÐÕÕÕÛÛÛÝÝÝÝÝÝââââââãããääääääæææääääääÝÝÝàààâââßßßÛÛÛØØØÙÙÙÜÜÜèèèëëëïïïòòòñññîîîêêêçççëëëãããàààØØØÜÜÜæææßßßÛÛÛñññêêêÜÜÜâââçççÝÝÝÑÑÑ»»»±±±´´´µµµ¸¸¸»»»¼¼¼¾¾¾¾¾¾äääçççöööïïïòòòïïïöööèèèçççççççççèèèíííòòòøøøüüüÿÿÿòòòäääÜÜÜÜÜÜÝÝÝÝÝÝÛÛÛÒÒÒÑÑÑÅÅÅÍÍÍÊÊʾ¾¾ÉÉÉÑÑÑÎÎξ¾¾µµµººº¸¸¸³³³¾¾¾ÒÒÒÃÃó³³³³³ÇÇÇÎÎο¿¿¯¯¯­­­±±±»»»¸¸¸¿¿¿ÃÃü¼¼¸¸¸¥¥¥¯¯¯´´´»»»¾¾¾ººº±±±©©©¥¥¥»»»»»»¸¸¸³³³¯¯¯°°°···¼¼¼ºººÀÀÀÀÀÀ»»»¼¼¼ÃÃÃÆÆÆÆÆÆºººÉÉÉÒÒÒÑÑÑÑÑÑÕÕÕÍÍÍ¿¿¿ÒÒÒÎÎÎÌÌÌÉÉÉ»»»¾¾¾ÆÆÆÊÊÊÇÇÇÒÒÒÛÛÛÕÕÕÕÕÕÛÛÛÙÙÙ××××××ØØØÙÙÙÛÛÛÝÝÝàààâââäääçççëëëîîîîîîëëëæææâââêêêíííïïïïïïíííêêêçççæææîîîíííàààßßßêêêèèèßßßÝÝÝÙÙÙÕÕÕ×××ÝÝÝâââââââââæææßßßçççßßßßßßÛÛÛ±±±¼¼¼¿¿¿ÀÀÀÅÅÅÅÅÅÂÂÂÀÀÀÃÃÃÃÃÃÀÀÀººº¾¾¾°°°¼¼¼»»»­­­ÂÂÂÇÇÇÆÆÆÊÊÊÎÎÎÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÌÌ̾¾¾»»»ºººÅÅ۰°°°°ºººµµµººº¾¾¾ÂÂÂÂÂÂÀÀÀÂÂÂÂÂÂ×××ÙÙÙÉÉÉÌÌÌÑÑÑÊÊÊÎÎÎÎÎÎÎÎÎÊÊÊÑÑÑÔÔÔÐÐÐÔÔÔÜÜÜÙÙÙßßßàààãããäääääääääãããâââæææâââàààâââßßßØØØÕÕÕ×××ßßßãããææææææãããâââäääèèèêêêäääãããäääãããÝÝÝÝÝÝâââëëëëëëâââêêêÜÜÜÐÐеµµ±±±´´´µµµµµµ»»»¼¼¼ÃÃü¼¼âââæææòòòííííííîîîêêêõõõÿÿÿæææäääæææíííõõõùùùùùùöööóóóñññëëëãããÛÛÛØØØØØØÙÙÙÒÒÒæææÍÍÍÅÅÅÕÕÕÎÎÎÊÊÊÎÎÎÍÍÍÊÊʾ¾¾¾¾¾»»»¸¸¸ÊÊÊÔÔÔÍÍÍÍÍÍÑÑÑÎÎÎÉÉÉÌÌÌÃÃí­­±±±³³³»»»¾¾¾»»»¾¾¾¸¸¸ªªª°°°¾¾¾Âººº···ººº³³³¨¨¨¼¼¼»»»´´´©©©¨¨¨¯¯¯µµµµµµ»»»···ºººÂ¿¿¿µµµµµµ¼¼¼ÂÂÂÍÍÍÑÑÑÐÐÐÑÑÑÕÕÕÍÍÍÀÀÀÎÎÎÍÍÍÃÃÃÊÊÊÉÉɾ¾¾ÃÃÃÂÂÂÉÉÉÑÑÑÙÙÙØØØÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÎÎÎÎÎÎÕÕÕÛÛÛÛÛÛÜÜÜâââääääääçççíííïïïíííçççãããâââæææëëëïïïïïïîîîëëëëëëíííæææßßßÛÛÛØØØØØØâââíííàààÜÜÜÙÙÙÛÛÛàààæææçççæææëëëñññæææäääããã···ººº»»»¿¿¿Â¾¾¾¾¾¾ÀÀÀÀÀÀ¾¾¾¼¼¼¾¾¾°°°ººº¸¸¸¯¯¯ÅÅÅÍÍÍÉÉÉÌÌÌÑÑÑÒÒÒÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÅÅž¾¾ÆÆÆ´´´´´´¼¼¼···ººº¾¾¾ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÊÊÊÒÒÒÉÉÉÉÉÉÎÎÎÌÌÌÑÑÑÑÑÑÉÉÉÉÉÉÐÐÐÒÒÒÎÎÎÒÒÒÛÛÛÛÛÛßßßàààâââãããäääãããâââàààçççäääãããæææäääßßßÝÝÝàààäääææææææäääâââãããèèèîîîæææãããâââããããããâââæææíííêêêëëëæææäääÍÍÍÃÃ÷··µµµ´´´µµµ³³³»»»¾¾¾ÀÀÀºººâââçççñññêêêèèèëëëèèèòòòúúúæææëëëòòòøøøùùùøøøöööõõõõõõòòòëëëãããÜÜÜÙÙÙÜÜÜààà×××âââÊÊÊÅÅÅÔÔÔÐÐÐÌÌÌÊÊÊÅÅÅÍÍÍÍÍÍÐÐÐÆÆÆ¼¼¼ÊÊÊÕÕÕÑÑÑÑÑÑÔÔÔÔÔÔÐÐÐÐÐÐÅÅÅ­­­±±±³³³ººº¼¼¼»»»ÀÀÀ¸¸¸¬¬¬¸¸¸ÃÃÃÀÀÀ»»»µµµ°°°¬¬¬­­­¬¬¬¨¨¨¢¢¢¦¦¦±±±¸¸¸»»»¿¿¿ºººººº¾¾¾»»»³³³µµµ¾¾¾ÆÆÆÐÐÐÔÔÔÑÑÑÒÒÒÕÕÕÎÎÎÂÂÂÍÍÍÍÍÍÉÉÉÌÌÌÌÌÌÆÆÆÂºººÊÊÊ×××ßßßÛÛÛØØØÛÛÛÕÕÕÌÌÌÅÅŵµµ´´´ÊÊÊÜÜÜÝÝÝÛÛÛÜÜÜâââæææèèèçççäääæææïïïøøøóóóïïïëëëèèèëëëîîîñññòòòßßßÙÙÙ××××××ÕÕÕÔÔÔØØØÝÝÝãããßßßÙÙÙÛÛÛàààæææèèèèèèëëëîîîàààÛÛÛßßß···ººº¿¿¿¾¾¾¿¿¿¾¾¾ºººººº¾¾¾¾¾¾»»»¼¼¼¾¾¾±±±¸¸¸µµµ°°°ÉÉÉÔÔÔÌÌÌÐÐÐÔÔÔÕÕÕÔÔÔÒÒÒÒÒÒÒÒÒÑÑÑÌÌÌÉÉÉ¿¿¿ÆÆÆµµµ¸¸¸¾¾¾ººº¼¼¼¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÇÇÇ×××ÑÑÑÍÍÍÎÎÎÍÍÍÑÑÑÐÐÐÎÎÎÐÐÐÕÕÕÕÕÕÑÑÑÒÒÒÙÙÙÛÛÛßßßßßßâââââââââàààßßßßßßãããââââââææææææããããããæææäääçççèèèçççæææçççëëëïïïëëëêêêêêêèèèäääàààâââæææëëëëëëêêêßßß¼¼¼µµµººº»»»ººº»»»´´´»»»ÀÀÀºººµµµßßßæææíííãããâââæææãããíííòòòæææïïïøøøùùùóóóîîîïïïòòòõõõóóóîîîæææÝÝÝÛÛÛßßßäääÜÜÜÝÝÝÍÍÍÉÉÉÑÑÑÑÑÑÍÍÍÇÇǸ¸¸ÅÅÅÊÊÊÑÑÑÉÉɼ¼¼ÃÃÃÅÅÅÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÉÉɵµµ´´´´´´ººº¼¼¼ºººÀÀÀÆÆÆÂ¬¬¬³³³¿¿¿ÆÆÆ¿¿¿³³³¯¯¯³³³³³³°°°ªªª¦¦¦ªªª´´´¸¸¸¸¸¸ÀÀÀ¼¼¼»»»¼¼¼ºººµµµ¼¼¼ÉÉÉÊÊÊÑÑÑÔÔÔÒÒÒÔÔÔÕÕÕÎÎÎÃÃÃÐÐÐÊÊÊÉÉÉÃÃÃÅÅÅÊÊÊÇÇÇÆÆÆÔÔÔÜÜÜÙÙÙÌÌÌÆÆÆÉÉÉÀÀÀ°°°³³³¨¨¨¦¦¦¸¸¸ÎÎÎÙÙÙÜÜÜÜÜÜÛÛÛÝÝÝâââããããããæææèèèèèèõõõïïïëëëëëëïïïññññññïïïãããÝÝÝÙÙÙÙÙÙØØØ××××××ØØØæææàààÛÛÛÛÛÛàààæææêêêêêêäääçççßßßÙÙÙÜÜÜ···¸¸¸ÀÀÀ¿¿¿ÀÀÀ¼¼¼¸¸¸¸¸¸¾¾¾¾¾¾»»»¼¼¼¾¾¾´´´¸¸¸···µµµÌÌÌØØØÐÐÐÒÒÒ×××ØØØ×××ÕÕÕÕÕÕÕÕÕÑÑÑÎÎÎÌÌ̾¾¾Â´´´···¼¼¼¼¼¼¾¾¾¾¾¾¼¼¼»»»¼¼¼¾¾¾ÀÀÀÀÀÀÔÔÔÔÔÔÊÊÊÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÍÍÍÑÑÑÒÒÒÑÑÑÔÔÔÛÛÛßßßßßßßßßààààààßßßßßßÝÝÝÜÜÜÜÜÜÙÙÙÜÜÜàààâââßßßßßßâââÜÜÜâââèèèííííííëëëëëëëëëãããæææêêêëëëèèèæææäääæææïïïëëëîîîÝÝݸ¸¸µµµÂººº¾¾¾ÃÃõµµµµµÝÝÝëëëñññäääãããèèèçççîîîòòòíííòòòõõõòòòíííêêêîîîóóóóóóóóóñññèèèàààÜÜÜßßßãããßßßÜÜÜÕÕÕÒÒÒÐÐÐÐÐÐÐÐÐÌÌÌ»»»¾¾¾ºººÃÃÃÉÉÉ¿¿¿³³³ÌÌÌÑÑÑÔÔÔÔÔÔÒÒÒÔÔÔÎÎÎÅÅŵµµµµµ¼¼¼¿¿¿»»»¿¿¿ÅÅÅ´´´°°°···ÂÂÂÀÀÀ´´´±±±ººº´´´°°°ªªª¬¬¬±±±¸¸¸»»»ººº°°°­­­­­­°°°¯¯¯°°°ºººÆÆÆÉÉÉÍÍÍÑÑÑÑÑÑÒÒÒÔÔÔÎÎÎÆÆÆØØØÎÎÎÎÎÎÃÃü¼¼¿¿¿¼¼¼ÇÇÇÜÜÜØØØÉÉÉ···±±±µµµ°°°¤¤¤­­­´´´³³³¯¯¯···ÌÌÌÙÙÙÛÛÛÝÝÝßßßÜÜÜÛÛÛÝÝÝãããäääãããëëëííííííîîîîîîîîîííííííëëëäääÛÛÛ×××ÔÔÔÒÒÒÑÑÑÑÑÑäääßßßÛÛÛÛÛÛàààæææççççççããããããæææàààÜÜܺºº¸¸¸¿¿¿ÅÅÅÃÃÿ¿¿»»»¼¼¼ÀÀÀÀÀÀ¼¼¼»»»¼¼¼¸¸¸ºººººº»»»ÍÍÍØØØÔÔÔ×××ÙÙÙÙÙÙØØØ××××××ØØØÔÔÔÑÑÑÍÍ;¾¾ÃÃõµµ¸¸¸¾¾¾¾¾¾¿¿¿¾¾¾¼¼¼»»»»»»¾¾¾ÀÀÀÆÆÆØØØÜÜÜÑÑÑÐÐÐÒÒÒÐÐÐÑÑÑÜÜÜßßßßßßÜÜÜÙÙÙØØØÛÛÛßßßßßßßßßßßßÝÝÝÜÜÜÛÛÛÛÛÛÙÙÙØØØ×××ØØØÜÜÜÝÝÝÛÛÛÛÛÛÝÝÝÙÙÙßßßæææëëëííííííëëëëëëäääçççêêêèèèçççæææææææææóóóëëëïïïâââÅÅž¾¾ÉÉÉÅÅÅÃÃÃÃÃþ¾¾ÂÂÂÆÆÆµµµÀÀÀàààæææëëëÝÝÝÝÝÝãããâââçççêêêïïïïïïñññïïïîîîîîîïïïòòòïïïòòòòòòîîîæææßßßÜÜÜÜÜÜßßßÜÜÜßßßÛÛÛÑÑÑÎÎÎÐÐÐÑÑÑÍÍÍÆÆÆ···¼¼¼ÇÇÇÇÇÇÆÆÆ¸¸¸ºººÆÆÆÑÑÑÔÔÔÕÕÕÔÔÔÐÐÐÎÎα±±³³³¼¼¼ÃÃÿ¿¿¾¾¾ÀÀÀ¾¾¾¿¿¿±±±­­­¸¸¸¿¿¿ººº¸¸¸¿¿¿¿¿¿¸¸¸±±±°°°°°°°°°­­­ªªª¯¯¯¯¯¯°°°³³³´´´µµµ¾¾¾ÆÆÆÃÃÃÇÇÇÊÊÊÍÍÍÐÐÐÑÑÑÎÎÎÉÉÉÀÀÀ»»»ÉÉÉÊÊÊÅÅÅÀÀÀ¿¿¿ÑÑÑÔÔÔÉÉÉ»»»µµµµµµ···¸¸¸¸¸¸µµµÀÀÀÀÀÀ±±±­­­»»»ÇÇÇÊÊÊÍÍÍÙÙÙââââââßßßãããçççèèèèèèíííîîîëëëçççæææêêêîîîïïïëëëäääßßßÝÝÝÜÜÜØØØÕÕÕàààÜÜÜÛÛÛÜÜÜàààäääãããâââãããÒÒÒÔÔÔÎÎÎÉÉÉ···ÃÃÃÊÊÊÉÉÉÇÇÇÃÃÿ¿¿ÂÂÂÆÆÆÃÃÿ¿¿¼¼¼¼¼¼»»»»»»¼¼¼ÂÂÂÎÎÎ××××××ÙÙÙÛÛÛÛÛÛÙÙÙØØØÙÙÙÙÙÙÙÙÙÒÒÒÎÎÎÂÂÂÇÇǸ¸¸»»»Â¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼¿¿¿Â»»»ÉÉÉÒÒÒÐÐÐÕÕÕÝÝÝÛÛÛàààßßßâââßßßÜÜÜÝÝÝÛÛÛÙÙÙÝÝÝßßßÝÝÝÝÝÝÜÜÜÙÙÙØØØØØØ×××ÙÙÙØØØÙÙÙÝÝÝßßßÜÜÜÜÜÜßßßßßßàààãããæææçççêêêíííîîîîîîîîîêêêääääääçççèèèçççõõõëëëñññçççÕÕÕÅÅÅÊÊÊÆÆÆÀÀÀ¿¿¿ÀÀÀÃÃÃÅÅŸ¸¸ÑÑÑäääâââèèèÜÜÜÝÝÝãããàààäääçççääääääçççêêêíííëëëèèèæææíííïïïòòòòòòíííäääÜÜÜØØØÜÜÜÛÛÛãããßßß×××ÑÑÑÎÎÎÔÔÔÔÔÔÑÑÑÀÀÀ¼¼¼¾¾¾ÀÀÀÉÉÉÅÅÅ­­­¼¼¼ÊÊÊÒÒÒØØØÕÕÕÎÎÎÎÎΰ°°¯¯¯ºººÃÃÃÀÀÀÀÀÀ¾¾¾ÅÅÅ´´´ªªª¯¯¯»»»¿¿¿¿¿¿¿¿¿»»»···´´´¸¸¸»»»»»»ººº»»»¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÅÅÅÇÇÇÊÊÊÂÂÂÃÃÃÆÆÆÊÊÊÍÍÍÐÐÐÎÎÎÊÊÊ¿¿¿¾¾¾ÆÆÆÉÉÉÃÃþ¾¾¿¿¿ÍÍÍÀÀÀººº···¼¼¼¿¿¿¼¼¼¾¾¾ÃÃÃÀÀÀÀÀÀÀÀÀ¼¼¼µµµ³³³³³³´´´±±±ÀÀÀÎÎÎ×××ÝÝÝäääâââÛÛÛÜÜÜäääíííîîîêêêääääääæææêêêíííïïïîîîîîîëëëæææßßßÝÝÝÜÜÜÛÛÛÜÜÜàààãããâââßßßààà»»»ºººººº»»»ºººÐÐÐÐÐÐÌÌÌÊÊÊÇÇÇÃÃÃÆÆÆÉÉÉÆÆÆ¿¿¿¿¿¿¾¾¾»»»ººº¾¾¾ÇÇÇÐÐÐ×××ÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛÙÙÙÙÙÙÛÛÛÜÜÜÐÐÐÉÉÉÂÂÂÊÊʸ¸¸ºººÃÃþ¾¾¿¿¿ÀÀÀ¿¿¿¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÌÌÌÅÅÅÇÇÇÇÇǺºº¿¿¿¾¾¾ÃÃÃÃÃÃÇÇÇÔÔÔØØØÙÙÙàààßßßÝÝÝÜÜÜÙÙÙØØØ×××ÕÕÕÕÕÕÛÛÛÙÙÙÛÛÛàààâââßßßàààãããäääääääääæææçççèèèêêêêêêäääæææäääæææíííõõõöööóóóòòòêêêòòòëëëàààÃÃÃÂÂÂÅÅÅÀÀÀ¼¼¼ÅÅÅÅÅÅ¿¿¿¸¸¸ÛÛÛàààèèèñññçççèèèîîîêêêîîîñññâââãããæææèèèèèèèèèæææäääëëëîîîòòòóóóòòòëëëâââÙÙÙÛÛÛ×××ÝÝÝÜÜÜÜÜÜØØØÊÊÊÑÑÑÐÐÐÔÔÔÉÉɾ¾¾······ÆÆÆÇÇÇ···¼¼¼¾¾¾ÆÆÆÔÔÔÕÕÕÍÍÍÍÍ͸¸¸³³³¸¸¸ÀÀÀ¿¿¿¿¿¿ÀÀÀ¿¿¿¿¿¿¸¸¸°°°­­­···ÃÃÃÃÃü¼¼ÅÅÅÀÀÀÀÀÀÃÃÃÃÃÃÀÀÀ¿¿¿ÀÀÀ¾¾¾¼¼¼¼¼¼¾¾¾ÀÀÀÂÂÂÃÃÃÂÂÂÃÃÃÃÃÃÅÅÅÉÉÉÍÍÍÎÎÎÍÍÍÌÌÌ¿¿¿ÃÃÃÀÀÀÀÀÀÂÂÂÇÇÇÌÌÌÆÆÆ³³³µµµ»»»ÀÀÀ¿¿¿¼¼¼¼¼¼¾¾¾Â¿¿¿¿¿¿ÀÀÀ¾¾¾µµµ°°°­­­°°°³³³±±±µµµÃÃÃÒÒÒÑÑÑÆÆÆÃÃÃÍÍÍÛÛÛæææëëëêêêãããßßßÝÝÝæææëëëëëëêêêèèèãããÝÝÝàààÝÝÝÛÛÛÜÜÜàààããããããàààâââ³³³¸¸¸ÀÀÀÃÃÃÅÅÅÑÑÑÂÂÂÌÌÌÌÌÌÉÉÉÆÆÆÇÇÇÌÌÌÆÆÆ¿¿¿ÃÃþ¾¾»»»¸¸¸¾¾¾ÉÉÉÐÐÐ×××ÛÛÛÜÜÜÝÝÝÜÜÜÛÛÛÙÙÙÙÙÙÛÛÛÙÙÙÊÊÊÃÃþ¾¾ÇÇÇ´´´µµµÀÀÀ¾¾¾¿¿¿ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÃÃÃÇÇÇÅÅÅÍÍÍÐÐÐÂÂÂÉÉÉÃÃÃÇÇÇÃÃÃÇÇÇÔÔÔÙÙÙ×××ÜÜÜßßßÝÝÝÛÛÛÙÙÙ×××ÕÕÕÕÕÕÔÔÔÙÙÙØØØÙÙÙàààâââàààâââææææææçççêêêëëëëëëêêêæææãããâââæææêêêîîîöööüüüöööíííïïïêêêòòòíííäää¿¿¿»»»ÃÃÃÃÃÿ¿¿ÉÉÉÆÆÆººº´´´ÜÜÜØØØßßßèèèâââãããçççãããçççêêêîîîññññññïïïííííííñññõõõêêêíííñññõõõöööñññæææßßßÛÛÛÔÔÔØØØØØØàààÜÜÜÇÇÇÌÌÌÑÑÑØØØÎÎÎÃÃúºº¸¸¸ÆÆÆÇÇÇÉÉÉ´´´¸¸¸ÌÌÌÔÔÔÎÎÎÎÎÎÅÅźººººº¿¿¿¼¼¼¼¼¼¿¿¿¾¾¾¸¸¸»»»···°°°µµµÅÅÅÅÅźºº¿¿¿¾¾¾¿¿¿ÃÃÃÃÃÃÀÀÀ¿¿¿ÃÃúºº¸¸¸¸¸¸»»»¿¿¿ÃÃÃÃÃÃÂÂÂÆÆÆÅÅÅÆÆÆÊÊÊÍÍÍÍÍÍÌÌÌÊÊÊÃÃÃÑÑÑÇÇÇÅÅÅÉÉÉÍÍÍÇÇÇ©©©­­­ºººÂÂÂÀÀÀ¿¿¿ÀÀÀÂÂÂÀÀÀ¿¿¿ÃÃÃÃÃÿ¿¿¼¼¼¼¼¼ºººµµµ­­­´´´µµµ³³³µµµ¿¿¿¾¾¾´´´µµµ¸¸¸ÂÂÂÑÑÑâââêêêèèèããããããêêêîîîêêêççççççæææâââäääàààÜÜÜÜÜÜàààääääääãããÔÔÔÅÅźºº¼¼¼ÅÅÅÉÉÉÉÉÉÉÉÉÍÍÍÊÊÊÇÇÇÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÆÆÆÀÀÀÃÃÃÀÀÀ¾¾¾ÐÐÐÙÙÙàààÝÝÝØØØÑÑÑÐÐÐÔÔÔÙÙÙÜÜÜÕÕÕÐÐп¿¿¿¿¿ÊÊÊ»»»¯¯¯¾¾¾»»»ÀÀÀ¾¾¾¾¾¾ÃÃÃÇÇÇÆÆÆÊÊÊÉÉÉÉÉÉÊÊÊÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÇÇÇÇÇÇÂÂÂÙÙÙØØØÙÙÙØØØÝÝÝàààßßßØØØÔÔÔÕÕÕ×××ÔÔÔÛÛÛÜÜÜÜÜÜÝÝÝàààäääçççèèèëëëèèèâââäääîîîèèèãããêêêñññõõõöööõõõõõõøøøøøøóóóøøøúúúøøøàà྾¾ÅÅÅ¿¿¿Â¿¿¿ÅÅÅÊÊʼ¼¼­­­···ÎÎÎÙÙÙçççÛÛÛÙÙÙÍÍÍÀÀÀØØØÛÛÛèèèççççççèèèææææææëëëóóóñññíííñññïïïêêêñññòòòæææÜÜÜØØØ×××ÕÕÕÛÛÛßßßÕÕÕÌÌÌÌÌÌÕÕÕÑÑÑÐÐп¿¿ÍÍÍÐÐÐÉÉÉÊÊÊÂÂÂÂÂÂÌÌÌÒÒÒÐÐÐÎÎÎÐÐÐÌÌÌÑÑÑÊÊÊ»»»µµµ¼¼¼Â¿¿¿¼¼¼ÃÃúºº¯¯¯ºººÆÆÆÃÃÿ¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀ¾¾¾¸¸¸···¼¼¼¿¿¿¾¾¾¾¾¾ÀÀÀÃÃÃÃÃÃÆÆÆÉÉÉÆÆÆÃÃÃÉÉÉÔÔÔÐÐÐÊÊÊÉÉÉÔÔÔÎÎÎÐÐкºº´´´···¸¸¸¾¾¾ÆÆÆÉÉÉÆÆÆÅÅÅÆÆÆÇÇÇÆÆÆÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»¾¾¾ÂÂÂÃÃÃÃÃÃÂÂÂÀÀÀºººµµµ»»»ÉÉÉÛÛÛæææëëëæææãããäääïïïëëëçççíííàààÛÛÛßßßàààÔÔÔßßßÛÛÛàààãããÃÃÿ¿¿ÀÀÀÇÇÇÊÊÊÉÉÉÇÇÇÉÉÉÐÐÐÍÍÍÌÌÌÌÌÌÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÉÉÉÀÀÀÃÃÃÀÀÀ¿¿¿ÑÑÑÜÜÜâââßßßØØØÒÒÒÐÐÐÑÑÑÕÕÕ×××ÙÙÙÕÕÕÆÆÆÀÀÀÃÃû»»´´´¼¼¼ººº¿¿¿ÀÀÀ¾¾¾¼¼¼ÀÀÀÂÂÂÂÂÂÊÊÊÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÅÅÅÇÇÇÇÇÇÛÛÛÒÒÒ×××ÜÜÜÛÛÛÝÝÝÝÝÝÙÙÙ×××ØØØÙÙÙØØØØØØØØØÛÛÛßßßæææèèèèèèæææäääíííîîîîîîïïïíííîîîúúúäääëëëïïïïïïïïïñññïïïëëëêêêïïïíííÛÛÛÇÇÇÅÅÅÇÇÇÃÃþ¾¾»»»ÀÀÀÇÇÇÀÀÀ³³³´´´¿¿¿···Â¸¸¸¾¾¾»»»³³³ÀÀÀ»»»ÙÙÙÜÜÜàààãããàààÝÝÝäääîîîõõõõõõöööóóóïïïòòòòòòëëëçççäääÝÝÝ××××××ÛÛÛ×××ÑÑÑÍÍÍÒÒÒÑÑÑÑÑÑ»»»ÂÂÂÆÆÆÊÊÊÍÍ;¾¾ºººÌÌÌ×××ÑÑÑÍÍÍÑÑÑÎÎÎÒÒÒÐÐÐÀÀÀ´´´´´´»»»¿¿¿¿¿¿Â¸¸¸³³³¾¾¾ÆÆÆÃÃÃÂÂÂÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀ¾¾¾ººº¸¸¸¼¼¼¾¾¾¾¾¾ÀÀÀÅÅÅ»»»»»»¼¼¼¿¿¿¾¾¾¿¿¿ÅÅÅÌÌÌÐÐÐÆÆÆÊÊÊÒÒÒÐÐÐÑÑѱ±±­­­»»»ººº¾¾¾ÅÅÅÇÇÇÅÅÅÅÅÅÇÇÇÀÀÀÃÃÃÇÇÇÇÇÇÃÃü¼¼»»»¾¾¾¾¾¾ÃÃÃÇÇÇÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÀÀÀ¾¾¾ººº¸¸¸»»»ÆÆÆÒÒÒÜÜÜäääçççæææîîîîîîëëëíííßßßßßßÜÜÜßßßÝÝÝòòòèèèâââÛÛÛ···¾¾¾ÇÇÇÎÎÎÎÎÎÊÊÊÌÌÌÐÐÐÒÒÒÑÑÑÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÎÎÎÌÌÌÌÌÌÂÂÂÃÃÃÀÀÀ¿¿¿ÑÑÑÜÜÜâââÝÝÝØØØÕÕÕÒÒÒÐÐÐÐÐÐÑÑÑÙÙÙÙÙÙÑÑÑÆÆÆ¿¿¿¾¾¾ººº´´´¾¾¾¿¿¿¾¾¾¸¸¸¸¸¸¾¾¾ÃÃÃÆÆÆÉÉÉÊÊÊÌÌÌÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÃÃÃÇÇÇÌÌÌÜÜÜÐÐÐÕÕÕÜÜÜÙÙÙÜÜÜÝÝÝÙÙÙØØØÙÙÙÛÛÛÛÛÛ×××ØØØÜÜÜâââäääèèèëëëïïïòòòöööóóóõõõüüüüüüõõõòòòêêêïïïïïïëëëæææææææææãããêêêêêêÜÜÜÇÇÇ¿¿¿ÃÃÃÆÆÆÉÉÉÇÇÇÅÅÅÅÅÅÇÇÇÆÆÆÀÀÀ¼¼¼¾¾¾µµµ¼¼¼´´´ÀÀÀÆÆÆ¿¿¿Â´´´···¼¼¼ÉÉÉ×××ÝÝÝàààæææíííëëëòòòóóóïïïïïïïïïïïïòòòèèèæææÝÝÝ××××××ÜÜÜâââàààÎÎÎÑÑÑÒÒÒÔÔÔ»»»¿¿¿ÃÃÃÎÎÎÍÍͺºº···ÍÍÍÛÛÛÔÔÔÎÎÎÒÒÒÍÍÍÒÒÒÑÑÑÃÃô´´°°°¸¸¸Â¿¿¿······ÂÂÂÆÆÆÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿»»»¸¸¸¸¸¸»»»¾¾¾ÀÀÀÆÆÆÍÍÍÑÑÑÑÑÑÍÍÍÆÆÆÃÃÃÆÆÆÇÇÇÆÆÆÇÇÇÀÀÀÌÌÌÒÒÒÒÒÒÒÒÒ±±±±±±¾¾¾»»»¾¾¾ÂÂÂÅÅÅÅÅÅÆÆÆÊÊÊÌÌÌÇÇÇÇÇÇÌÌÌÊÊÊÃÃÃÀÀÀÃÃÿ¿¿ÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÃÃÃÂÂÂÉÉÉÉÉÉÇÇÇÃÃþ¾¾ººº¸¸¸¸¸¸ØØØçççããããããæææãããäääÝÝÝòòòèèèæææâââëëëÑÑÑÀÀÀ···¾¾¾ÃÃÃÊÊÊÎÎÎÎÎÎÎÎÎÒÒÒ×××ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÒÒÒÒÒÒÌÌÌÌÌÌÃÃÃÅÅÅ¿¿¿ÎÎÎ×××ÝÝÝØØØÕÕÕÕÕÕÔÔÔÐÐÐÎÎÎÎÎÎÑÑÑ×××ÙÙÙÌÌ̾¾¾ÀÀÀ¾¾¾¯¯¯···ºººººººººººº¾¾¾ÃÃÃÇÇÇÇÇÇÊÊÊÎÎÎÐÐÐÎÎÎÎÎÎÐÐÐÒÒÒÑÑÑÇÇÇÊÊÊÊÊÊÙÙÙÒÒÒ×××ÕÕÕÛÛÛÜÜÜÜÜÜÙÙÙØØØØØØÙÙÙÛÛÛÙÙÙÜÜÜàààããããããæææòòòÿÿÿúúúÿÿÿüüüööööööùùùøøøóóóóóóñññæææÔÔÔÆÆÆÂÂÂÀÀÀ¿¿¿ÜÜÜÜÜÜÉÉɸ¸¸¾¾¾ÅÅÅÉÉÉÐÐÐÑÑÑÎÎÎÉÉÉÆÆÆÆÆÆÆÆÆÆÆÆÃÃÃÅÅÅÇÇÇ¿¿¿ÉÉÉÐÐÐÉÉÉÇÇǺºº···´´´µµµÀÀÀÍÍÍÕÕÕÝÝÝãããîîîùùùøøøññññññëëëèèèñññòòòïïïàààØØØ×××ØØØÜÜÜÕÕÕÍÍÍÑÑÑ×××ÕÕÕÀÀÀÌÌÌÊÊÊÑÑÑÅÅż¼¼¿¿¿ÐÐÐÛÛÛ×××ÑÑÑÒÒÒÊÊÊÑÑÑÍÍͼ¼¼±±±µµµ¿¿¿ÅÅźºº´´´ºººÂÂÂÃÃÃÂÂÂÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿µµµµµµ···ººº¼¼¼ÃÃÃÍÍÍÔÔÔÍÍÍÍÍÍÉÉÉÂÂÂÃÃÃÉÉÉÊÊÊÆÆÆÆÆÆÊÊÊÑÑÑØØØÕÕÕÆÆÆ´´´···¿¿¿»»»»»»ÀÀÀÃÃÃÅÅÅÉÉÉÎÎÎÆÆÆ¸¸¸°°°ºººÅÅÅÇÇÇÆÆÆÆÆÆÎÎÎÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÊÊÊÇÇÇÅÅÅÅÅÅÇÇÇÌÌÌÇÇÇ¿¿¿······àààïïïîîîêêêæææïïïöööîîîçççèèèâââßßß¾¾¾···¿¿¿ÉÉÉÊÊÊÌÌÌÎÎÎÑÑÑÕÕÕ×××ØØØÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÔÔÔÕÕÕÕÕÕÉÉÉÊÊÊÃÃÃÆÆÆÃÃÿ¿¿ÊÊÊÎÎÎÕÕÕÑÑÑÐÐÐÕÕÕ×××ÒÒÒÎÎÎÐÐÐÎÎÎÒÒÒÙÙÙÍÍÍ»»»¿¿¿Â³³³©©©­­­´´´ººº¼¼¼¼¼¼¾¾¾¿¿¿ÅÅÅÉÉÉÍÍÍÎÎÎÐÐÐÑÑÑÔÔÔ×××ÕÕÕÍÍÍÎÎÎÆÆÆÕÕÕØØØÛÛÛÎÎÎØØØØØØÙÙÙÙÙÙØØØØØØÛÛÛÝÝÝâââÝÝÝàààçççëëëïïïøøøÿÿÿüüüúúúõõõïïïòòòøøøöööíííçççæææÜÜÜÎÎÎÆÆÆÅÅÅÆÆÆÆÆÆÀÀÀÅÅż¼¼ºººÇÇÇÐÐÐÐÐÐÔÔÔÐÐÐÐÐÐÍÍÍÇÇÇÅÅÅÆÆÆÆÆÆÆÆÆÊÊÊÌÌÌÅÅÅÉÉÉÉÉÉÆÆÆÆÆÆÀÀÀÃÃû»»´´´±±±´´´¿¿¿ÑÑÑâââæææïïïïïïíííïïïêêêçççïïïóóóñññÝÝÝÙÙÙÛÛÛØØØØØØÉÉÉÍÍÍÒÒÒØØØÑÑÑÂÂÂ×××ÎÎÎÉÉɾ¾¾ÆÆÆÎÎÎÕÕÕÙÙÙÙÙÙÕÕÕÑÑÑÎÎÎÑÑÑÆÆÆ³³³°°°¾¾¾ÅÅÅ¿¿¿Â´´´°°°ºººÀÀÀÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¼¼¼···¸¸¸ºººººº»»»ÂÂÂÊÊÊÐÐÐÉÉÉÊÊÊÅÅÅ¿¿¿ÀÀÀÇÇÇÇÇÇÂÂÂÎÎÎâââÛÛÛâââÕÕÕ°°°³³³µµµ¼¼¼ºººººº¿¿¿ÂÂÂÅÅÅÊÊÊÑÑÑÀÀÀµµµ°°°»»»ÌÌÌÔÔÔÕÕÕÕÕÕÎÎÎÑÑÑÑÑÑÐÐÐÍÍÍÌÌÌÍÍÍÎÎÎÐÐÐÊÊÊÅÅÅÅÅÅÊÊÊÍÍÍÊÊÊÇÇǺººØØØßßßãããêêêçççæææàààçççãããçççßßß×××´´´µµµÆÆÆÍÍÍÎÎÎÐÐÐÑÑÑÕÕÕÙÙÙØØØÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔ×××ØØØÉÉÉÊÊÊÃÃÃÇÇÇÅÅÅ¿¿¿ÇÇÇÊÊÊÐÐÐÉÉÉÊÊÊÔÔÔØØØÔÔÔÐÐÐÒÒÒÐÐÐÒÒÒÕÕÕÌÌ̺ºººººÂ¿¿¿¬¬¬ªªª¬¬¬¯¯¯°°°³³³ºººÀÀÀ¿¿¿ÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÑÑÑÔÔÔÐÐÐÒÒÒÅÅÅÐÐÐ×××ßßßÐÐÐ××××××ØØØÛÛÛÛÛÛÛÛÛßßßãããäääÝÝÝßßßîîîúúúüüüöööõõõöööòòòòòòööööööñññàààÊÊÊÀÀÀÅÅÅÅÅÅÃÃÃÆÆÆÌÌÌÎÎÎÌÌÌÀÀÀ¾¾¾¾¾¾ÉÉÉÐÐÐÒÒÒÕÕÕÐÐÐÔÔÔ×××ÔÔÔÐÐÐÍÍÍÌÌÌÊÊÊÉÉÉÉÉÉÆÆÆÅÅÅÃÃÃÂÂÂÆÆÆÇÇÇ¿¿¿ÀÀÀ¾¾¾´´´³³³ÃÃÃÕÕÕâââæææèèèîîîòòòîîîëëëïïïíííîîîÛÛÛÜÜÜßßßÛÛÛÝÝÝÌÌÌÎÎÎÔÔÔÙÙÙÌÌ̼¼¼ØØØÉÉÉ¿¿¿ÂÂÂÑÑÑÜÜÜÙÙÙØØØÛÛÛÙÙÙÑÑÑÕÕÕÑÑÑÀÀÀ°°°³³³ÀÀÀÃÃû»»Â³³³¯¯¯···¾¾¾ÂÂÂÃÃÿ¿¿ÀÀÀÀÀÀÀÀÀ¿¿¿¿¿¿¼¼¼»»»»»»»»»¾¾¾¼¼¼ººº»»»¿¿¿ÂÂÂÂÂÂÕÕÕÒÒÒÎÎÎÉÉÉÉÉÉÊÊÊÇÇÇÃÃÃÍÍÍçççÛÛÛâââ×××¥¥¥µµµººº»»»¸¸¸ººº¿¿¿ÃÃÃÅÅÅÉÉÉÐÐШ¨¨ªªª°°°´´´¸¸¸¼¼¼¾¾¾¾¾¾ÀÀÀ»»»ºººÃÃÃÒÒÒÙÙÙÕÕÕÍÍÍÒÒÒÒÒÒÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÇÇÇ»»»¾¾¾³³³»»»ÑÑÑâââêêêãããäääàààæææààààààÂÂÂÀÀÀÍÍÍÍÍÍÑÑÑÒÒÒÑÑÑÒÒÒØØØØØØÕÕÕ×××××××××ÕÕÕÔÔÔÕÕÕÙÙÙÜÜÜÍÍÍÌÌÌÅÅÅÇÇÇÆÆÆ¿¿¿ÇÇÇÊÊÊÌÌÌÅÅÅÆÆÆÑÑÑØØØÔÔÔÑÑÑÔÔÔÑÑÑÑÑÑ×××ÒÒÒÃÃø¸¸¼¼¼ÅÅÅ»»»µµµ°°°¯¯¯­­­¯¯¯···ÀÀÀºººººº¼¼¼¿¿¿ÃÃÃÅÅÅÅÅÅÅÅÅÐÐÐÍÍÍÕÕÕÉÉÉÌÌÌÐÐÐâââÝÝÝßßßÜÜÜÝÝÝàààßßßÜÜÜÝÝÝãããâââÝÝÝäääóóóÿÿÿøøøòòòóóóïïïóóóÿÿÿüüüäääÑÑÑÉÉÉÂÂÂÎÎÎÐÐÐÐÐÐÎÎÎÑÑÑÕÕÕÒÒÒÌÌÌÔÔÔÍÍÍÉÉÉÆÆÆÅÅÅÊÊÊÒÒÒÔÔÔÙÙÙØØØÙÙÙÛÛÛÛÛÛ×××ÒÒÒÒÒÒÇÇÇÆÆÆÆÆÆÃÃÃÂÂÂÃÃÃÅÅÅÇÇÇÅÅÅÊÊÊÎÎÎÎÎεµµ´´´»»»äääàààæææñññóóóñññíííçççòòòøøøäääâââÝÝÝÕÕÕßßßÑÑÑÒÒÒÒÒÒÛÛÛÌÌÌ»»»ÔÔÔÇÇÇÆÆÆÒÒÒÛÛÛßßßÜÜÜÛÛÛÜÜÜÙÙÙÔÔÔÕÕÕÉÉÉ»»»···ººº¾¾¾¿¿¿¿¿¿ÃÃô´´°°°µµµ¼¼¼ÅÅÅÇÇÇ¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»ººº¸¸¸ººº¼¼¼¼¼¼»»»»»»¿¿¿¾¾¾¸¸¸ÍÍÍÊÊÊÉÉÉÌÌÌÌÌÌÉÉÉÉÉÉÉÉÉÅÅÅÜÜÜÒÒÒÙÙÙ××צ¦¦···¾¾¾»»»¸¸¸»»»ÀÀÀÃÃÃÃÃÃÅÅÅÉÉɬ¬¬···¿¿¿¼¼¼¾¾¾ÂÂÂÅÅÅÃÃÃÃÃúºº³³³¼¼¼ÐÐÐÜÜÜÜÜÜÕÕÕÎÎÎÐÐÐÑÑÑÑÑÑÍÍÍÊÊÊÉÉÉÉÉÉÆÆÆÇÇǾ¾¾¼¼¼ºººÂÂÂÛÛÛâââêêêääääääÜÜÜßßßÆÆÆÃÃÃÊÊÊÍÍÍÒÒÒÔÔÔÎÎÎÌÌÌÒÒÒÙÙÙÛÛÛÙÙÙÙÙÙØØØÕÕÕÔÔÔÕÕÕÛÛÛßßßÑÑÑÎÎÎÆÆÆÇÇÇÆÆÆÀÀÀÉÉÉÌÌÌÌÌÌÃÃÃÅÅÅÑÑÑØØØÔÔÔÑÑÑÔÔÔÍÍÍÑÑÑÙÙÙÝÝÝÐÐкºº···ÃÃþ¾¾¼¼¼¾¾¾ÀÀÀ¼¼¼´´´³³³µµµµµµ´´´´´´···»»»¼¼¼»»»ºººÊÊÊÉÉÉ×××ÎÎÎÊÊÊÉÉÉâââëëëèèèæææääääääàààÛÛÛÛÛÛßßßÝÝÝàààíííöööóóóëëëïïïúúúÿÿÿóóóïïïäääÍÍÍÂÂÂÌÌÌÒÒÒÔÔÔÑÑÑÎÎÎÌÌÌÑÑÑØØØ×××ÑÑÑÔÔÔÎÎÎÒÒÒÔÔÔÌÌÌÎÎÎÔÔÔÑÑÑßßßÕÕÕÐÐÐÔÔÔ×××ÕÕÕÔÔÔÔÔÔÕÕÕÒÒÒÒÒÒÐÐÐÐÐÐÑÑÑÌÌÌÌÌÌÊÊÊÅÅÅÃÃÃÇÇÇÊÊÊÆÆÆÀÀÀ¿¿¿ººº³³³ÀÀÀØØØäääëëëíííæææëëëöööæææãããÜÜÜ×××êêêæææÔÔÔÑÑÑÜÜÜÐÐм¼¼ÔÔÔÌÌÌ×××âââßßßÜÜÜÝÝÝÝÝÝÜÜÜÙÙÙ×××ÑÑÑ¿¿¿···¾¾¾ÀÀÀ»»»¾¾¾ÇÇÇÅÅŵµµ±±±µµµ»»»ÆÆÆÊÊÊÀÀÀ¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼ººº¸¸¸···´´´¸¸¸ºººººº¾¾¾Â¾¾¾···ÔÔÔÎÎÎÍÍÍÐÐÐÌÌÌÃÃÃÀÀÀÃÃÃÅÅÅÕÕÕÎÎÎÒÒÒÕÕÕ¨¨¨¯¯¯µµµ»»»ººº¼¼¼ÂÂÂÃÃÃÂÂÂÂÂÂÅÅű±±¼¼¼ÂÂÂÂÂÂÌÌÌÜÜÜãããÝÝÝÆÆÆÃÃþ¾¾···³³³ºººÉÉÉÕÕÕäääÛÛÛÑÑÑÌÌÌÌÌÌÌÌÌÉÉÉÆÆÆÌÌÌÆÆÆÃÃÃÇÇǾ¾¾¸¸¸ÀÀÀ···ººº¸¸¸¾¾¾»»»ÆÆÆ»»»ÃÃÃÑÑÑÒÒÒ×××ÒÒÒÒÒÒÛÛÛÙÙÙÕÕÕÙÙÙØØØßßßÒÒÒÑÑÑ××××××ÛÛÛÙÙÙÒÒÒÐÐÐÇÇÇÅÅÅÇÇÇÃÃÃÂÂÂÌÌÌÍÍÍÀÀÀÃÃÃÑÑÑÔÔÔÒÒÒÒÒÒÒÒÒÎÎÎÐÐÐÙÙÙÜÜÜÐÐÐÅÅž¾¾±±±ÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀ¼¼¼´´´¯¯¯°°°³³³ÅÅÅÑÑÑÅÅźºº¸¸¸µµµÀÀÀÇÇÇÊÊÊÉÉÉÇÇÇÊÊÊÊÊÊÇÇÇÌÌÌÍÍÍèèèÜÜÜããããããÜÜÜÝÝÝÜÜÜàààíííïïïîîîöööÿÿÿöööüüüãããÉÉÉÊÊÊÔÔÔÑÑÑÒÒÒÔÔÔÑÑÑÔÔÔÎÎÎÕÕÕÙÙÙÔÔÔ×××ÔÔÔÍÍÍÐÐÐÑÑÑÐÐÐÍÍÍÍÍÍÒÒÒØØØÛÛÛØØØ××××××ÔÔÔÑÑÑ×××àààßßßÜÜÜ×××ÑÑÑÎÎÎÍÍÍÐÐÐÒÒÒÑÑÑÕÕÕÉÉÉÎÎÎÔÔÔÑÑÑÐÐл»»¿¿¿ºººÆÆÆ¿¿¿¿¿¿ÜÜÜîîîöööïïïñññóóóëëëÜÜÜàààæææßßß×××ÎÎÎÔÔÔÑÑÑÆÆÆÐÐÐÑÑÑ¿¿¿ãããàààßßßààààààßßßÛÛÛØØØÇÇÇ¿¿¿ºººººº»»»»»»¾¾¾ÂÂÂÂÂÂÃÃꪪªªª¾¾¾¿¿¿ÀÀÀÅÅÅ¿¿¿¾¾¾¼¼¼»»»ººº¸¸¸¸¸¸¸¸¸ºººººº¾¾¾ÃÃõµµ»»»···ÊÊÊÃÃÃÌÌÌÐÐÐÌÌÌÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÇÇÇÐÐÐÍÍÍÑÑÑÉÉɱ±±¯¯¯¼¼¼······ÅÅž¾¾¼¼¼ÌÌ̼¼¼±±±´´´¾¾¾ÎÎÎÑÑÑâââÙÙÙâââÝÝÝÍÍÍÆÆÆÂ¸¸¸···»»»ºººÙÙÙØØØÔÔÔÍÍÍÍÍÍÎÎÎÊÊÊÃÃÃÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÃÃÿ¿¿¼¼¼ººº»»»¼¼¼¾¾¾ÀÀÀÅÅÅÊÊÊÐÐÐÕÕÕØØØÔÔÔÔÔÔÛÛÛÛÛÛÙÙÙßßßÝÝÝëëëâââÜÜÜßßßÝÝÝÙÙÙÍÍÍÒÒÒÐÐÐÇÇÇÃÃÃÆÆÆÂÂÂÂÂÂÌÌÌÍÍÍÂÂÂÆÆÆÔÔÔÔÔÔÑÑÑÒÒÒÑÑÑÌÌÌÉÉÉÑÑÑØØØÔÔÔÑÑÑÉÉÉ»»»¼¼¼»»»»»»¾¾¾ÀÀÀÃÃÃÂÂÂÀÀÀÇÇÇÅÅÅÊÊÊÐÐÐÇÇÇÂÂÂÀÀÀºººÅÅÅÊÊÊÌÌÌÉÉÉÇÇÇÊÊÊÌÌÌÊÊÊÌÌÌÎÎÎëëëßßßæææäääÜÜÜÝÝÝãããæææîîîñññíííòòòöööñññÜÜÜÔÔÔÉÉÉÉÉÉÐÐÐÔÔÔ×××ÕÕÕÑÑÑÙÙÙÔÔÔ×××ØØØÛÛÛÝÝÝÔÔÔÕÕÕÔÔÔÑÑÑÐÐÐÑÑÑÕÕÕÛÛÛÝÝÝõõõæææØØØ××××××ÐÐÐÆÆÆ¿¿¿¿¿¿¿¿¿¾¾¾ººººººÃÃÃÕÕÕäääÒÒÒÝÝÝ×××ÔÔÔÌÌÌÇÇÇÐÐÐÍÍÍÆÆÆÅÅÅÉÉɾ¾¾¼¼¼ÊÊÊ×××íííóóóïïïùùùùùùæææÝÝÝßßßØØØçççØØØÙÙÙ×××ÊÊÊÒÒÒÜÜÜÒÒÒÛÛÛßßßßßßÛÛÛÙÙÙÜÜÜÜÜÜ××׿¿¿ººº¸¸¸»»»¼¼¼¼¼¼¿¿¿ÅÅÅÃÃÃÅÅÅ­­­¬¬¬¾¾¾¾¾¾¼¼¼¾¾¾ÂÂÂÀÀÀ¾¾¾»»»¸¸¸·········¸¸¸ººº¼¼¼ÀÀÀ···Â¼¼¼ÊÊÊÆÆÆÍÍÍÐÐÐÊÊÊÆÆÆÆÆÆÆÆÆÅÅÅÇÇÇÂÂÂÌÌÌÎÎÎÐÐÐÎÎμ¼¼´´´ººº¸¸¸ºººÂ¿¿¿ÅÅÅÌÌÌ´´´´´´´´´¸¸¸ÂÂÂÆÆÆÛÛÛÕÕÕÝÝÝâââÎÎÎÃÃÿ¿¿¿¿¿ÀÀÀ¼¼¼ÇÇÇÑÑÑÕÕÕÑÑÑÊÊÊÉÉÉÊÊÊÉÉÉÉÉÉÊÊÊÌÌÌÌÌÌÊÊÊÆÆÆÂ¿¿¿ÂÂÂÂÂÂÂÂÂÃÃÃÇÇÇÌÌÌÑÑÑÔÔÔÕÕÕÛÛÛÛÛÛÛÛÛÝÝÝÜÜÜØØØÙÙÙÔÔÔàààÐÐÐÅÅÅÌÌÌ×××ÙÙÙÎÎÎÔÔÔÐÐÐÆÆÆÂÂÂÃÃÃÀÀÀÀÀÀÊÊÊÊÊÊÃÃÃÊÊÊÕÕÕÔÔÔÐÐÐÐÐÐÎÎÎÌÌÌÇÇÇÌÌÌÔÔÔÙÙÙÙÙÙÎÎο¿¿ÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÐÐÐÊÊÊÉÉÉÉÉÉÉÉÉÌÌÌÆÆÆ»»»ÆÆÆÊÊÊÌÌÌÊÊÊÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÑÑÑîîîâââçççäääÜÜÜÝÝÝäääçççîîîñññîîîñññóóóïïïÃÃÃÊÊÊÎÎÎÌÌÌÎÎÎØØØÛÛÛ×××ÒÒÒßßßØØØÙÙÙØØØßßßàààÒÒÒ×××ÔÔÔÑÑÑÑÑÑÕÕÕØØØÛÛÛÛÛÛÃÃÃÇÇÇÉÉÉÆÆÆ¼¼¼ºººÃÃÃÐÐÐâââäääæææààà×××ÍÍÍÉÉÉÇÇÇÌÌÌ×××ØØØÙÙÙÔÔÔÐÐÐÕÕÕÒÒÒÎÎÎÐÐÐÌÌÌ¿¿¿¼¼¼ÃÃÃäääöööîîîõõõùùùèèèßßßãããäääàààÑÑÑ×××ÜÜÜÎÎÎÐÐÐÜÜÜ×××ÐÐÐÜÜÜàààÛÛÛÙÙÙÝÝÝÛÛÛÑÑѺºº···¸¸¸»»»¼¼¼»»»¿¿¿ÅÅÅÅÅÅÅÅů¯¯°°°¿¿¿¿¿¿¿¿¿¾¾¾ÂÂÂÀÀÀ¾¾¾ººº¸¸¸µµµµµµµµµ»»»¼¼¼¼¼¼¾¾¾¸¸¸ÉÉÉÀÀÀÆÆÆÉÉÉÍÍÍÎÎÎÊÊÊÅÅÅÆÆÆÇÇÇÉÉÉÇÇÇ»»»ÉÉÉÒÒÒÑÑÑÐÐо¾¾¬¬¬¸¸¸ººº¼¼¼ÂÂÂÂÂÂÉÉÉÇÇǬ¬¬°°°³³³´´´¼¼¼ÂÂÂßßßÛÛÛßßßâââÔÔÔÍÍÍÊÊÊÆÆÆÃÃÃÃÃÃÀÀÀºººÊÊÊØØØÕÕÕÊÊÊÅÅÅÇÇÇÍÍÍÇÇÇÉÉÉÌÌÌÍÍÍÌÌÌÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÂÂÂÃÃÃÇÇÇÍÍÍÑÑÑÔÔÔÜÜÜßßßÝÝÝÙÙÙØØØØØØ×××ÕÕÕâââäääÌÌÌ¿¿¿ÉÉÉÒÒÒÜÜÜ×××ÒÒÒÐÐÐÅÅÅÀÀÀ¿¿¿¿¿¿ÉÉÉÇÇÇÅÅÅÎÎÎØØØÒÒÒÍÍÍÍÍÍÌÌÌÎÎÎÍÍÍÐÐÐ×××ÙÙÙÕÕÕÉÉÉ»»»ÆÆÆÃÃÿ¿¿¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÆÆÆÆÆÆÅÅÅÂÂÂÅÅÅÇÇÇ¿¿¿±±±ÀÀÀÅÅÅÉÉÉÌÌÌÌÌÌÍÍÍÎÎÎÎÎÎÐÐÐÒÒÒïïïâââäääãããÜÜÜßßßßßßãããèèèîîîñññóóóõõõóóóÌÌÌÊÊÊÔÔÔÒÒÒÐÐÐÙÙÙØØØÕÕÕ×××àààßßßêêêãããêêêêêêàààëëëêêêäääÝÝÝÕÕÕÍÍÍÇÇÇÃÃÃÉÉÉÆÆÆÆÆÆÌÌÌÔÔÔØØØØØØ×××ÂÂÂÀÀÀÅÅÅÎÎÎÙÙÙââââââßßßÐÐÐÍÍÍÉÉÉÐÐÐÙÙÙÛÛÛÕÕÕÊÊÊÑÑÑÐÐÐÍÍÍÍÍÍÌÌÌ¿¿¿ÂÂÂÜÜÜîîîñññõõõóóóíííääääääííí×××ÌÌÌÐÐÐÛÛÛÎÎÎÉÉÉÙÙÙÙÙÙÍÍÍÕÕÕÛÛÛÝÝÝßßßÝÝÝÒÒÒÆÆÆ»»»ºººººº»»»¸¸¸···»»»ÂÂÂÃÃÃÃÃð°°±±±¾¾¾¿¿¿Â¾¾¾¼¼¼»»»¸¸¸······µµµ···¾¾¾ÀÀÀ¼¼¼»»»¸¸¸ÎÎÎÃÃÃÂÂÂÉÉÉÍÍÍÐÐÐÍÍÍÉÉÉÆÆÆÇÇÇÊÊÊÊÊʼ¼¼ÅÅÅÊÊÊÍÍÍÉÉɵµµ¨¨¨ºººººº¿¿¿ÃÃÿ¿¿ÀÀÀ¼¼¼ªªªªªª°°°´´´»»»ÃÃÃàààÙÙÙ×××ÜÜÜÛÛÛÛÛÛØØØÍÍÍÃÃÃÃÃÃÇÇÇ»»»ÇÇÇÔÔÔÕÕÕÐÐÐÌÌÌÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÊÊÊÆÆÆÅÅÅÅÅÅÆÆÆÊÊÊÎÎÎÒÒÒÕÕÕâââàààÜÜÜÔÔÔÑÑÑ×××ÜÜÜÙÙÙÜÜÜÜÜÜÍÍÍÑÑÑÜÜÜÛÛÛÝÝÝÜÜÜÒÒÒÎÎÎÅÅÅÀÀÀ¾¾¾¾¾¾ÇÇÇÆÆÆÆÆÆÑÑÑØØØÒÒÒÍÍÍÎÎÎÌÌÌÍÍÍÒÒÒ×××ÙÙÙØØØÍÍÍ¿¿¿¸¸¸¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¿¿¿ÂÂÂÃÃÃÅÅÅÉÉÉÆÆÆÀÀÀÀÀÀÀÀÀ»»»³³³µµµ»»»ÅÅÅÌÌÌÎÎÎÎÎÎÎÎÎÐÐÐÒÒÒÒÒÒëëëÜÜÜàààâââÜÜÜàààÜÜÜßßßäääëëëñññóóóóóóõõõàààÉÉÉÎÎÎÒÒÒÑÑÑ×××ÒÒÒÕÕÕÝÝÝßßßÙÙÙèèèÑÑÑÉÉÉÃÃþ¾¾ÂÂÂÅÅÅÆÆÆÃÃÿ¿¿¾¾¾ÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎÒÒÒ×××ÔÔÔÊÊÊÂÂÂßßßÕÕÕÌÌÌÉÉÉÍÍÍÐÐÐÎÎÎÌÌÌçççÛÛÛÐÐÐÎÎÎÔÔÔÙÙÙ×××ÔÔÔÎÎÎÌÌÌÌÌÌÕÕÕÔÔÔÇÇÇÆÆÆÐÐÐÜÜÜöööúúúõõõöööêêêÛÛÛâââãããÛÛÛÑÑÑ×××ÎÎÎÆÆÆÙÙÙãããÕÕÕÍÍÍÌÌÌÔÔÔÙÙÙÒÒÒÅÅż¼¼¾¾¾ººº¸¸¸¸¸¸···µµµ¼¼¼ÃÃÃÂÂÂÀÀÀ°°°¯¯¯µµµµµµ»»»»»»···············¸¸¸¸¸¸¸¸¸»»»¾¾¾»»»ººººººÑÑÑÇÇÇÃÃÃÇÇÇÌÌÌÐÐÐÑÑÑÎÎÎÉÉÉÇÇÇÉÉÉÎÎÎÅÅÅÃÃÃÃÃÃÉÉÉÅÅű±±³³³¾¾¾¸¸¸ÀÀÀÅÅž¾¾µµµ°°°¯¯¯­­­±±±³³³¸¸¸¿¿¿ÛÛÛÒÒÒÐÐÐØØØÛÛÛÝÝÝßßßØØØÍÍÍÇÇÇÌÌÌÃÃÃÃÃÃÉÉÉÑÑÑØØØØØØÒÒÒÎÎÎÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÒÒÒ×××ÛÛÛÝÝÝÜÜÜÝÝÝàààßßßÝÝÝãããâââÕÕÕÊÊÊÍÍÍÆÆÆÔÔÔàààÛÛÛÙÙÙÛÛÛÐÐÐÍÍÍÅÅÅÀÀÀ¼¼¼»»»ÃÃÃÊÊÊÊÊÊÕÕÕÛÛÛÕÕÕÒÒÒÒÒÒÎÎÎÌÌÌÕÕÕÛÛÛÛÛÛ×××ÉÉɾ¾¾»»»¾¾¾¿¿¿ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÅÅÅÅÅÅÉÉÉÆÆÆÀÀÀÃÃÃÅÅÅÅÅÅÆÆÆ¯¯¯µµµÀÀÀÌÌÌÐÐÐÎÎÎÎÎÎÐÐÐÒÒÒÐÐÐæææ×××ÝÝÝàààÜÜÜßßßÝÝÝàààâââèèèññññññîîîñññêêêÀÀÀÂÂÂÍÍÍÐÐÐÔÔÔÎÎÎØØØààààààÝÝÝóóóÕÕÕÍÍÍÌÌÌÍÍÍÑÑÑÐÐÐÌÌÌÆÆÆÀÀÀÃÃÃÊÊÊÑÑÑÍÍÍØØØÝÝÝØØØÐÐÐÍÍÍÒÒÒ×××ÍÍÍÐÐÐÔÔÔ×××ØØØØØØÙÙÙÛÛÛÐÐÐÍÍÍÐÐÐÊÊÊÃÃÃÃÃÃÆÆÆÑÑÑÌÌÌÐÐÐÍÍÍÔÔÔÔÔÔÌÌÌÉÉÉÅÅÅÍÍÍíííöööñññöööíííßßßäääçççëëë×××ØØØ×××ÅÅÅÎÎÎÛÛÛÝÝÝÊÊÊ¿¿¿ÅÅÅÌÌÌÅÅż¼¼»»»¾¾¾¸¸¸µµµ···¸¸¸ºººÀÀÀÇÇÇÃÃÃÃÃô´´°°°­­­¨¨¨¯¯¯­­­­­­°°°³³³µµµ¸¸¸¸¸¸¸¸¸¸¸¸µµµ¸¸¸¸¸¸¸¸¸¸¸¸ÑÑÑÉÉÉÉÉÉÆÆÆÊÊÊÑÑÑ×××ÒÒÒÊÊÊÇÇÇÉÉÉÅÅÅÇÇÇÎÎÎÑÑÑÕÕÕÇÇǰ°°···ÀÀÀ¸¸¸ÀÀÀÅÅÅ¿¿¿´´´¬¬¬³³³³³³´´´´´´»»»ÀÀÀÝÝÝÛÛÛàààØØØ×××ÔÔÔÛÛÛãããÜÜÜÐÐÐÌÌÌÇÇÇÀÀÀ¿¿¿ÉÉÉ×××ÛÛÛÙÙÙÕÕÕ×××ÕÕÕÑÑÑÎÎÎÍÍÍÎÎÎÎÎÎÐÐÐÎÎÎÐÐÐÑÑÑÑÑÑÒÒÒÕÕÕÛÛÛßßßãããäääëëëíííêêêîîîæææÑÑÑÔÔÔÙÙÙÑÑÑÕÕÕÜÜÜÕÕÕÔÔÔÒÒÒÎÎÎÍÍÍÅÅÅÂÂÂÃÃü¼¼ºººÀÀÀÐÐÐÐÐÐÙÙÙßßßÛÛÛÙÙÙÛÛÛÔÔÔÑÑÑÙÙÙÛÛÛØØØÕÕÕÊÊÊ¿¿¿¿¿¿ÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÂÂÂÂÂÂÉÉÉÆÆÆÀÀÀÆÆÆ¯¯¯´´´¿¿¿ÌÌÌÐÐÐÎÎÎÎÎÎÑÑÑÐÐÐÌÌÌàààÒÒÒÜÜÜàààÛÛÛÛÛÛÝÝÝààààààçççñññîîîèèèîîîèè躺º¿¿¿ÌÌÌÎÎÎÕÕÕÐÐÐÛÛÛßßßãããßßßïïïÉÉÉÇÇÇÊÊÊÎÎÎæææßßßÕÕÕÎÎÎÌÌÌÌÌÌÊÊÊÊÊÊßßß×××ÌÌÌÉÉÉÎÎÎ×××ÒÒÒÉÉÉÅÅÅÆÆÆÉÉÉÊÊÊÉÉÉÉÉÉÌÌÌÎÎÎÐÐÐÎÎÎÛÛÛÙÙÙÕÕÕÔÔÔÐÐÐÛÛÛÇÇÇÝÝÝÔÔÔÍÍÍÒÒÒÎÎÎÎÎÎÌÌÌÅÅÅÙÙÙëëëññññññêêêçççêêêâââóóóØØØ×××ßßßÆÆÆÅÅÅÒÒÒÝÝÝÐÐÐÅÅÅÃÃÃÅÅÅÀÀÀ¿¿¿¿¿¿ÀÀÀ»»»···ººº¼¼¼¼¼¼ÀÀÀÅÅÅÅÅÅÇÇǾ¾¾¸¸¸¯¯¯¥¥¥ªªª¨¨¨¨¨¨¬¬¬±±±µµµ¸¸¸¸¸¸···µµµµµµ¸¸¸ººº»»»···ÊÊÊÃÃÃÇÇÇÆÆÆÊÊÊÒÒÒØØØÔÔÔÌÌÌÇÇÇÊÊÊÀÀÀÆÆÆÛÛÛààà××ׯ¯¯µµµÂ¸¸¸¿¿¿ÂÂÂÃÃÿ¿¿°°°³³³´´´´´´µµµ¿¿¿ÃÃÃÛÛÛØØØâââÝÝÝØØØÐÐÐ×××äääàààÑÑÑÌÌÌÊÊÊÃÃÃÀÀÀÃÃÃÉÉÉÍÍÍÒÒÒÙÙÙÕÕÕÕÕÕÔÔÔÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÍÍÍÐÐÐÒÒÒÑÑÑÐÐÐÑÑÑÙÙÙßßßúúúõõõñññêêêæææîîîëëëØØØÍÍÍÙÙÙÔÔÔÕÕÕÛÛÛ×××ÕÕÕÎÎÎÍÍÍÌÌÌÅÅÅÂÂÂÃÃü¼¼¸¸¸¿¿¿ÔÔÔÔÔÔÜÜÜâââßßßßßßàààÙÙÙÙÙÙÝÝÝÙÙÙÕÕÕ×××ÍÍÍÀÀÀÀÀÀÅÅÅÆÆÆÆÆÆÃÃÃÂÂÂÃÃÃÇÇÇÌÌÌÌÌÌÉÉÉÂÂÂÅÅÅÊÊʼ¼¼¬¬¬¬¬¬³³³µµµ¿¿¿ÌÌÌÐÐÐÍÍÍÎÎÎÔÔÔÌÌÌÇÇÇÝÝÝÑÑÑÜÜÜàààØØØØØØÛÛÛÝÝÝÝÝÝäääñññîîîèèèïïïççç»»»ÅÅÅÎÎÎÐÐÐØØØÒÒÒÜÜÜÝÝÝçççâââëëëÀÀÀÇÇÇÐÐÐÑÑÑçççßßßÙÙÙÛÛÛââââââÛÛÛÑÑÑÅÅÅÐÐÐÕÕÕÒÒÒÍÍÍÊÊÊÇÇÇÂÂÂßßßÜÜÜÛÛÛÝÝÝâââãããàààÜÜÜÛÛÛÊÊÊÊÊÊÊÊÊÒÒÒ×××ÉÉÉÊÊÊÆÆÆëëëÙÙÙÉÉÉÒÒÒÔÔÔ×××ÙÙÙÂÂÂÍÍÍëëëÿÿÿõõõæææâââÝÝÝäääüüü×××ÐÐÐàààÊÊÊÊÊÊÝÝÝØØØ×××ÒÒÒÌÌÌÇÇÇÆÆÆÅÅÅÃÃÃÅÅž¾¾»»»¼¼¼¿¿¿¼¼¼¼¼¼¿¿¿ÅÅÅÊÊÊÆÆÆÃÃõµµªªª¯¯¯¬¬¬¥¥¥©©©°°°µµµ¸¸¸···´´´³³³ººº¼¼¼¼¼¼¼¼¼´´´Â»»»ÃÃÃÇÇÇÊÊÊÑÑÑØØØÕÕÕÌÌÌÉÉÉÌÌÌÌÌÌÉÉÉÜÜÜÜÜÜÅÅÅ´´´°°°¸¸¸ÀÀÀººº¿¿¿¿¿¿ÇÇÇÍÍÍ···°°°³³³±±±´´´¾¾¾¼¼¼ÉÉÉ¿¿¿ÇÇÇãããßßßÕÕÕ×××ßßßÙÙÙÍÍÍÍÍÍÍÍÍÉÉÉÆÆÆÂ¼¼¼¼¼¼ÉÉÉØØØÒÒÒÔÔÔÕÕÕ×××ÕÕÕÔÔÔÑÑÑÐÐÐÐÐÐÕÕÕÙÙÙ×××ÔÔÔÕÕÕÝÝÝæææèèèíííäääÛÛÛñññøøøæææèèèÊÊÊÔÔÔßßßàààÙÙÙÑÑÑÌÌÌÊÊÊÐÐÐÍÍÍ¿¿¿ÌÌÌÀÀÀ»»»¼¼¼ÅÅÅÒÒÒÙÙÙßßßÝÝÝÜÜÜÝÝÝÜÜÜØØØÙÙÙÔÔÔÒÒÒÔÔÔÌÌ̾¾¾ºººÀÀÀÃÃÃÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀ»»»±±±°°°±±±¼¼¼ÇÇÇ¿¿¿­­­©©©°°°···ºººÀÀÀÉÉÉÎÎÎÑÑÑÎÎÎÌÌÌÇÇÇÌÌÌÕÕÕÝÝÝÝÝÝØØØÙÙÙâââßßßÝÝÝßßßöööñññèèèÿÿÿîîîßßßÆÆÆºººÊÊÊÇÇÇÕÕÕÔÔÔ×××ÛÛÛààààààäääÒÒÒ¿¿¿ÌÌÌÔÔÔÜÜÜÐÐÐÐÐÐÆÆÆÃÃÃÉÉÉÉÉÉØØØÉÉÉÍÍÍÌÌ̾¾¾ÆÆÆÒÒÒÛÛÛÒÒÒÒÒÒÔÔÔÕÕÕ×××ØØØÙÙÙÙÙÙÙÙÙ×××ØØØÙÙÙÒÒÒÉÉÉÍÍÍÙÙÙÎÎÎÉÉÉÛÛÛÙÙÙØØØÑÑÑÛÛÛÑÑÑÎÎλ»»õõõøøøòòòõõõêêêãããëëëîîîÝÝÝØØØâââÐÐÐÆÆÆßßßßßß×××ÎÎÎÊÊÊÊÊÊÌÌÌÊÊÊÇÇÇÃÃÿ¿¿¼¼¼»»»»»»¼¼¼¼¼¼ÂÂÂÉÉÉ»»»»»»³³³ªªª­­­¦¦¦¢¢¢¦¦¦´´´¼¼¼ºººµµµ´´´µµµººº¼¼¼»»»»»»¿¿¿ÀÀÀ¿¿¿ÉÉÉÐÐÐÎÎÎÔÔÔÇÇÇÌÌÌÉÉÉÐÐÐÊÊÊÆÆÆÕÕÕÝÝÝÐÐЬ¬¬···»»»¼¼¼¼¼¼ººº¾¾¾ÎÎÎÙÙÙÉÉÉ­­­³³³±±±···¿¿¿ÃÃÃÂÂÂÃÃÃÉÉÉÉÉÉÑÑÑÔÔÔÒÒÒØØØÝÝÝ×××ÉÉÉÉÉÉÒÒÒÐÐÐÇÇÇÇÇÇÇÇÇÆÆÆÊÊÊÕÕÕÒÒÒÙÙÙ×××ÕÕÕØØØÑÑÑÕÕÕÙÙÙÛÛÛÛÛÛÙÙÙÙÙÙßßßêêêóóóâââèèèëëëãããçççêêêàààëëëçççâââÙÙÙÔÔÔÑÑÑÎÎÎÌÌÌÉÉÉÎÎÎÊÊʺººÇÇǾ¾¾¿¿¿ÅÅÅÎÎÎÐÐÐØØØÝÝÝÜÜÜÙÙÙÙÙÙØØØÕÕÕÒÒÒÍÍÍÎÎÎÒÒÒÌÌÌ¿¿¿»»»¿¿¿¿¿¿ÃÃÃÅÅÅÂÂÂÀÀÀ¾¾¾···´´´±±±±±±³³³­­­¨¨¨­­­¸¸¸ººº¼¼¼ÂÂÂÉÉÉÎÎÎÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÍÍÍÕÕÕÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜàààâââõõõïïïíííÿÿÿîîîêêê×××¾¾¾ÆÆÆÃÃÃÐÐÐÔÔÔØØØÜÜÜàààßßßààà×××ÅÅÅÇÇÇÑÑÑÑÑÑÐÐÐ×××ÙÙÙ×××ÔÔÔÐÐÐÔÔÔÃÃÃÐÐÐÛÛÛÛÛÛ×××ÔÔÔÑÑÑÍÍÍÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÑÑÑÍÍÍÉÉÉÊÊÊÑÑÑÐÐÐÇÇÇÆÆÆÍÍÍÑÑÑßßßÑÑÑÅÅÅçççÜÜÜÍÍÍÙÙÙÔÔÔ¾¾¾ÝÝÝîîîõõõòòòïïïæææîîîèèèÛÛÛØØØàààÕÕÕÊÊÊÒÒÒÛÛÛÕÕÕÒÒÒÔÔÔ×××ÔÔÔÌÌÌÃÃÃÆÆÆÅÅÅ¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼ÂÂÂÅÅÅÆÆÆÆÆÆÃÃþ¾¾¾¾¾ÆÆÆÂ¸¸¸°°°°°°µµµººº»»»¼¼¼»»»µµµ³³³¸¸¸¿¿¿ÀÀÀÂÂÂÃÃÃÙÙÙÙÙÙÑÑÑ×××ÍÍÍÒÒÒÊÊÊÊÊÊÌÌÌÍÍÍÝÝÝäääÒÒÒ¬¬¬¸¸¸¾¾¾¸¸¸¾¾¾¿¿¿¿¿¿ÆÆÆÐÐÐÒÒÒÎÎÎÃÃÃÀÀÀººº±±±³³³¼¼¼ÀÀÀ¾¾¾ÐÐÐÕÕÕ×××ÕÕÕÙÙÙàààÜÜÜÑÑÑÑÑÑÝÝÝßßßÕÕÕÐÐÐÊÊÊÉÉÉÍÍÍîîîßßßØØØÐÐÐÔÔÔßßßÝÝÝâââãããêêêîîîëëëäääàààãããçççããããããëëëæææàààßßßÜÜÜçççàààÛÛÛÔÔÔÑÑÑÒÒÒÒÒÒÎÎÎÊÊÊÇÇÇÆÆÆ¸¸¸ÉÉÉÅÅÅÇÇÇÍÍÍÔÔÔÍÍÍ×××ÜÜÜÛÛÛ×××ÕÕÕÒÒÒÐÐÐÑÑÑÍÍÍÎÎÎÑÑÑÍÍÍÀÀÀ¼¼¼¿¿¿¼¼¼ÀÀÀÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀ¾¾¾ªªª­­­°°°±±±°°°°°°³³³´´´»»»¾¾¾ÂÂÂÇÇÇÍÍÍÍÍÍÊÊÊÇÇÇÊÊÊÇÇÇÆÆÆÌÌÌØØØâââàààÛÛÛÛÛÛàààãããòòòïïïïïïÿÿÿîîîîîîæææÀÀÀÅÅÅÅÅÅÍÍÍÕÕÕØØØÜÜÜÝÝÝÜÜÜÛÛÛÜÜÜÎÎÎÂÂÂÎÎÎÑÑÑÑÑÑÎÎÎÑÑÑÐÐÐÌÌÌÒÒÒÕÕÕÐÐÐÒÒÒÑÑÑÍÍÍÊÊÊÌÌÌÎÎÎÐÐÐÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÆÆÆ¿¿¿¿¿¿ÇÇÇÊÊÊÇÇÇÅÅÅÇÇÇÑÑÑÐÐÐÐÐÐÊÊÊÒÒÒÍÍÍÍÍÍÍÍÍÒÒÒÂÂÂÇÇÇäääùùùñññóóóæææîîîãããØØØØØØÝÝÝÜÜÜÑÑÑÇÇÇÜÜÜÙÙÙ×××××××××ÕÕÕÑÑÑÎÎÎÊÊÊÉÉÉÅÅÅ¿¿¿¾¾¾¾¾¾¾¾¾ÀÀÀ¿¿¿ÅÅÅÇÇÇÀÀÀ¼¼¼ÀÀÀÆÆÆ¿¿¿¸¸¸°°°­­­±±±¸¸¸ººº···µµµ¸¸¸»»»¼¼¼¿¿¿ÀÀÀÀÀÀ¿¿¿ÇÇÇÐÐÐÐÐÐ×××ÌÌÌÎÎÎÊÊÊÐÐÐÍÍÍÑÑÑäääèèè××ׯ¯¯»»»ÅÅÅ»»»ÀÀÀÃÃÃÃÃÃÃÃÃÊÊÊØØØãããÕÕÕÒÒÒÉÉÉ»»»···¼¼¼ÂÂÂÂÂÂÐÐÐ×××ÙÙÙÛÛÛàààäääààà×××ãããçççãããàààãããÜÜÜÎÎÎÇÇÇæææÜÜÜßßßÜÜÜàààäääÜÜÜÜÜÜàààæææêêêæææÛÛÛÐÐÐÌÌÌÌÌÌïïïÝÝÝââââââÜÜÜÝÝÝÛÛÛÜÜÜÑÑÑÒÒÒÔÔÔÒÒÒÎÎÎÌÌÌÉÉÉÇÇÇÀÀÀÅÅž¾¾ÔÔÔÒÒÒÒÒÒÐÐÐÐÐÐÊÊÊÔÔÔÛÛÛØØØÔÔÔÑÑÑÐÐÐÍÍÍÔÔÔÐÐÐÎÎÎÐÐÐÊÊʼ¼¼¿¿¿¼¼¼ÀÀÀÅÅÅÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀ¥¥¥¯¯¯¸¸¸»»»¿¿¿ÀÀÀ¼¼¼´´´ººº»»»¿¿¿ÆÆÆÊÊÊÌÌÌÉÉÉÆÆÆÉÉÉÇÇÇÃÃÃÆÆÆÒÒÒààààààÙÙÙÛÛÛÝÝÝâââòòòòòòîîîøøøïïïæææêêêÀÀÀÆÆÆÉÉÉÎÎÎÕÕÕÔÔÔØØØØØØØØØ×××ßßßÕÕÕ¿¿¿ÎÎÎÕÕÕÕÕÕÇÇÇÇÇÇÆÆÆÅÅÅÕÕÕØØØÎÎÎÌÌÌÇÇÇÃÃÃÂÂÂÅÅÅÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÆÆÆÊÊʾ¾¾ÀÀÀÅÅÅÆÆÆÉÉÉÎÎÎÅÅÅÎÎÎÎÎÎÍÍÍÙÙÙ×××ÔÔÔÜÜÜÎÎÎÇÇÇÂÂÂÙÙÙòòòòòòñññæææèèèäääÛÛÛ×××ÝÝÝâââØØØÌÌÌ×××ÙÙÙÛÛÛØØØÕÕÕÔÔÔ×××ÛÛÛÐÐÐÍÍÍÉÉÉÅÅÅÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾»»»ÂÂÂÃÃü¼¼¼¼¼¿¿¿···¬¬¬­­­¬¬¬¬¬¬³³³¼¼¼»»»´´´¾¾¾ÐÐÐÒÒÒ¿¿¿±±±¸¸¸¼¼¼ººº···ÅÅÅÌÌÌÕÕÕÊÊÊÍÍÍÉÉÉÐÐÐÎÎÎÑÑÑßßßäääÙÙÙµµµ¿¿¿ÉÉÉÆÆÆÂÂÂÂÂÂÆÆÆÉÉÉÊÊÊÑÑÑÙÙÙÌÌÌÌÌÌÌÌÌÊÊʸ¸¸¸¸¸¿¿¿ÆÆÆÐÐÐÙÙÙßßßääääääÜÜÜÑÑÑççççççâââæææñññêêêÔÔÔÇÇÇÑÑÑÙÙÙîîîóóóóóóñññãããâââçççäääâââÝÝÝ×××ÑÑÑÌÌÌÇÇÇõõõÜÜÜÛÛÛÛÛÛØØØÜÜÜØØØÔÔÔÙÙÙÕÕÕÎÎÎÆÆÆÀÀÀ¿¿¿ÀÀÀÃÃÃÅÅÅÌÌÌÆÆÆÛÛÛÙÙÙÙÙÙÑÑÑÊÊÊÇÇÇÐÐÐ×××ÕÕÕÑÑÑÐÐÐÎÎÎÌÌÌÎÎÎÊÊÊÆÆÆÆÆÆÃÃÿ¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅ¿¿¿¿¿¿Â­­­µµµ»»»»»»ÀÀÀÇÇÇÆÆÆÀÀÀ···¸¸¸¼¼¼ÂÂÂÇÇÇÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÇÇÇÆÆÆÎÎÎÛÛÛßßßÛÛÛÝÝÝÛÛÛâââóóóóóóíííñññïïïäääççç¿¿¿ÃÃÃÇÇÇÍÍÍÒÒÒÑÑÑÒÒÒÒÒÒÔÔÔÒÒÒÝÝÝÕÕÕÀÀÀÑÑÑÎÎÎØØØÔÔÔÙÙÙÙÙÙÔÔÔÛÛÛÕÕÕÊÊÊÉÉÉÇÇÇÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÆÆÆÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÉÉÉÐÐÐØØØÂÂÂÌÌÌØØØÌÌÌØØØãããÎÎÎÐÐÐÎÎÎÊÊÊÍÍÍßßßñññîîîëëëâââêêêààà×××ßßßâââÛÛÛÛÛÛÐÐÐÒÒÒ×××ÛÛÛÜÜÜÛÛÛ×××ÔÔÔÒÒÒÐÐÐÌÌÌÇÇÇÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿ÀÀÀÆÆÆÅÅÅÃÃÃÌÌÌÇÇDZ±±°°°³³³³³³³³³ºººÂ¼¼¼¸¸¸ÉÉÉÊÊʸ¸¸³³³ÀÀÀÐÐÐÒÒÒÉÉÉÌÌÌÆÆÆÑÑÑÌÌÌÒÒÒÉÉÉÇÇÇÍÍÍÌÌÌÔÔÔÜÜÜÜÜÜ»»»ÃÃÃÌÌÌÌÌÌÃÃÿ¿¿ÅÅÅÉÉÉÆÆÆÇÇÇÌÌÌÇÇÇÆÆÆÌÌÌÒÒÒÑÑÑÅÅÅ»»»¸¸¸¾¾¾ÆÆÆÑÑÑØØØÜÜÜÛÛÛÔÔÔÌÌÌ×××ÝÝÝàààèèèñññèèè×××ÐÐÐÀÀÀÉÉÉÜÜÜâââæææêêêæææëëëäääÝÝÝ××××××ÜÜÜÜÜÜÔÔÔÌÌÌîîîÜÜÜÜÜÜ×××ÐÐÐÔÔÔÒÒÒÒÒÒÒÒÒÌÌÌÃÃÃÀÀÀÆÆÆÌÌÌÎÎÎÎÎÎÒÒÒÕÕÕÉÉÉÙÙÙ×××ØØØÐÐÐÇÇÇÃÃÃÊÊÊÎÎÎÎÎÎÍÍÍÐÐÐÎÎÎÊÊÊÀÀÀ¼¼¼ºººººº¼¼¼¿¿¿ÂÂÂÅÅÅÅÅÅÃÃÃÅÅÅÆÆÆÃÃÿ¿¿¿¿¿ÀÀÀ¯¯¯µµµººº»»»ÀÀÀÇÇÇÇÇÇÃÃ÷··¸¸¸¼¼¼ÂÂÂÇÇÇÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÊÊÊÌÌÌÑÑÑÙÙÙÝÝÝÝÝÝßßßßßßæææóóóõõõïïïîîîïïïëëëâââ¼¼¼ÀÀÀÃÃÃÌÌÌÐÐÐÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒ×××ÍÍÍÅÅÅÔÔÔÅÅÅÑÑÑÙÙÙàààâââÜÜÜÙÙÙÑÑÑÍÍÍÉÉÉÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÑÑÑÍÍÍÍÍÍÊÊÊÇÇÇÆÆÆÃÃÃÀÀÀÀÀÀ¼¼¼¿¿¿ÂÂÂÃÃÃÂÂÂÀÀÀÂÂÂÆÆÆÇÇÇÝÝÝÅÅž¾¾ÕÕÕÔÔÔÂÂÂßßß×××ÕÕÕÒÒÒÃÃÃÉÉÉííííííõõõßßßëëëæææÜÜÜààààààÝÝÝäääÙÙÙÒÒÒÎÎÎÑÑÑÙÙÙÜÜÜ×××ÐÐÐÔÔÔÑÑÑÎÎÎÊÊÊÆÆÆÅÅÅÃÃÃÃÃÃÇÇÇÉÉÉÉÉÉÆÆÆÇÇÇÌÌ̯¯¯¸¸¸¾¾¾ÂÂÂÃÃÃÃÃþ¾¾¸¸¸ÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÍÍÍÍÍÍÅÅÅÌÌÌÇÇÇÐÐÐÊÊÊÌÌÌÌÌÌÉÉÉÍÍÍ×××ÜÜܼ¼¼ÀÀÀÇÇÇÆÆÆÀÀÀ¾¾¾ÀÀÀÀÀÀ¿¿¿ÃÃÃÊÊÊÎÎÎÍÍÍÊÊÊÍÍÍÕÕÕØØØÉÉÉ···¼¼¼ÀÀÀÅÅÅÉÉÉÍÍÍÎÎÎÍÍÍÌÌÌÌÌÌÐÐÐÕÕÕâââïïïêêêÙÙÙÒÒÒÕÕÕÎÎÎÐÐÐÌÌÌÍÍÍÑÑÑÌÌÌÎÎÎÕÕÕÎÎÎÊÊÊÑÑÑÜÜÜÝÝÝÑÑÑÅÅÅâââÛÛÛÝÝÝÒÒÒÌÌÌÐÐÐÌÌÌÌÌÌÉÉÉÇÇÇÉÉÉÍÍÍÔÔÔÛÛÛÜÜÜÜÜÜÙÙÙÛÛÛÊÊÊÕÕÕÒÒÒÔÔÔÌÌÌ¿¿¿ÂÂÂÅÅÅÆÆÆÉÉÉÎÎÎÍÍÍÉÉɸ¸¸µµµ´´´···¼¼¼ÂÂÂÆÆÆÇÇÇÆÆÆÂÂÂÂÂÂÅÅÅÆÆÆÂÂÂÀÀÀ¬¬¬³³³»»»ÀÀÀÃÃÃÅÅÅÃÃû»»¼¼¼¿¿¿ÅÅÅÉÉÉÌÌÌÊÊÊÉÉÉÊÊÊÆÆÆÇÇÇÐÐÐÙÙÙÝÝÝßßßßßßßßßçççïïïñññóóóöööòòòëëëëëëÕÕÕºººÅÅÅÅÅÅÑÑÑÐÐÐÎÎÎÍÍÍÑÑÑÑÑÑÔÔÔÍÍÍÀÀÀÇÇÇÔÔÔÊÊÊÎÎÎÔÔÔÑÑÑÐÐÐÒÒÒÐÐÐÎÎÎÇÇÇÅÅÅÅÅÅÉÉÉÉÉÉÆÆÆÇÇÇÌÌÌÍÍÍÍÍÍÊÊÊÇÇÇÃÃÃÀÀÀ¾¾¾¼¼¼ºººººº¼¼¼¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾ÎÎÎÍÍÍÒÒÒÐÐÐÕÕÕÕÕÕçççÛÛÛÕÕÕÔÔÔÇÇÇÅÅÅçççëëëøøøâââçççêêêäääßßßÝÝÝßßßâââãããÛÛÛÐÐÐÌÌÌÎÎÎÒÒÒÕÕÕÕÕÕÔÔÔÒÒÒÎÎÎÊÊÊÇÇÇÆÆÆÆÆÆÅÅÅÊÊÊÌÌÌÉÉÉÇÇÇÇÇÇÀÀÀ¸¸¸µµµ¿¿¿ÃÃÃÉÉÉÌÌÌÇÇÇ¿¿¿»»»»»»ÀÀÀ¾¾¾ÀÀÀÉÉÉÎÎÎÊÊÊÃÃÃÀÀÀÂÂÂÇÇÇÇÇÇÔÔÔÎÎÎ×××ÐÐÐÑÑÑÌÌÌÍÍÍÑÑÑØØØÛÛÛ······¿¿¿¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼ÀÀÀÃÃÃÅÅÅÃÃÃÂÂÂÃÃÃÍÍÍÒÒÒÌÌÌ¿¿¿»»»¼¼¼¿¿¿ÂÂÂÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÜÜÜîîîêêêÙÙÙÑÑÑÝÝÝØØØÛÛÛ×××ØØØßßßÛÛÛßßßØØØÔÔÔÒÒÒØØØßßßÝÝÝÒÒÒÉÉÉÛÛÛÙÙÙÙÙÙÍÍÍÌÌÌÐÐÐÆÆÆÃÃÃØØØÜÜÜßßßÛÛÛÕÕÕÔÔÔØØØÜÜÜÛÛÛÛÛÛÊÊÊÕÕÕÑÑÑÒÒÒÇÇÇ»»»»»»¾¾¾¾¾¾¿¿¿ÆÆÆÍÍÍÍÍÍÇÇǺºº¸¸¸¸¸¸»»»ÀÀÀÆÆÆÉÉÉÉÉÉÇÇÇÀÀÀÀÀÀÅÅÅÆÆÆÃÃÃÂÂÂÃÃñ±±µµµ»»»¿¿¿ÂÂÂÂÂÂÅÅÅÆÆÆÀÀÀÀÀÀÃÃÃÇÇÇÊÊÊÌÌÌÊÊÊÉÉÉÌÌÌÃÃÃÅÅÅÒÒÒßßßâââààààààßßßñññùùùïïïòòòÿÿÿöööèèèãããÇÇǺººÌÌÌÍÍÍÙÙÙÑÑÑÎÎÎÎÎÎÒÒÒÑÑÑÕÕÕÆÆÆ¸¸¸ÉÉÉÔÔÔÕÕÕÒÒÒÕÕÕÆÆÆÂÂÂÊÊÊÆÆÆÊÊÊÌÌÌÉÉÉÉÉÉÊÊÊÊÊÊÆÆÆÉÉÉÐÐÐÐÐÐÎÎÎÌÌÌÇÇÇÅÅÅÀÀÀ¾¾¾¼¼¼¾¾¾ºººµµµ¸¸¸ÀÀÀÆÆÆÅÅÅÀÀÀÅÅÅÊÊÊÎÎÎÙÙÙÍÍÍÐÐÐÆÆÆÅÅÅØØØÑÑÑÑÑÑÒÒÒÊÊÊæææëëëóóóæææãããêêêëëëÝÝÝÛÛÛßßßÛÛÛÛÛÛßßßßßß×××ÌÌÌÇÇÇÍÍÍÕÕÕÔÔÔÒÒÒÎÎÎÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÇÇÇÆÆÆÌÌÌÍÍÍ¿¿¿»»»ÌÌÌÍÍÍÉÉÉÉÉÉÇÇÇÃÃÿ¿¿ÇÇÇÔÔÔÆÆÆÇÇÇÃÃþ¾¾¾¾¾ÂÂÂÆÆÆÆÆÆÆÆÆÊÊÊÌÌÌâââçççíííØØØÌÌÌÊÊÊÑÑÑØØØÝÝÝÛÛÛ±±±°°°¸¸¸»»»»»»»»»¼¼¼ÀÀÀ¼¼¼¸¸¸¿¿¿¿¿¿ÆÆÆÎÎÎÎÎÎÍÍÍÐÐÐØØØ···ººº¿¿¿ÃÃÃÅÅÅÅÅÅÃÃÃÅÅÅÂÂÂÊÊÊÒÒÒßßßèèèààà×××ØØØòòòïïïóóóçççÝÝÝÜÜÜÙÙÙâââÝÝÝÜÜÜÛÛÛÛÛÛÛÛÛØØØÑÑÑÌÌÌÔÔÔÙÙÙÐÐÐÐÐÐÅÅÅÅÅÅÂÂÂÜÜÜãããæææãããÙÙÙÕÕÕ×××ØØØØØØÐÐÐÒÒÒ××××××ÒÒÒÌÌÌÆÆÆÃÃÿ¿¿¼¼¼»»»¾¾¾¿¿¿¿¿¿ÆÆÆÍÍÍÇÇǼ¼¼µµµ»»»ÃÃÃÇÇÇÊÊÊÌÌÌÇÇÇÌÌÌÌÌÌÊÊÊÊÊÊÇÇÇ»»»¬¬¬­­­³³³»»»ÂÂÂÆÆÆÇÇÇÅÅÅÂÂÂÂÂÂÀÀÀÅÅÅÌÌÌÌÌÌÇÇÇÉÉÉÐÐÐÊÊÊÌÌÌÍÍÍâââÜÜÜÜÜÜÙÙÙçççüüüõõõóóóøøøøøøñññíííïïïÝÝÝÇÇÇÃÃÃÎÎÎÐÐÐÎÎÎÑÑÑÑÑÑÆÆÆÒÒÒÊÊÊÌÌÌÛÛÛ¼¼¼ÙÙÙÀÀÀÃÃÃÎÎÎÌÌÌÃÃÃÆÆÆÇÇÇÆÆÆÊÊÊÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÊÊÊÌÌÌÍÍÍÊÊÊÇÇÇÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾ººº¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÃÃÃÃÃÃÐÐÐÎÎÎÅÅÅÒÒÒÛÛÛÆÆÆÛÛÛÑÑÑÐÐÐÑÑѾ¾¾ÂÂÂçççòòòîîîäääÜÜÜßßßèèèñññëëëßßßØØØÒÒÒÒÒÒÙÙÙÜÜÜÒÒÒÇÇÇ»»»ÑÑÑÊÊÊÐÐÐÆÆÆÆÆÆÅÅÅÉÉÉÉÉÉÌÌÌÎÎÎÇÇǼ¼¼ÂÂÂÐÐÐÑÑÑÅÅÅÀÀÀ¿¿¿¿¿¿»»»¸¸¸ÀÀÀÍÍÍÊÊÊÂÂÂÀÀÀÆÆÆÌÌÌÊÊÊÊÊÊÍÍÍèèèâââßßßàààãããèèèëëëêêêäääàààÕÕÕÜÜÜäääÌÌ̯¯¯¯¯¯±±±µµµÀÀÀµµµ³³³···µµµÂÂÂÂÂÂÅÅÅÊÊÊÎÎÎÎÎÎÍÍÍÊÊÊàààÌÌÌ······Â¿¿¿»»»ÃÃÃÇÇÇÆÆÆÌÌÌÕÕÕ×××ÕÕÕÔÔÔÕÕÕñññíííêêêëëëçççàààßßßààààààÙÙÙÜÜÜÒÒÒ×××ÜÜÜÌÌÌÅÅÅÛÛÛÙÙÙÌÌÌÊÊÊÅÅÅÍÍÍÑÑÑâââäääçççæææßßßØØØÕÕÕÒÒÒÐÐÐÌÌÌÎÎÎÑÑÑÑÑÑÎÎÎÉÉÉÃÃÃÀÀÀ¿¿¿¿¿¿ÀÀÀ¿¿¿»»»¼¼¼ÂÂÂÑÑÑÇÇÇÀÀÀÅÅÅÉÉÉÊÊÊÉÉÉÇÇÇÊÊÊÍÍÍÎÎÎÍÍÍÊÊÊÃÃõµµ©©©­­­³³³»»»ÃÃÃÇÇÇÉÉÉÇÇÇÆÆÆÅÅÅÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÉÉÉÒÒÒ××××××ãããßßßæææçççïïïïïïëëëÿÿÿòòòÇÇÇÉÉÉãããàààÂÂÂÀÀÀÊÊÊÒÒÒÑÑÑÐÐÐÒÒÒÐÐÐÌÌÌÌÌÌÉÉÉÎÎÎÊÊÊ»»»ÕÕÕÍÍÍÇÇÇÎÎÎÊÊÊÂÂÂÆÆÆÇÇÇÆÆÆÊÊÊÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÊÊÊÌÌÌÌÌÌÉÉÉÆÆÆÂ¿¿¿¾¾¾¼¼¼¼¼¼ººº¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÆÆÆÂÂÂÊÊÊÎÎÎÍÍÍÔÔÔÕÕÕÆÆÆÛÛÛÝÝÝ××××××ÎÎÎÃÃÃÔÔÔæææíííëëëçççààààààæææçççäääïïïãããØØØØØØÛÛÛØØØÎÎÎÇÇǼ¼¼ÒÒÒÍÍÍÒÒÒÉÉÉÉÉÉÇÇÇÌÌÌÎÎÎÊÊÊÇÇÇÃÃÿ¿¿ÆÆÆÊÊʺººÆÆÆÍÍÍÍÍÍÐÐÐÕÕÕÑÑÑÆÆÆÌÌÌÆÆÆÅÅÅÍÍÍÙÙÙÝÝÝÜÜÜÙÙÙÝÝÝçççíííêêêææææææèèèêêêàààäääÛÛÛÙÙÙßßßÌÌ̱±±¬¬¬±±±¬¬¬­­­¯¯¯¬¬¬°°°···´´´ººº¼¼¼ÂÂÂÃÃÃÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÒÒÒÑÑÑÑÑÑÎÎμ¼¼ÆÆÆÂÂÂÇÇÇÐÐÐÔÔÔÐÐÐÍÍÍÕÕÕàààïïïçççæææïïïøøøöööîîîèèèÝÝÝÝÝÝãããÛÛÛ×××ØØØÊÊÊÆÆÆßßß×××ÊÊÊÆÆÆÂÂÂÔÔÔâââæææÛÛÛàààãããßßßÜÜÜÙÙÙÕÕÕÑÑÑÐÐÐÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÇÇÇÃÃÃÂÂÂÀÀÀÂÂÂÃÃÿ¿¿¸¸¸···ºººÂ¼¼¼¼¼¼ÅÅÅÍÍÍÎÎÎÎÎÎÎÎÎÒÒÒÑÑÑÑÑÑÐÐÐÊÊÊ¿¿¿···³³³±±±···¾¾¾ÃÃÃÉÉÉÊÊÊÊÊÊÉÉÉÆÆÆÊÊÊÊÊÊÅÅÅÆÆÆÍÍÍÎÎÎÊÊÊÜÜÜàààÝÝÝâââàààîîîòòòöööñññòòòÿÿÿëëëÀÀÀÀÀÀÑÑÑ¿¿¿ÅÅÅÎÎÎÐÐÐÍÍÍÒÒÒ×××ÒÒÒÐÐÐÇÇÇÌÌÌÒÒÒººº¼¼¼ÅÅÅÌÌÌÌÌÌÍÍÍÇÇÇÂÂÂÅÅÅÇÇÇÇÇÇÉÉÉÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÅÅÅ¿¿¿¼¼¼¼¼¼»»»¸¸¸¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÆÆÆÀÀÀÃÃÃÎÎÎÕÕÕÒÒÒÍÍÍÊÊÊ¿¿¿ØØØÐÐÐÐÐÐ×××ÇÇÇÆÆÆÔÔÔçççíííêêêßßßÛÛÛàààæææêêêïïïäää×××ÑÑÑ×××ÜÜÜ×××ÍÍÍ¿¿¿ÕÕÕÎÎÎÕÕÕÌÌÌÌÌÌÊÊÊÍÍÍÑÑÑÉÉÉÆÆÆÅÅÅÃÃÃÉÉÉÇÇǾ¾¾ÊÊÊÍÍÍÇÇÇÀÀÀÅÅÅÐÐÐÎÎÎÃÃÃÀÀÀÆÆÆÍÍÍ×××àààççççççâââæææííííííçççæææèèèèèèçççÝÝÝçççâââÜÜÜäääßßßÑÑÑÍÍÍÊÊʵµµªªª¯¯¯»»»ÆÆÆÅÅÅ···±±±¸¸¸ÀÀÀÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÌÌÌÒÒÒÕÕÕÙÙÙßßß×××ÇÇÇÂÂÂÂÂÂÇÇÇÐÐÐÔÔÔÔÔÔÔÔÔÝÝÝêêêçççÝÝÝÙÙÙâââñññúúúüüüúúúüüüóóóîîîàààØØØÕÕÕÉÉÉÅÅÅ×××ÒÒÒÌÌÌÇÇǾ¾¾ÑÑÑêêêãããÙÙÙÝÝÝßßßÛÛÛÙÙÙÙÙÙØØØÒÒÒÑÑÑÐÐÐÐÐÐÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆ¿¿¿¿¿¿ÀÀÀÃÃü¼¼»»»¿¿¿¾¾¾¼¼¼¿¿¿ÉÉÉÎÎÎÎÎÎÌÌÌÍÍÍÒÒÒÍÍÍÊÊÊÉÉÉÃÃúºº¸¸¸¾¾¾ººº¼¼¼ÀÀÀÆÆÆÉÉÉÊÊÊÊÊÊÊÊÊÅÅÅÇÇÇÇÇÇÇÇÇÍÍÍÕÕÕØØØ×××àààßßßÝÝÝâââæææïïïõõõùùùüüüüüüçççÎÎÎÌÌÌÑÑÑÍÍÍÉÉÉÑÑÑÐÐÐÐÐÐÐÐÐÒÒÒ×××ÕÕÕÐÐÐÒÒÒÌÌÌÒÒÒ×××»»»ÐÐо¾¾ÍÍÍÑÑÑÍÍÍÅÅÅÂÂÂÅÅÅÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼»»»ººº¸¸¸¸¸¸¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÆÆÆÂÂÂÀÀÀÍÍÍ×××ÍÍÍÇÇÇÒÒÒÃÃÃÜÜÜÛÛÛØØØÙÙÙÐÐÐÇÇÇÀÀÀäääíííèèèÜÜÜÛÛÛßßßàààããããããàààÙÙÙÔÔÔ×××ÜÜÜØØØÎÎÎÀÀÀ×××ÐÐÐÕÕÕÌÌÌÌÌÌÊÊÊÎÎÎÐÐÐÊÊÊÌÌÌÊÊÊÃÃÃÆÆÆÊÊÊÆÆÆÊÊÊÀÀÀ¾¾¾ÃÃÃÅÅÅ¿¿¿¼¼¼¾¾¾ÊÊÊÙÙÙäääãããÝÝÝÝÝÝßßßÝÝÝâââäääãããæææëëëèèèãããäääíííòòòêêêâââæææäääàààãããÛÛÛÑÑÑÐÐÐÎÎÎÌÌÌÎÎÎÒÒÒÍÍͰ°°µµµººº¾¾¾ÅÅÅÊÊÊÌÌÌÉÉÉÊÊÊÍÍÍÇÇÇÍÍÍßßßäääÕÕÕÉÉÉÉÉÉÉÉÉÊÊÊ××׿ææèèèæææèèèÜÜÜ×××ÒÒÒÔÔÔÜÜÜæææîîîòòòëëëäääâââãããèèèæææÕÕÕÇÇÇÉÉÉÍÍÍÐÐÐÊÊʼ¼¼ÇÇÇçççÜÜÜààààààÜÜÜÔÔÔÑÑÑÒÒÒÑÑÑÎÎÎÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀÃÃÿ¿¿ÂÂÂÆÆÆÃÃÃÃÃÃÇÇÇÑÑÑÔÔÔÑÑÑÎÎÎÐÐÐÅÅÅÂÂÂÂÂÂÃÃÿ¿¿ººº»»»ÂÂÂÂÂÂÃÃÃÅÅÅÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅÉÉÉÑÑÑ×××ÙÙÙÝÝÝããããããÛÛÛÜÜÜçççïïïïïïóóóúúúîîîäääÎÎÎÅÅÅÐÐÐ×××ÕÕÕÙÙÙÕÕÕÒÒÒÔÔÔØØØÛÛÛÕÕÕÍÍÍÌÌÌÊÊÊÊÊÊÇÇÇÃÃü¼¼ØØØ¸¸¸ÇÇÇÔÔÔÌÌÌÅÅÅÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÇÇÇÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿¼¼¼»»»ººº¸¸¸¸¸¸···¸¸¸ººº»»»¾¾¾¿¿¿ÃÃÃÅÅÅÂÂÂÉÉÉÑÑÑÇÇÇÆÆÆÛÛÛÌÌÌÐÐÐ×××ßßß×××ÐÐÐÐÐм¼¼ÛÛÛíííëëëßßßÜÜÜÜÜÜØØØÛÛÛâââçççæææÝÝÝ××××××ÕÕÕÑÑÑÀÀÀ×××ÑÑÑ×××ÍÍÍÍÍÍÌÌÌÎÎÎÑÑÑÊÊÊÊÊÊÉÉÉÂÂÂÂÂÂÇÇÇÇÇÇÉÉÉÂÂÂÉÉÉÛÛÛßßßÒÒÒÑÑÑÜÜÜÒÒÒÛÛÛÙÙÙÊÊÊ»»»···¸¸¸ºººÅÅÅÎÎÎÜÜÜîîîõõõæææÜÜÜæææííííííæææâââàààÛÛÛÙÙÙàààâââÝÝÝàààÜÜÜÒÒÒÒÒÒÙÙÙÙÙÙ××××××ÍÍÍ¿¿¿···ººº¿¿¿ÂÂÂÃÃÃÍÍÍÌÌÌÊÊÊÕÕÕÝÝÝÝÝÝÜÜÜÍÍÍÍÍÍÌÌÌÛÛÛïïïîîîßßßÛÛÛÕÕÕÕÕÕÕÕÕ×××ÛÛÛÝÝÝÝÝÝÜÜÜ×××ÒÒÒÎÎÎ×××àààßßßØØØÎÎÎÀÀÀÍÍÍÒÒÒÍÍ;¾¾¿¿¿ãããÙÙÙÝÝÝÜÜÜÕÕÕÎÎÎÍÍÍÐÐÐÐÐÐÍÍÍÅÅÅÇÇÇÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÆÆÆÃÃÃÃÃÃÅÅÅÃÃÃÀÀÀÃÃÃÊÊÊÃÃÃÃÃÃÉÉÉÐÐÐÐÐÐÌÌÌÊÊÊÍÍÍÀÀÀÃÃÃÇÇÇÍÍÍÌÌÌÇÇÇÇÇÇÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÊÊÊÉÉÉÐÐÐÛÛÛÝÝÝÛÛÛÝÝÝäääæææÙÙÙßßßíííúúúóóóöööúúúêêêÍÍÍÉÉÉÔÔÔÒÒÒØØØÝÝÝÒÒÒÑÑÑÒÒÒÒÒÒÔÔÔÔÔÔÎÎÎÍÍÍÕÕÕÕÕÕÎÎÎÀÀÀ···ÀÀÀÐÐеµµÀÀÀÕÕÕÊÊÊÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¼¼¼»»»ººº¸¸¸·········¸¸¸»»»¾¾¾¿¿¿ÂÂÂÆÆÆÃÃÃÅÅÅÊÊÊÇÇÇÊÊÊÙÙÙÎÎξ¾¾ÅÅÅÛÛÛÒÒÒÊÊÊÔÔÔÆÆÆÂÂÂâââíííãããààààààßßßæææßßßääääääÝÝÝÔÔÔÑÑÑÕÕÕØØØÂÂÂØØØÑÑÑØØØÍÍÍÎÎÎÌÌÌÐÐÐÒÒÒÇÇÇÅÅÅÆÆÆÂÂÂÂÂÂÆÆÆÃÃÃØØØÔÔÔÐÐÐÍÍÍÉÉÉÃÃÃÃÃÃÉÉÉâââÛÛÛÌÌ̾¾¾···»»»¿¿¿Â¼¼¼ÂÂÂÉÉÉßßßõõõîîîäääíííääääääãããäääààà×××ÒÒÒ××׿ææÛÛÛØØØÙÙÙÙÙÙßßßãããÝÝÝàààçççãããÐÐо¾¾»»»¾¾¾¿¿¿ÀÀÀÎÎÎÑÑÑÎÎÎÔÔÔÙÙÙÝÝÝäääÇÇÇÐÐÐÒÒÒÝÝÝëëëâââÑÑÑÑÑÑ×××ÕÕÕÕÕÕÛÛÛäääíííêêêâââçççãããÕÕÕÒÒÒÎÎÎÉÉÉÐÐÐÑÑÑÂÂÂÎÎÎÑÑÑÌÌ̼¼¼ãããÝÝÝÕÕÕÕÕÕÑÑÑÍÍÍÍÍÍÐÐÐÍÍÍÇÇÇÂÂÂÇÇÇÌÌÌÊÊÊÆÆÆÂÂÂÃÃÃÆÆÆÅÅÅÂÂÂÂÂÂÅÅÅÃÃÃÂÂÂÆÆÆÌÌÌÍÍÍÌÌÌÍÍÍÍÍÍÇÇǾ¾¾»»»¾¾¾ÇÇÇÌÌÌÐÐÐÐÐÐÐÐÐÒÒÒÒÒÒÑÑÑÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÊÊÊÌÌÌÆÆÆÍÍÍØØØßßßßßßÜÜÜÝÝÝâââãããÛÛÛãããêêêüüüøøøúúúøøøëëëÐÐÐÊÊÊÒÒÒÒÒÒ×××ÛÛÛÒÒÒÐÐÐÕÕÕÑÑÑÌÌÌÑÑÑÔÔÔÕÕÕÛÛÛâââÑÑÑÆÆÆÂÂÂÕÕÕÊÊÊÅÅÅÉÉÉÕÕÕÉÉÉÇÇÇÊÊÊÅÅÅÃÃÃÅÅÅ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÿ¿¿¾¾¾»»»ººº············¸¸¸»»»¾¾¾¿¿¿ÀÀÀÅÅÅÃÃÃÀÀÀÇÇÇÐÐÐÑÑÑÐÐÐÛÛÛÔÔÔÊÊÊÑÑÑÒÒÒÎÎÎÑÑÑÇÇǵµµÙÙÙçççãããèèèëëëèèèîîîàààââââââßßßØØØÒÒÒÔÔÔÛÛÛÅÅÅÛÛÛÔÔÔÙÙÙÐÐÐÐÐÐÎÎÎÒÒÒÌÌÌÅÅÅÉÉÉÌÌÌÆÆÆÆÆÆÌÌÌÎÎÎÔÔÔ×××ÔÔÔÐÐÐÐÐÐÒÒÒÍÍÍÅÅÅÆÆÆ¼¼¼³³³³³³···¾¾¾ÅÅÅÊÊÊÍÍÍÊÊÊ¿¿¿ÉÉÉêêêöööîîîëëëèèèêêêèèèâââÙÙÙÕÕÕÑÑÑÍÍÍØØØÙÙÙâââãããÛÛÛÝÝÝæææçççàààèèèëëëâââØØØÎÎο¿¿°°°¿¿¿ÉÉÉÌÌÌÍÍÍ×××ÛÛÛÝÝÝäääÂÂÂÐÐÐÕÕÕÜÜÜäääÙÙÙÍÍÍ×××ØØØÛÛÛÝÝÝâââêêêóóóòòòíííäääçççàààãããÛÛÛÍÍÍÐÐÐÎÎÎÉÉÉÑÑÑÎÎÎÇÇÇÆÆÆ¿¿¿æææãããÕÕÕ×××ÔÔÔÐÐÐÍÍÍÌÌÌÅÅÅ»»»ºººÀÀÀÇÇÇÆÆÆÀÀÀ¼¼¼¾¾¾Â¿¿¿¾¾¾ÀÀÀÅÅÅÅÅÅÅÅÅÇÇÇÎÎÎÌÌÌÊÊÊÍÍÍÎÎÎÊÊÊÃÃÃÅÅÅÉÉÉÌÌÌÍÍÍÊÊÊÅÅÅÅÅÅÍÍÍÑÑÑÐÐÐÌÌÌÊÊÊÇÇÇÆÆÆÇÇÇÉÉÉÌÌÌÍÍ;¾¾ÎÎÎÜÜÜßßßÝÝÝààààààßßßÝÝÝÛÛÛããããããøøøøøøüüüñññÆÆÆÐÐÐÍÍÍÐÐÐÝÝÝÕÕÕÌÌÌ×××ÎÎÎØØØÒÒÒÎÎÎÜÜÜæææÛÛÛÐÐÐÍÍ͵µµ···ÃÃÃÛÛÛ¼¼¼ÊÊÊÊÊÊÕÕÕÉÉÉÉÉÉÌÌÌÅÅÅÂÂÂÃÃÃÀÀÀ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¾¾¾»»»ººº············¸¸¸»»»¾¾¾¿¿¿ÂÂÂÃÃÃÀÀÀ¾¾¾ÇÇÇ×××ÕÕÕÇÇÇÉÉÉÛÛÛÅÅŸ¸¸ÌÌÌÕÕÕÑÑÑÆÆÆÀÀÀÝÝÝæææâââïïïóóóèèèæææïïïíííííííííæææØØØÒÒÒÔÔÔÆÆÆÜÜÜ×××ÜÜÜÒÒÒÒÒÒÑÑÑÕÕÕ¿¿¿ÃÃÃÒÒÒØØØÌÌÌÉÉÉ×××ãããÎÎÎÎÎÎÉÉÉÅÅÅÆÆÆÆÆÆººº¨¨¨¬¬¬©©©­­­µµµººº»»»ÀÀÀÉÉÉÐÐÐØØØÌÌÌÇÇÇãããõõõíííæææÝÝÝâââßßßÒÒÒÎÎÎÙÙÙÝÝÝ×××ÎÎÎÔÔÔâââèèèâââßßßàààÝÝÝ×××ÙÙÙÛÛÛßßßêêêëëëÔÔÔ¸¸¸···ÀÀÀÆÆÆÊÊÊÒÒÒ×××ÝÝÝêêêÀÀÀÎÎÎÒÒÒØØØäääÜÜÜÕÕÕàààÕÕÕäääññññññîîîêêêäääßßßæææäääÛÛÛâââßßßÐÐÐÑÑÑÊÊÊàààÌÌÌÍÍÍÊÊÊÇÇÇÔÔÔÛÛÛæææÔÔÔÜÜÜÒÒÒÔÔÔÙÙÙÎÎÎÅÅż¼¼ÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÃÃÃÀÀÀ»»»¿¿¿ÉÉÉÉÉÉÇÇÇÎÎÎÍÍÍÌÌÌÎÎÎÌÌÌ¿¿¿µµµ»»»ÆÆÆÍÍÍÑÑÑÐÐÐÉÉÉÇÇÇÌÌÌÐÐÐÐÐÐÑÑÑÌÌÌÍÍÍÃÃÃÊÊÊÅÅÅÍÍÍÌÌÌëëëãããÜÜÜÜÜÜàààãããàààÛÛÛßßßæææâââñññòòòóóóÿÿÿäääÍÍÍÑÑÑ×××ÙÙÙ×××ÒÒÒÎÎÎÌÌÌÐÐÐÌÌÌÉÉÉÔÔÔÊÊÊØØØ°°°¼¼¼···µµµÆÆÆÝÝÝÆÆÆºººÐÐÐÆÆÆÝÝÝÐÐÐÅÅÅÃÃÃÅÅÅÆÆÆÅÅÅ¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾ººº¸¸¸¸¸¸ººº»»»¼¼¼¾¾¾¾¾¾ÀÀÀÅÅÅÂÂÂÆÆÆÉÉÉÒÒÒÜÜÜÌÌÌÕÕÕÉÉÉÉÉɾ¾¾ÒÒÒÎÎÎÇÇÇÊÊÊÀÀÀ···°°°±±±¼¼¼ÍÍÍãããõõõòòòõõõïïïïïïâââßßßÑÑÑÕÕÕÊÊÊÛÛÛßßßÛÛÛÜÜÜØØØÒÒÒÔÔÔÅÅÅÃÃÃÉÉÉÃÃÃÃÃÃàààêêêÎÎγ³³ÅÅÅ···°°°©©©µµµ¯¯¯¬¬¬±±±°°°­­­°°°´´´ººº¿¿¿ÆÆÆÒÒÒÑÑÑÃÃÃÍÍÍæææööööööÜÜÜäääÜÜÜØØØÛÛÛÜÜÜÙÙÙØØØÛÛÛÒÒÒÙÙÙçççÜÜÜÜÜÜæææÙÙÙÒÒÒçççêêêèèèääääääçççäääÝÝݸ¸¸···¿¿¿ÍÍÍÑÑÑÒÒÒÜÜÜêêê¿¿¿ÊÊÊÑÑÑÜÜÜíííëëëßßßÛÛÛßßßëëëïïïçççäääèèèæææÝÝÝçççÝÝÝâââÕÕÕØØØÒÒÒ×××ÆÆÆÔÔÔÉÉÉÀÀÀ¸¸¸ÂÂÂÙÙÙÜÜÜÒÒÒÍÍÍÙÙÙÑÑÑÑÑÑÎÎÎÂÂÂÀÀÀÀÀÀÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÆÆÆÅÅÅ¿¿¿ÅÅÅÎÎÎÌÌÌÇÇÇÍÍÍÌÌÌÎÎÎÎÎÎÉÉÉ¿¿¿ººº¿¿¿ÉÉÉÎÎÎÑÑÑÐÐÐÉÉÉÇÇÇÊÊÊÎÎÎÎÎÎÊÊÊÆÆÆÉÉÉÂÂÂÍÍÍÍÍÍÜÜÜàààãããßßßÜÜÜÝÝÝãããäääâââÝÝÝããããããßßßïïïïïïòòòóóóÇÇÇÍÍÍÑÑÑ×××ØØØÕÕÕÒÒÒÐÐÐÎÎÎÐÐÐÍÍÍÌÌÌÒÒÒÍÍÍÛÛÛµµµ¾¾¾¿¿¿¸¸¸ÆÆÆÒÒÒÆÆÆÆÆÆÑÑÑÀÀÀ×××ÔÔÔÊÊÊÃÃÃÂÂÂÀÀÀ»»»¸¸¸¾¾¾¼¼¼¼¼¼»»»¼¼¼¾¾¾ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿ºººººººººººº»»»¼¼¼¾¾¾¿¿¿ÅÅÅÉÉÉÅÅÅÇÇÇÉÉÉÐÐÐ×××ÆÆÆÒÒÒÌÌÌÐÐÐÅÅÅÒÒÒÍÍÍÆÆÆÆÆÆÂ¼¼¼¸¸¸»»»¾¾¾ÀÀÀÇÇÇÐÐÐèèèóóóöööòòòäääèèèãããÝÝÝÒÒÒØØØßßßâââàààßßß×××ÌÌÌÊÊÊÌÌÌÔÔÔÔÔÔÔÔÔßßßÕÕÕ´´´¦¦¦­­­©©©¯¯¯ŸŸŸ¥¥¥¥¥¥ªªª°°°¯¯¯¯¯¯¯¯¯³³³···¼¼¼ÀÀÀÃÃÃÂÂÂÊÊÊäääõõõïïïèèèâââÜÜÜÝÝÝÛÛÛÕÕÕÕÕÕØØØÕÕÕÎÎÎÑÑÑÕÕÕßßßØØØØØØßßß×××ÕÕÕÔÔÔÕÕÕÔÔÔÕÕÕÝÝÝæææçççãããÐÐо¾¾µµµÂÂÂÎÎÎÔÔÔßßßîîîÊÊÊÊÊÊÑÑÑßßßèèèêêêäääÝÝÝßßßèèèîîîîîîîîîñññíííæææâââØØØØØØÎÎÎÐÐÐÐÐÐØØØÌÌÌÌÌÌÊÊʼ¼¼¾¾¾ÐÐÐßßßßßßÎÎÎÐÐÐØØØÐÐÐÐÐÐÍÍÍÃÃÃÇÇÇÊÊÊÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÉÉÉÉÉÉÅÅÅÉÉÉÑÑÑÎÎÎÉÉÉÌÌÌÍÍÍÑÑÑÐÐÐÆÆÆÀÀÀ¿¿¿ÅÅÅÌÌÌÐÐÐÑÑÑÐÐÐÉÉÉÇÇÇÊÊÊÍÍÍÍÍÍÌÌÌÊÊÊÑÑÑÊÊÊÒÒÒÑÑÑßßßâââÝÝÝÝÝÝÝÝÝàààããããããàààßßßââââââæææõõõóóóøøøóóó¿¿¿ÎÎÎÑÑÑÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÐÐÐÎÎÎÑÑÑÐÐÐÛÛÛ¼¼¼¿¿¿Â¾¾¾ÎÎÎÉÉÉÃÃÃÎÎÎÑÑÑ¿¿¿¿¿¿ÍÍÍÊÊÊ¿¿¿Â¼¼¼¿¿¿¼¼¼»»»»»»»»»»»»¼¼¼¿¿¿ÀÀÀÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÀÀÀ¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÅÅÅÇÇÇÆÆÆÊÊÊÊÊÊÎÎÎÕÕÕÅÅÅÑÑÑÊÊÊÐÐÐÃÃÃÒÒÒÒÒÒÎÎÎÍÍÍÀÀÀ¾¾¾¿¿¿Â¾¾¾¼¼¼¾¾¾ÀÀÀ×××îîîîîîàààããããããÎÎÎÛÛÛÔÔÔÙÙÙßßßÜÜÜÝÝÝ×××ÃÃÃÐÐÐÌÌÌÅÅÅÃÃÃÎÎÎÝÝÝÝÝÝÒÒÒ¯¯¯©©©¯¯¯¼¼¼©©©¨¨¨©©©···±±±±±±±±±°°°±±±¸¸¸¾¾¾¾¾¾¿¿¿ÉÉÉàààòòòóóóêêêÝÝÝßßßßßßâââàààÛÛÛØØØØØØÒÒÒÊÊÊÍÍÍÎÎÎ×××ÔÔÔÔÔÔ×××ÔÔÔØØØØØØ×××ÒÒÒÔÔÔÜÜÜæææêêêçççíííÑÑÑ»»»¾¾¾ÌÌÌÒÒÒØØØâââ×××ÊÊÊÐÐÐÝÝÝàààäääêêêäää×××ÜÜÜæææîîîòòòñññíííèèèÝÝÝÝÝÝàààÒÒÒÍÍÍÌÌÌÛÛÛÛÛÛÅÅÅÃÃþ¾¾ÔÔÔäääÛÛÛÙÙÙ×××ÔÔÔÒÒÒÉÉÉÍÍÍÎÎÎÉÉÉÌÌÌÊÊÊÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÉÉÉÊÊÊÊÊÊÌÌÌÆÆÆÇÇÇÐÐÐÎÎÎÉÉÉÌÌÌÎÎÎ×××ÑÑÑÅÅÅÂÂÂÅÅÅÇÇÇÍÍÍÎÎÎÐÐÐÎÎÎÉÉÉÉÉÉÍÍÍÎÎÎÍÍÍÊÊÊÎÎÎÜÜÜØØØÝÝÝÔÔÔØØØ×××ßßßßßßàààââââââàààßßßÝÝÝÜÜÜàààîîîùùùñññõõõóóóÃÃÃÍÍÍÐÐÐÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÑÑÑÍÍÍÑÑÑÕÕÕ¾¾¾»»»¼¼¼ÂÂÂÜÜÜÅÅÅ¿¿¿ÐÐÐÎÎÎÀÀÀ¸¸¸ÒÒÒÑÑÑÀÀÀÀÀÀ¼¼¼µµµ»»»»»»»»»ººººººººº¼¼¼¾¾¾¿¿¿ÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀ¿¿¿ÅÅÅÅÅÅÌÌÌÌÌÌÐÐÐ×××ÉÉÉÒÒÒÇÇÇÇÇÇ´´´ÂÂÂÉÉÉÉÉÉÅÅÅÊÊÊÆÆÆÆÆÆÉÉÉÉÉÉÅÅÅÅÅÅÇÇÇ···ÊÊÊçççñññãããàààèèèÕÕÕÝÝÝÔÔÔÑÑÑÑÑÑÑÑÑÒÒÒÎÎÎÃÃÃÔÔÔÑÑÑÃÃÃÂÂÂÐÐÐ×××ØØØÝÝÝÑÑÑÉÉÉÇÇÇÐÐо¾¾´´´¦¦¦´´´³³³±±±¯¯¯¨¨¨¥¥¥°°°¸¸¸´´´ßßßçççúúúöööîîîëëëâââäääæææâââßßßàààÛÛÛÑÑÑÌÌÌÍÍÍÊÊÊÉÉÉÐÐÐÔÔÔÔÔÔÑÑÑÒÒÒÙÙÙÛÛÛÙÙÙÕÕÕÒÒÒÒÒÒØØØßßßãããñññãããÍÍÍÅÅÅÌÌÌÒÒÒÒÒÒÕÕÕÝÝÝÎÎÎÌÌÌÔÔÔØØØßßßèèèîîîæææßßßÜÜÜàààâââßßßÝÝÝßßßÜÜÜÕÕÕÎÎÎÆÆÆÉÉÉÍÍÍÍÍÍÅÅÅ¿¿¿µµµ´´´×××äääÔÔÔÒÒÒÕÕÕÒÒÒÎÎÎÅÅÅÉÉÉÆÆÆ¾¾¾ÃÃÃÀÀÀÉÉÉÇÇÇÅÅÅÂÂÂÂÂÂÅÅÅÇÇÇÉÉÉÊÊÊÊÊÊÃÃÃÀÀÀÉÉÉÌÌÌÉÉÉÌÌÌÑÑÑÙÙÙÑÑÑÅÅÅÆÆÆÉÉÉÉÉÉÎÎÎÍÍÍÐÐÐÎÎÎÊÊÊÊÊÊÐÐÐÐÐÐÍÍÍÆÆÆÍÍÍÝÝÝÜÜÜâââ×××ÙÙÙ×××ßßßßßßàààààààààßßßàààâââßßßàààíííòòòèèèíííççç¾¾¾ÊÊÊÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÔÔÔÑÑÑÑÑÑÊÊÊÑÑÑÊÊʺºº···»»»ÂÂÂàààÀÀÀÃÃÃÑÑÑÊÊÊ¿¿¿¸¸¸ÒÒÒÒÒÒ¾¾¾···¾¾¾»»»»»»ººººººººº»»»¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀ¿¿¿ÃÃÃÅÅÅÌÌÌÌÌÌÎÎÎ×××ÌÌÌÇÇÇÆÆÆÎÎθ¸¸¾¾¾ÇÇÇÑÑÑÑÑÑÙÙÙÔÔÔÐÐÐÐÐÐÎÎÎÊÊÊÌÌÌÎÎÎÊÊÊÍÍÍÙÙÙîîîàààÝÝÝïïïëëëÙÙÙÙÙÙÒÒÒÎÎÎÐÐÐÊÊÊÅÅÅÇÇÇÔÔÔÕÕÕÎÎÎÍÍÍÔÔÔÐÐÐÌÌÌ×××××××××ÎÎÎÐÐÐÍÍÍÆÆÆ¦¦¦±±±±±±±±±´´´±±±µµµÎÎÎâââßßßîîîêêêñññèèèââââââÜÜÜäääâââÜÜÜØØØ×××ÑÑÑÉÉÉÆÆÆÊÊÊÉÉÉÇÇÇÌÌÌÕÕÕ×××ÐÐÐÒÒÒØØØÕÕÕ×××ØØØÔÔÔÎÎÎÑÑÑÝÝÝèèèàààêêêÝÝÝÉÉÉÊÊÊÔÔÔ×××ÙÙÙÛÛÛÔÔÔÉÉÉÇÇÇÐÐÐ×××ãããóóóõõõêêêãããäääçççèèèîîîøøøÜÜÜÜÜÜÔÔÔÑÑÑÑÑÑÔÔÔÌÌÌÅÅÅÀÀÀ±±±´´´ÎÎÎÛÛÛÙÙÙÙÙÙÑÑÑÕÕÕÒÒÒÍÍÍÎÎο¿¿³³³¾¾¾ÂÂÂÐÐÐÍÍÍÉÉÉÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÆÆÆÇÇǾ¾¾ºººÃÃÃÊÊÊÊÊÊÍÍÍÒÒÒØØØÎÎÎÆÆÆÌÌÌÌÌÌÉÉÉÑÑÑÐÐÐÑÑÑÎÎÎÌÌÌÍÍÍÑÑÑÑÑÑÍÍÍÐÐÐÑÑÑÜÜÜ×××ÝÝÝÕÕÕÛÛÛÙÙÙÛÛÛÜÜÜÝÝÝàààâââãããæææçççäääàààçççîîîîîîïïïàà྾¾ÅÅÅÇÇÇÌÌÌÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÒÒÒÎÎÎÑÑÑÇÇÇÑÑѾ¾¾···µµµ¼¼¼¿¿¿ØØØ»»»ÊÊÊÑÑÑÇÇǼ¼¼»»»ÍÍÍÌÌÌÂÂÂÂÂÂÀÀÀ¾¾¾ÅÅÅ»»»»»»ººººººººº¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÅÅÅÅÅÅÍÍÍÌÌÌÌÌÌÔÔÔÌÌ̼¼¼ÉÉÉÝÝÝÃÃû»»ÀÀÀÐÐÐÒÒÒØØØÔÔÔÒÒÒÔÔÔÒÒÒÎÎÎÎÎÎÑÑÑÐÐÐÊÊÊÆÆÆíííâââÜÜÜæææêêêØØØÝÝÝÛÛÛØØØØØØÍÍÍÃÃÃÊÊÊÒÒÒÔÔÔÍÍÍÌÌÌÑÑÑÎÎÎÎÎÎÛÛÛÐÐÐÕÕÕÐÐÐÎÎÎÕÕÕÒÒÒ¨¨¨°°°±±±±±±³³³¬¬¬­­­ÊÊÊàààÙÙÙãããâââàààÙÙÙÛÛÛãããßßßÛÛÛÛÛÛÝÝÝÙÙÙÐÐÐÊÊÊÌÌÌÍÍÍÊÊÊÉÉÉÊÊÊÉÉÉÔÔÔ×××ÒÒÒ××××××ÕÕÕØØØÛÛÛØØØÑÑÑÐÐÐÜÜÜêêêßßßîîîàààÆÆÆÅÅÅÐÐÐÔÔÔÙÙÙ×××ØØØÌÌÌÂÂÂÉÉÉÑÑÑÛÛÛíííúúúöööóóóõõõïïïæææÝÝÝÝÝÝÅÅÅÔÔÔÕÕÕÑÑÑÃÃÃÀÀÀ¾¾¾ÃÃþ¾¾±±±ÃÃÃÔÔÔÕÕÕààààààÑÑÑ×××ÑÑÑÌÌÌÍÍÍ¿¿¿´´´ÅÅÅÌÌÌÍÍÍÌÌÌÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÀÀÀÂÂÂÃÃû»»···ÀÀÀÊÊÊÌÌÌÎÎÎÐÐÐÔÔÔÊÊÊÇÇÇÑÑÑÎÎÎÊÊÊÕÕÕÔÔÔÔÔÔÑÑÑÎÎÎÎÎÎÑÑÑÎÎÎÊÊÊÜÜÜÙÙÙÝÝÝÕÕÕÛÛÛÔÔÔÙÙÙØØØÙÙÙÛÛÛßßßâââæææççççççæææäääãããêêêòòòóóóëëëÔÔÔ¾¾¾ÀÀÀÃÃÃÇÇÇÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÑÑÑÊÊÊÑÑÑÉÉÉÔÔÔ´´´µµµ¸¸¸¼¼¼¾¾¾ÒÒÒºººÍÍÍÇÇÇÃÃÃÂÂÂÎÎÎÎÎÎÉÉɾ¾¾¼¼¼»»»¼¼¼¼¼¼»»»ºººººº»»»¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿ÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÃÃÃÌÌÌÊÊÊÊÊÊÕÕÕÎÎÎÀÀÀÌÌÌßßß¿¿¿°°°´´´¿¿¿»»»ÒÒÒÐÐÐÑÑÑÔÔÔÕÕÕÒÒÒÒÒÒÕÕÕÒÒÒÑÑÑÂÂÂøøøñññëëëãããæææßßßÝÝÝÝÝÝÝÝÝÛÛÛÑÑÑÊÊÊÌÌÌ×××ÔÔÔÎÎÎÐÐÐÔÔÔÑÑÑÌÌÌÌÌÌ×××ÙÙÙÙÙÙÙÙÙØØØÐÐС¡¡©©©°°°±±±´´´¯¯¯°°°ÑÑÑêêêàààãããçççâââßßßäääêêêçççØØØØØØÛÛÛØØØÐÐÐÌÌÌÎÎÎÑÑÑÐÐÐÌÌÌÍÍÍÆÆÆÐÐÐÕÕÕÒÒÒÙÙÙÕÕÕÕÕÕÕÕÕ×××ÕÕÕÑÑÑÎÎÎ×××àààæææêêêÔÔÔÀÀÀÆÆÆÌÌÌÊÊÊÑÑÑÒÒÒÙÙÙ×××ÉÉÉÅÅÅÌÌÌ×××ßßß×××ÛÛÛàààäääàààØØØÑÑÑÎÎÎÒÒÒÜÜÜÑÑÑÎÎÎÆÆÆÉÉɾ¾¾ÀÀÀ³³³ªªªÐÐÐàààÔÔÔÛÛÛÜÜÜÑÑÑÑÑÑÅÅÅ»»»Â»»»¸¸¸ÉÉÉÍÍÍÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÆÆÆÅÅÅÃÃÿ¿¿ÂºººµµµÂÂÂÌÌÌÎÎÎÐÐÐÍÍÍÐÐÐÇÇÇÉÉÉÕÕÕÑÑÑÌÌÌÙÙÙØØØØØØÔÔÔÐÐÐÎÎÎÐÐÐÍÍÍÇÇÇÝÝÝÙÙÙÝÝÝÕÕÕÝÝÝ×××ÜÜÜÙÙÙÜÜÜÝÝÝâââæææèèèçççäääàààßßßçççñññóóóîîî×××»»»°°°¾¾¾ÂÂÂÆÆÆÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÑÑÑÉÉÉÐÐÐÉÉÉÕÕÕ°°°µµµ¾¾¾¸¸¸¿¿¿ÒÒÒ»»»ÊÊÊ»»»ÂÂÂÌÌÌÑÑÑÇÇÇÀÀÀ¿¿¿¼¼¼¾¾¾ÀÀÀ¿¿¿¼¼¼»»»»»»ººº»»»¼¼¼¿¿¿ÀÀÀ¾¾¾¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀ¾¾¾¿¿¿ÀÀÀÊÊÊÊÊÊÍÍÍÙÙÙÕÕÕÇÇÇÊÊÊØØØ¼¼¼¼¼¼ÌÌÌØØØÎÎÎØØØÔÔÔÑÑÑÒÒÒÒÒÒÐÐÐÒÒÒ×××ØØØÙÙÙ¼¼¼öööòòòóóóäääçççèèèÛÛÛÙÙÙÜÜÜÕÕÕÒÒÒÑÑÑÌÌÌÙÙÙÐÐÐÉÉÉÊÊÊÒÒÒ×××ÒÒÒÌÌÌÉÉÉÇÇÇÕÕÕßßßØØØÐÐШ¨¨³³³­­­°°°µµµ¯¯¯°°°ÔÔÔëëëàààçççßßßÔÔÔãããæææÕÕÕÒÒÒÍÍÍÒÒÒÎÎÎÎÎÎÎÎÎÌÌÌÆÆÆÉÉÉÐÐÐÎÎÎÎÎÎÃÃÃÊÊÊÑÑÑÒÒÒÜÜÜÔÔÔÛÛÛØØØØØØÜÜÜßßßßßßãããèèèäääÜÜÜÃÃü¼¼ÍÍÍÐÐÐÇÇÇÎÎÎÑÑÑÙÙÙßßßÒÒÒÂÂÂÉÉÉÕÕÕÒÒÒ××××××ÕÕÕÔÔÔÕÕÕÜÜÜæææíííØØØßßßÎÎÎÇÇǾ¾¾ÀÀÀµµµ»»»°°°­­­ÑÑÑØØØÔÔÔàààÔÔÔÊÊÊÀÀÀÉÉÉÉÉÉ»»»ÅÅÅÐÐÐÇÇÇÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÆÆÆÅÅÅÃÃÃÅÅÅÆÆÆ»»»´´´¸¸¸ÇÇÇÐÐÐÇÇÇ»»»ÀÀÀÂÂÂÉÉÉÒÒÒ×××ÔÔÔÒÒÒÕÕÕÕÕÕÕÕÕÎÎÎÔÔÔÒÒÒÉÉÉÊÊÊÆÆÆÙÙÙÝÝÝââââââàààÝÝÝÜÜÜÜÜÜàààâââãããææææææääääääæææßßßøøøòòòñññêêêÝÝݼ¼¼ººº¼¼¼ÂÂÂÇÇÇÇÇÇÆÆÆÅÅÅÉÉÉÌÌÌÐÐÐÎÎÎÑÑÑ××׺ºº´´´¸¸¸ÅÅÅÙÙÙÑÑÑÂÂÂÐÐÐÅÅŵµµÐÐÐØØØÕÕÕÆÆÆÂÂÂÀÀÀ¼¼¼¿¿¿ÃÃü¼¼ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÂÂÂÃÃÃÅÅÅÂÂÂÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÿ¿¿ÌÌÌÊÊÊÊÊÊÛÛÛÒÒÒºººÌÌÌÔÔÔ¿¿¿ÝÝÝÊÊÊÑÑÑÍÍÍÕÕÕÕÕÕÑÑÑÒÒÒÎÎÎÌÌÌÔÔÔÙÙÙÔÔÔÍÍÍîîîëëëøøøäääææææææ×××ÝÝÝÜÜÜÝÝÝÍÍÍÐÐÐÊÊÊÎÎÎÕÕÕÒÒÒÆÆÆÂÂÂÌÌÌÑÑÑÎÎÎÒÒÒÂÂÂÅÅÅÐÐÐÒÒÒØØØÊÊʨ¨¨±±±¸¸¸­­­°°°³³³ÔÔÔßßßäääÙÙÙÔÔÔÛÛÛäääææææææßßßÐÐÐÐÐÐÒÒÒÔÔÔÑÑÑÎÎÎÍÍÍÎÎÎÐÐÐÔÔÔÉÉÉÃÃÃÐÐÐÕÕÕÑÑÑ×××ÝÝÝêêêæææíííêêêííííííßßßããã××׿¿¿ÊÊÊÊÊÊÉÉÉÌÌÌÌÌÌÙÙÙÒÒÒîîîÙÙÙ¼¼¼ÉÉÉÇÇÇÉÉÉÅÅÅÒÒÒÝÝÝæææñññùùùòòòäääâââÛÛÛÅÅÅÐÐÐÀÀÀµµµ±±±¸¸¸ÎÎÎÆÆÆÙÙÙÕÕÕÉÉÉÎÎÎÅÅźººÅÅÅÅÅÅÀÀÀ´´´»»»ÉÉÉÆÆÆÍÍÍÐÐÐÐÐÐÍÍÍÊÊÊÆÆÆÃÃÃÅÅÅÆÆÆÆÆÆ¿¿¿»»»¿¿¿ÆÆÆÇÇÇÃÃþ¾¾¾¾¾¾¾¾ÃÃÃÍÍÍÒÒÒÒÒÒÔÔÔØØØÛÛÛØØØÍÍÍÒÒÒÑÑÑÊÊÊÎÎÎÍÍÍÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛÜÜÜßßßâââàààâââäääæææææææææääääääèèèõõõñññøøøíííØØØººº»»»¿¿¿ÃÃÃÇÇÇÇÇÇÅÅÅÅÅÅÉÉÉÍÍÍÍÍÍÊÊÊÉÉÉÆÆÆµµµ¸¸¸ÆÆÆÒÒÒÔÔÔÌÌ̼¼¼ÌÌÌÆÆÆºººÊÊÊÇÇÇÎÎÎÉÉÉÉÉÉÇÇÇÅÅÅÃÃÃÃÃÿ¿¿ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼¾¾¾¿¿¿ÂÂÂÃÃÃÃÃÃÅÅÅÃÃÃÊÊÊÇÇÇÇÇÇÒÒÒÉÉɾ¾¾ÐÐÐÔÔÔ»»»¸¸¸ÙÙÙÉÉÉÉÉÉÒÒÒÕÕÕÐÐÐÌÌÌÐÐÐÎÎÎÍÍÍÒÒÒÔÔÔ×××ÎÎÎææææææùùùèèèâââãããÔÔÔÝÝÝââââââÐÐÐÍÍÍÆÆÆÎÎÎÙÙÙßßßÔÔÔÇÇÇÃÃÃÃÃÃÂÂÂ×××ÐÐÐÍÍÍÉÉÉÊÊÊ×××ÎÎί¯¯¯¯¯³³³±±±ÀÀÀÉÉÉàààæææëëëÙÙÙÕÕÕÜÜÜæææææææææàààÒÒÒÒÒÒÔÔÔÕÕÕÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÊÊÊÊÊÊÎÎÎÙÙÙÝÝÝÙÙÙ×××ÕÕÕîîîææææææãããæææíííèèèäääÉÉÉ¿¿¿ÂÂÂÊÊÊÉÉÉÉÉÉÐÐÐÔÔÔÌÌÌÒÒÒîîîâââÍÍÍÑÑÑÌÌÌÉÉÉÕÕÕâââêêêèèèèèèëëëæææÛÛÛÙÙÙÎÎÎÆÆÆÇÇǰ°°­­­¥¥¥¦¦¦ÝÝÝÕÕÕ×××ÐÐÐÃÃÃÇÇÇÇÇǾ¾¾ÆÆÆÀÀÀ¼¼¼µµµ¼¼¼ÆÆÆÅÅÅÎÎÎÎÎÎÍÍÍÊÊÊÆÆÆÃÃÃÂÂÂÅÅÅÇÇÇÇÇÇÃÃÃÅÅÅÇÇÇÅÅž¾¾¾¾¾ÃÃÃÀÀÀÀÀÀÃÃÃÍÍÍÒÒÒÔÔÔØØØÝÝÝÙÙÙ×××ÍÍÍÒÒÒÔÔÔÑÑÑÙÙÙÙÙÙÝÝÝßßßàààßßßÝÝÝÜÜÜÛÛÛÜÜÜääääääææææææçççççççççäääóóóøøøöööõõõÜÜÜÊÊʼ¼¼¿¿¿ÃÃÃÆÆÆÇÇÇÇÇÇÆÆÆÇÇÇÌÌÌÐÐÐÙÙÙÕÕÕÐÐÐÀÀÀ»»»ÃÃÃÕÕÕÙÙÙÐÐÐÇÇǺººÆÆÆÇÇÇÀÀÀÇÇǺººÌÌÌÐÐÐÎÎÎÍÍÍÍÍÍÇÇÇ¿¿¿¼¼¼ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾ÀÀÀÂÂÂÃÃÃÅÅÅÉÉÉÇÇÇÇÇÇÅÅÅÅÅÅÊÊÊ¿¿¿¿¿¿ÇÇÇÊÊʸ¸¸´´´ÊÊʼ¼¼¿¿¿ÉÉÉÊÊÊÇÇÇÇÇÇÎÎÎÐÐÐÎÎÎÑÑÑÒÒÒ×××ÐÐÐæææëëëüüüèèèâââêêê×××ÛÛÛãããàààÍÍÍÉÉÉÅÅÅÂÂÂÌÌÌÔÔÔÔÔÔÎÎÎÉÉÉÇÇÇÇÇÇÆÆÆÇÇÇÅÅÅÀÀÀÌÌÌßßßâââÔÔÔ©©©¯¯¯¸¸¸ÑÑÑßßßêêêçççêêêØØØØØØßßßæææææææææâââÙÙÙÔÔÔÕÕÕÔÔÔÒÒÒÐÐÐÎÎÎÎÎÎÎÎÎâââÝÝÝÙÙÙÕÕÕÕÕÕØØØÙÙÙÛÛÛíííäääßßßàààâââêêêëëëÕÕÕ¾¾¾ÀÀÀÉÉÉÌÌÌÇÇÇÊÊÊÔÔÔ×××ÑÑÑßßßèèèàààØØØÙÙÙÜÜÜßßßÛÛÛæææíííçççããããããâââÝÝÝØØØÇÇÇÌÌÌÆÆÆ···ÑÑÑÙÙÙÛÛÛàààÛÛÛÔÔÔÍÍÍÃÃÃÆÆÆÌÌÌ»»»ÂÂÂÃÃÃÉÉÉÊÊÊÃÃÃÊÊÊÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÂÂÂÅÅÅÇÇÇÊÊÊÆÆÆÇÇÇÍÍÍÆÆÆ»»»¾¾¾ÇÇÇÊÊÊÉÉÉÌÌÌÒÒÒÕÕÕ×××ÛÛÛßßßÕÕÕÔÔÔÍÍÍ×××ÛÛÛÙÙÙââââââãããââââââàààààààààãããäääóóóõõõóóóòòòóóóööööööóóóõõõøøøöööàà྾¾ºººÂÂÂÅÅÅÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÍÍÍÒÒÒØØØâââßßßÙÙÙÀÀÀÅÅÅÍÍÍÜÜÜÕÕÕÍÍÍÉÉÉ¿¿¿ÆÆÆÇÇÇÆÆÆÌÌ̼¼¼ÃÃÃÌÌÌÉÉÉÇÇÇÑÑÑÎÎÎÀÀÀ¼¼¼ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÊÊÊÊÊÊÅÅÅÃÃÃÆÆÆÆÆÆ¾¾¾ÅÅÅ···¸¸¸¾¾¾ÇÇÇÌÌ̺ºººººÀÀÀÅÅÅÇÇÇÌÌÌÎÎÎÎÎÎÍÍÍÎÎÎÔÔÔÑÑÑÍÍÍêêêõõõúúúæææçççøøøßßßØØØÝÝÝØØØÉÉÉÇÇÇÊÊÊÆÆÆÃÃÃÂÂÂÆÆÆÊÊÊÍÍÍÌÌÌÊÊÊÅÅÅÅÅÅÂÂÂÅÅÅÎÎÎ×××ÝÝÝãããâââàààßßßäääæææäääÛÛÛÕÕÕ×××ÙÙÙßßßäääæææææææææãããøøøöööóóóîîîèèèãããàààÝÝÝçççàààßßß×××ÕÕÕØØØØØØÝÝÝêêêãããßßßäääâââæææäää¼¼¼ÀÀÀÉÉÉÐÐÐÍÍÍÊÊÊÎÎÎÒÒÒÒÒÒÛÛÛëëëäääàààààààààëëëñññÛÛÛãããçççäääãããäääãããàààÙÙÙÌÌÌÅÅÅ···³³³ÑÑÑÜÜÜÕÕÕÉÉÉÇÇÇÆÆÆÇÇÇÇÇÇÎÎÎÒÒÒÌÌÌ¿¿¿¸¸¸ÃÃÃÊÊÊÍÍÍÊÊÊÀÀÀÅÅÅ¿¿¿ÀÀÀÃÃÃÃÃÃÃÃÃÃÃÃÆÆÆÇÇÇÍÍÍÇÇÇÇÇÇÍÍÍÉÉÉÀÀÀÃÃÃÍÍÍÒÒÒÐÐÐÑÑÑÕÕÕ×××ÕÕÕÕÕÕØØØÔÔÔÕÕÕÒÒÒßßßãããÝÝÝâââßßßÝÝÝÛÛÛÙÙÙÛÛÛàààèèèñññõõõîîîîîîíííèèèêêêîîîîîîèèèëëëäääßßßÉÉɳ³³µµµÆÆÆÇÇÇÇÇÇÇÇÇÉÉÉÊÊÊÎÎÎÔÔÔÛÛÛßßßßßßÝÝÝÔÔÔ¸¸¸ÅÅÅÑÑÑÜÜÜÑÑÑÎÎÎÍÍÍÊÊÊÊÊÊÆÆÆÉÉÉÒÒÒÌÌ̾¾¾Â»»»¾¾¾ÐÐÐÔÔÔÇÇǾ¾¾ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÅÅÅÅÅÅÆÆÆÅÅÅÅÅÅÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÆÆÆÉÉÉÉÉÉÃÃÃÃÃÃÇÇÇÅÅÅÃÃÃÅÅÅ»»»ÅÅÅÍÍÍÎÎεµµ···¼¼¼ÀÀÀÇÇÇÉÉÉÅÅÅÃÃÃÆÆÆÇÇÇÑÑÑÌÌÌÅÅÅÝÝÝñññöööæææêêêùùùâââ×××ÛÛÛÒÒÒÌÌÌÍÍÍÒÒÒÙÙÙÐÐÐÆÆÆÂ¿¿¿¼¼¼»»»ÅÅÅÆÆÆÆÆÆÉÉÉÎÎÎÐÐÐÕÕÕÜÜÜæææçççäääÝÝÝâââèèèèèèßßßÕÕÕÙÙÙßßßãããççççççèèèêêêâââàààâââãããääääääææææææÛÛÛ×××àààÝÝÝÝÝÝàààÜÜÜçççêêêäääàààèèèäääæææßßßµµµÅÅÅÍÍÍÎÎÎÍÍÍÐÐÐÕÕÕÕÕÕÐÐÐÔÔÔêêêãããçççîîîäääèèèçççàààãããããããããääääääÝÝÝ×××ÐÐÐÍÍÍ¿¿¿¼¼¼ÎÎÎßßßæææÒÒÒÇÇÇÆÆÆÇÇÇÅÅÅÅÅÅÉÉÉ»»»ÃÃø¸¸ÀÀÀÅÅÅÅÅÅÆÆÆÀÀÀÃÃÃÅÅÅÆÆÆÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÎÎÎÊÊÊÊÊÊÍÍÍÊÊÊÆÆÆÊÊÊÔÔÔÔÔÔÑÑÑÑÑÑÔÔÔÔÔÔÐÐÐÐÐÐÒÒÒÙÙÙÜÜÜÙÙÙäääæææÝÝÝÝÝÝÙÙÙÕÕÕØØØÝÝÝäääêêêîîîîîîîîîõõõùùùöööòòòòòòõõõîîîäääÙÙÙÅÅž¾¾¾¾¾¼¼¼ÇÇÇÅÅÅÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐ×××ÝÝÝâââæææäääÒÒÒºººÂÂÂÒÒÒ×××ÍÍÍÍÍÍÎÎÎÒÒÒÐÐÐÅÅÅÆÆÆÑÑÑÒÒÒÇÇÇÆÆÆ¼¼¼ºººÇÇÇÐÐÐÅÅÅ···ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÅÅÅÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÆÆÆÆÆÆÉÉÉÅÅÅÇÇÇÇÇÇ¿¿¿ÅÅŵµµµµµÅÅÅÃÃÃÀÀÀ······³³³···¸¸¸¾¾¾¿¿¿»»»¾¾¾ÆÆÆÉÉÉÆÆÆÇÇǾ¾¾ÉÉÉäääòòòèèèçççíííßßßØØØÝÝÝÒÒÒÔÔÔÕÕÕÙÙÙÕÕÕÕÕÕÒÒÒÊÊʾ¾¾¼¼¼¼¼¼»»»ÀÀÀÆÆÆÆÆÆÉÉÉÕÕÕÜÜÜØØØÎÎÎÙÙÙäääÝÝÝääääääàààÐÐÐ×××ÜÜÜÝÝÝàààçççèèèèèèíííèèèçççäääãããâââàààßßßÜÜÜàààâââñññêêêçççîîîäääííííííæææâââäääãããæææÜÜÜ¿¿¿ÃÃÃÊÊÊÉÉÉÊÊÊÔÔÔÛÛÛØØØÔÔÔÐÐÐàààÝÝÝäääëëëâââàààÜÜÜâââààààààâââäääãããÛÛÛÑÑÑÊÊÊÇÇǸ¸¸¾¾¾ÙÙÙÝÝÝßßßÌÌÌÃÃÃÀÀÀÉÉÉÃÃÃÇÇÇÐÐÐÂÂÂÀÀÀÉÉɼ¼¼ÂÂÂÀÀÀ¾¾¾ÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉÌÌÌÍÍÍÍÍÍÐÐÐÑÑÑÍÍÍÆÆÆÆÆÆÐÐÐÜÜÜ×××ÑÑÑÐÐÐÑÑÑÒÒÒÐÐÐÒÒÒ×××ÝÝÝßßßÙÙÙâââãããÜÜÜßßßÛÛÛßßßâââèèèïïïóóóòòòíííçççíííóóóóóóïïïíííêêêÛÛÛÊÊÊÇÇǺºº»»»»»»ÅÅÅ¿¿¿ÆÆÆÃÃÃÉÉÉÉÉÉÉÉÉÌÌÌÐÐÐÕÕÕÛÛÛÝÝÝäääçççÒÒÒÂÂÂÆÆÆ×××ÑÑÑÉÉÉÉÉÉÊÊÊÔÔÔÔÔÔÆÆÆÂÂÂÇÇÇÌÌÌÑÑÑÍÍÍÇÇÇÀÀÀÀÀÀÉÉÉÅÅÅ´´´ºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÃÃÃÇÇÇÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÆÆÆÃÃÃÉÉÉÇÇÇÊÊÊÃÃô´´¿¿¿ÎÎξ¾¾ººº±±±´´´¬¬¬¯¯¯ŸŸŸ¨¨¨¤¤¤©©©¯¯¯¯¯¯±±±³³³¬¬¬¼¼¼ÀÀÀ»»»ÉÉÉèèèóóóçççäääçççãããÜÜÜßßßÑÑÑØØØØØØÛÛÛÌÌÌÔÔÔØØØÑÑÑÌÌÌÍÍÍÎÎÎÊÊÊÆÆÆÃÃÃÇÇÇÇÇÇÅÅÅÐÐÐÙÙÙÑÑÑÎÎÎØØØèèèæææëëëâââÜÜÜÎÎÎÜÜÜâââßßßßßßæææçççäääêêêêêêçççääääääääääääâââßßßâââíííÿÿÿæææßßßïïïäääâââëëëâââßßßÝÝÝÝÝÝÜÜÜÍÍÍ¿¿¿¿¿¿ÆÆÆÅÅÅÇÇÇÒÒÒ×××ÕÕÕØØØ×××ÛÛÛØØØÜÜÜàààÝÝÝßßßÝÝÝÝÝÝßßßàààâââàààÝÝÝØØØÕÕÕÎÎο¿¿ÃÃÃÎÎÎãããââââââÔÔÔÊÊÊÃÃÃÎÎÎÆÆÆÊÊÊ×××ÅÅÅÇÇÇÎÎÎÂÂÂÇÇÇ¿¿¿ÇÇÇÉÉÉÇÇÇÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÉÉÉÍÍÍÑÑÑÌÌÌÕÕÕØØØÎÎÎÃÃÃÅÅÅÒÒÒàààØØØÒÒÒÐÐÐÑÑÑÒÒÒÔÔÔÙÙÙßßßßßßÝÝÝ×××ÝÝÝàààÜÜÜãããâââñññîîîêêêëëëïïïöööùùùüüüæææîîîñññíííèèèàààÌÌ̵µµ»»»¿¿¿ÆÆÆ¸¸¸¿¿¿»»»ÅÅÅÃÃÃÉÉÉÉÉÉÉÉÉÊÊÊÎÎÎÒÒÒ×××ØØØÍÍÍØØØÉÉÉÅÅÅÉÉÉÙÙÙÌÌÌÅÅÅÅÅÅÅÅÅÒÒÒÕÕÕÇÇǾ¾¾¼¼¼ÀÀÀÍÍÍÌÌÌÌÌÌÆÆÆ¿¿¿ÊÊÊÎÎÎÀÀÀºººººº»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÂÂÂÃÃÃÉÉÉÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÇÇÇÂÂÂÉÉÉÌÌÌÍÍÍÀÀÀªªª¸¸¸¾¾¾°°°···³³³°°°©©©ÇÇÇÕÕÕÝÝÝ×××ÛÛÛãããâââßßßÒÒÒ¾¾¾¸¸¸ººº¼¼¼×××úúúøøøääääääíííêêêàààßßßÌÌÌÕÕÕØØØÛÛÛØØØÝÝÝÜÜÜÒÒÒÒÒÒØØØÔÔÔÊÊÊÒÒÒ¿¿¿ÂÂÂÊÊÊÅÅÅÌÌÌØØØÕÕÕÙÙÙÕÕÕÜÜÜÕÕÕÜÜÜÒÒÒÜÜÜÝÝÝâââäääßßßÝÝÝæææäääâââæææèèèæææããããããääääääâââßßßâââëëëëëë¼¼¼´´´ÝÝÝäääçççæææÜÜÜÝÝÝØØØØØØÒÒÒºººµµµ¾¾¾ÅÅÅÅÅÅÇÇÇÐÐÐÐÐÐÐÐÐØØØÛÛÛØØØÙÙÙÝÝÝßßßààààààÝÝÝàààãããäääâââÛÛÛÔÔÔÒÒÒÔÔÔÊÊÊ´´´ÒÒÒäääíííãããÙÙÙÌÌÌÐÐÐÊÊÊÉÉÉÍÍÍÒÒÒÑÑÑÉÉÉ¿¿¿ÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÃÃÿ¿¿ÅÅÅÍÍÍÑÑÑÒÒÒÒÒÒÑÑÑÑÑÑ×××ØØØÔÔÔÍÍÍÌÌÌÒÒÒÙÙÙÜÜÜàààÐÐÐÔÔÔÒÒÒÔÔÔÔÔÔÍÍÍÙÙÙ×××ÝÝÝâââóóóííííííæææïïïîîîïïïòòòõõõöööøøøùùùùùùñññóóóõõõíííØØØÃÃþ¾¾ÃÃÿ¿¿ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÂÂÂÅÅÅÉÉÉÆÆÆÅÅÅÇÇÇÌÌÌÑÑÑÒÒÒÔÔÔÛÛÛÔÔÔÀÀÀÃÃÃÆÆÆ×××ÎÎÎÆÆÆÉÉÉÑÑÑÑÑÑÒÒÒÎÎÎÎÎÎÍÍÍ···¸¸¸ÀÀÀÐÐÐÀÀÀ¾¾¾ÔÔÔÎÎξ¾¾»»»¼¼¼¼¼¼¼¼¼»»»»»»¾¾¾¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÊÊÊÆÆÆÌÌÌÔÔÔÃÃó³³»»»»»»³³³°°°­­­žžž©©©ÍÍÍÑÑÑ×××ÕÕÕÑÑÑ×××ãããÝÝÝÕÕÕÙÙÙØØØæææèèèèèèóóóõõõêêêäääëëëöööÜÜÜàààÒÒÒÔÔÔÝÝÝÕÕÕÙÙÙßßßÝÝÝÔÔÔÐÐÐÕÕÕÒÒÒÊÊÊÑÑÑÂÂÂÆÆÆÊÊÊÍÍÍÉÉÉâââÜÜÜØØØÑÑÑØØØÝÝÝØØØ×××ÝÝÝßßßâââßßßâââçççèèèææææææêêêäääàààßßßâââãããßßßßßßäääàààäääÝÝÝ»»»»»»±±±ÙÙÙÝÝÝÛÛÛ···³³³µµµ······°°°ºººÂÂÂÃÃÃÅÅÅÉÉÉÍÍÍÑÑÑÔÔÔ××××××ÙÙÙÛÛÛÝÝÝßßßàààààààààÛÛÛÝÝÝÜÜÜÕÕÕÒÒÒÔÔÔÑÑÑÌÌÌ···ºººÝÝÝâââÝÝÝæææÕÕÕÎÎÎÍÍÍÎÎÎÎÎÎÐÐÐÎÎÎÍÍÍÊÊÊÇÇÇ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÅÅÅÇÇÇÉÉÉÃÃÃÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÍÍÍÊÊÊØØØÙÙÙÕÕÕÍÍÍÌÌÌÑÑÑØØØÛÛÛÔÔÔÇÇÇÍÍÍÐÐÐÔÔÔÕÕÕÔÔÔààààààääääääóóóïïïõõõîîîòòòîîîîîîîîîïïïññññññïïïîîîöööîîîää䨨ØÉÉÉ»»»¸¸¸¾¾¾¿¿¿¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾ÂÂÂÅÅÅÇÇÇÆÆÆÆÆÆÇÇÇÌÌÌÐÐÐÒÒÒÔÔÔÍÍÍÆÆÆºººÅÅÅÌÌÌÜÜÜÕÕÕÑÑÑÊÊÊÐÐÐÍÍÍÊÊÊÂÂÂÀÀÀÇÇǸ¸¸ÀÀÀÂÂÂÉÉɼ¼¼ÆÆÆÇÇǾ¾¾»»»¼¼¼¼¼¼¼¼¼»»»»»»¼¼¼¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÉÉÉÆÆÆÍÍÍÕÕÕÆÆÆ´´´»»»Â¾¾¾´´´¬¬¬¦¦¦¾¾¾ÛÛÛÒÒÒ×××ÑÑÑÍÍÍÕÕÕãããæææãããäääãããëëëêêêêêêñññíííâââÜÜÜêêêïïïÛÛÛêêêÜÜÜÕÕÕÛÛÛÛÛÛÛÛÛßßßÜÜÜÒÒÒÐÐÐÕÕÕÕÕÕÐÐÐÊÊÊÀÀÀÇÇÇÌÌÌÎÎÎÌÌÌãããÛÛÛØØØ×××ÜÜÜÜÜÜ×××ÛÛÛâââßßßâââßßßàààãããàààÛÛÛÙÙÙÜÜÜâââãããäääæææãããÛÛÛÕÕÕÔÔÔãããäääÛÛÛ¸¸¸¸¸¸±±±ÕÕÕØØØÎÎεµµ´´´µµµ···¾¾¾¼¼¼Â¿¿¿ÂÂÂÅÅÅÉÉÉÍÍÍÑÑÑÒÒÒÔÔÔ×××ØØØÙÙÙÛÛÛÜÜÜÜÜÜÛÛÛÛÛÛàààÕÕÕÑÑÑ×××ÔÔÔÉÉÉÂÂÂÅÅÅÉÉÉÊÊÊäääâââßßßæææÕÕÕÔÔÔÔÔÔÒÒÒÑÑÑÎÎÎÍÍÍÌÌÌÍÍÍÍÍÍÐÐÐÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÎÎÎÌÌÌÉÉÉÍÍÍÔÔÔÕÕÕÐÐÐÊÊÊÙÙÙÙÙÙÕÕÕÎÎÎÍÍÍÒÒÒØØØÙÙÙÛÛÛÐÐÐÒÒÒÑÑÑÑÑÑÑÑÑÑÑÑÜÜÜæææëëëëëëóóóëëëóóóèèèãããçççæææçççíííòòòöööõõõóóóää䨨ØÌÌÌÃÃÿ¿¿¼¼¼¾¾¾¿¿¿¾¾¾¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼ÀÀÀÃÃÃÆÆÆÆÆÆÉÉÉÉÉÉÊÊÊÍÍÍÐÐÐÒÒÒÃÃÃÃÃþ¾¾ÊÊÊÆÆÆÎÎÎÆÆÆÇÇÇÐÐÐÒÒÒÎÎÎÌÌ̾¾¾···¾¾¾µµµÊÊÊÆÆÆÃÃÃÅÅÅ»»»¸¸¸ÀÀÀ¿¿¿»»»¼¼¼¼¼¼»»»»»»»»»¼¼¼¿¿¿¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÅÅÅÇÇÇÆÆÆÎÎÎÙÙÙÉÉÉ···»»»»»»ÀÀÀµµµªªª­­­ÊÊÊàààÎÎÎÑÑÑÐÐÐØØØâââäääãããâââÝÝÝêêêèèèçççêêêîîîçççÜÜÜÜÜÜÜÜÜãããÕÕÕçççÜÜÜÒÒÒÕÕÕ×××ÔÔÔÛÛÛßßßÛÛÛÙÙÙÛÛÛÕÕÕÌÌÌÃÃÃÃÃÃÍÍÍÎÎÎÑÑÑÎÎÎää䨨ØÛÛÛÝÝÝàààÜÜÜØØØÝÝÝâââÛÛÛãããâââââââââßßßÝÝÝàààæææÛÛÛÝÝÝàààßßßØØØÔÔÔÒÒÒÐÐÐäääâââØØØµµµ´´´¯¯¯ÊÊÊÊÊʰ°°¨¨¨°°°´´´···ÀÀÀ¿¿¿»»»¾¾¾ÀÀÀÅÅÅÉÉÉÍÍÍÐÐÐÐÐÐÑÑÑÕÕÕÕÕÕ××××××××××××ÕÕÕÕÕÕ×××ÒÒÒÒÒÒÒÒÒÇÇǼ¼¼ÃÃÃÔÔÔÕÕÕØØØæææàààãããêêêÝÝÝäääãããÙÙÙÎÎÎÉÉÉÌÌÌÐÐÐÎÎÎÌÌÌÉÉÉÌÌÌÐÐÐÒÒÒÒÒÒÐÐÐÌÌÌÉÉÉÑÑÑÎÎÎÌÌÌÎÎÎÒÒÒÔÔÔÑÑÑÍÍÍ×××ØØØÕÕÕÐÐÐÎÎÎÕÕÕÙÙÙÙÙÙÙÙÙÒÒÒÑÑÑÑÑÑÒÒÒÔÔÔÙÙÙäääãããîîîññññññÝÝÝàààÔÔÔÉÉÉÂÂÂÃÃÃÇÇÇÒÒÒßßßèèèëëëëëëÊÊÊÅÅÅÀÀÀ¿¿¿ÀÀÀÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÃÆÆÆÊÊÊÊÊÊÊÊÊÌÌÌÍÍÍÐÐи¸¸¼¼¼ºººÆÆÆÇÇÇÔÔÔÍÍÍÊÊÊ××××××ÔÔÔ×××ÉÉÉ»»»»»»¯¯¯ÊÊÊÊÊÊÃÃÃÆÆÆººº³³³ÀÀÀ¾¾¾ººº»»»¼¼¼»»»ºººººº¼¼¼¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿ÂÂÂÅÅÅÆÆÆÉÉÉÇÇÇÆÆÆÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÂÂÂÆÆÆÅÅÅÐÐÐÛÛÛÌÌ̺ºº¾¾¾¨¨¨¸¸¸³³³©©©¬¬¬ÂÂÂ×××ÌÌÌØØØÕÕÕÜÜÜÝÝÝÔÔÔÕÕÕßßßàààãããÝÝÝÝÝÝçççíííæææâââæææÝÝÝêêêâââíííããããããâââÝÝÝÑÑÑØØØÜÜÜÙÙÙØØØ×××ÐÐÐÇÇÇÆÆÆÊÊÊÔÔÔÑÑÑÒÒÒÐÐÐää䨨ØÝÝÝßßßàààßßßÜÜÜÛÛÛÙÙÙ×××ÕÕÕÙÙÙßßßâââßßßÜÜÜÛÛÛÜÜÜàààßßßßßß×××ÍÍÍÐÐÐÕÕÕÕÕÕÜÜÜØØØÍÍͬ¬¬¨¨¨¤¤¤³³³°°°­­­¥¥¥¦¦¦©©©ªªªµµµÀÀÀÃÃþ¾¾¿¿¿ÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎÐÐÐÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÍÍÍÕÕÕÒÒÒÃÃû»»ÆÆÆÛÛÛçççÝÝÝàààæææßßßæææëëëàààëëëëëëßßßÑÑÑÊÊÊÊÊÊÍÍÍÎÎÎÍÍÍÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÌÌÌÉÉÉÆÆÆÉÉÉÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÑÑÑÔÔÔÒÒÒÑÑÑÒÒÒÙÙÙÜÜÜÛÛÛØØØÒÒÒÌÌÌÍÍÍÐÐÐÔÔÔßßßæææàààîîîòòòêêêÉÉÉÌÌÌÇÇÇÀÀÀÌÌÌÇÇÇÅÅÅÆÆÆÉÉÉÉÉÉÅÅÅÀÀÀÅÅÅÇÇÇÉÉÉÇÇÇÃÃÃÀÀÀ¾¾¾¼¼¼ÀÀÀÀÀÀÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÂÂÂÃÃÃÆÆÆÊÊÊÌÌÌÊÊÊÊÊÊÌÌÌÍÍÍÃÃÃÅÅŸ¸¸¾¾¾ÃÃÃÛÛÛ×××ÎÎÎÕÕÕÑÑÑÍÍÍÔÔÔÎÎÎÅÅű±±ÃÃÃÌÌÌÇÇÇÆÆÆ»»»ºººÆÆÆ»»»ººº»»»¼¼¼»»»ºººººº¼¼¼¾¾¾¿¿¿¾¾¾¾¾¾¾¾¾ÀÀÀÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÀÀÀÅÅÅÅÅÅÎÎÎÛÛÛÍÍͼ¼¼Â¢¢¢···µµµ­­­©©©±±±ÊÊÊÕÕÕÛÛÛÕÕÕØØØ×××ÐÐÐ×××âââàààØØØÑÑÑÕÕÕäääêêêæææçççïïïÛÛÛâââÙÙÙäääÝÝÝàààÝÝÝÜÜÜÒÒÒÑÑÑÌÌÌÅÅÅÂÂÂÃÃÃÆÆÆÅÅÅÎÎÎÔÔÔÙÙÙÒÒÒÔÔÔÐÐÐâââØØØÙÙÙÕÕÕ×××àààâââÙÙÙ×××ÜÜÜàààêêêõõõùùùóóóçççÛÛÛÑÑÑÐÐÐÎÎÎÔÔÔÕÕÕÍÍÍÑÑÑÛÛÛÛÛÛàààÛÛÛÑÑÑ´´´¬¬¬©©©­­­¨¨¨±±±¨¨¨¨¨¨°°°¯¯¯°°°¾¾¾ÆÆÆ¿¿¿¿¿¿¿¿¿ÀÀÀÃÃÃÉÉÉÍÍÍÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒÒÒÒÔÔÔÔÔÔÕÕÕÑÑÑÕÕÕÊÊʸ¸¸¼¼¼ÔÔÔäääâââèèèèèèçççâââçççæææÛÛÛäääæææãããÛÛÛÑÑÑÉÉÉÇÇÇÌÌÌÐÐÐÔÔÔÑÑÑÎÎÎÌÌÌÊÊÊÉÉÉÉÉÉÉÉÉÊÊÊÍÍÍÎÎÎÎÎÎÌÌÌÊÊÊÍÍÍÎÎÎÍÍÍÑÑÑÒÒÒÔÔÔØØØÜÜÜÝÝÝÙÙÙØØØÔÔÔÉÉÉÊÊÊÎÎÎÑÑÑÜÜÜÝÝÝâââîîîïïïããã¾¾¾ÅÅÅÌÌÌÍÍÍÑÑÑÎÎÎÍÍÍÎÎÎÑÑÑÑÑÑÎÎÎÌÌÌÉÉÉÎÎÎÐÐÐÊÊÊÃÃÃÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾ÀÀÀÃÃÃÃÃÃÆÆÆÊÊÊÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÎÎÎÒÒÒÆÆÆ¿¿¿±±±¾¾¾¿¿¿ÃÃÃÇÇÇ»»»ÃÃÃÆÆÆÇÇÇÌÌ̼¼¼»»»ÇÇÇÊÊÊÃÃü¼¼ÃÃÃÇÇǸ¸¸ººº»»»»»»»»»ºººººº»»»¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÆÆÆÅÅÅÃÃÃÀÀÀÀÀÀÀÀÀ¿¿¿ÅÅÅÃÃÃÌÌÌ×××ÌÌÌ¿¿¿ÉÉɰ°°Â»»»³³³¬¬¬©©©ÂÂÂÙÙÙØØØÕÕÕÕÕÕØØØÙÙÙÝÝÝÙÙÙÐÐÐÒÒÒÍÍÍÕÕÕâââãããàààçççîîîíííãããÛÛÛîîîêêêçççàààèèèêêêçççâââÜÜÜÙÙÙÙÙÙÛÛÛÛÛÛ×××ÙÙÙÙÙÙÒÒÒÕÕÕÍÍÍÜÜÜÕÕÕÑÑÑÊÊÊÌÌÌÛÛÛäääÜÜÜÛÛÛèèèäääêêêëëëêêêçççâââÙÙÙÑÑÑÒÒÒÎÎÎÛÛÛæææÝÝÝÜÜÜâââÝÝÝâââÝÝÝ×××»»»±±±±±±¯¯¯ªªª¨¨¨¥¥¥©©©¸¸¸´´´­­­µµµµµµ¿¿¿¾¾¾¼¼¼¾¾¾ÀÀÀÅÅÅÊÊÊÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÒÒÒÒÒÒÊÊÊÀÀÀ¿¿¿ÉÉÉÕÕÕÛÛÛèèèçççææææææèèèäääßßßãããßßßàààÝÝÝØØØÐÐÐÊÊÊÊÊÊÍÍÍÅÅÅÆÆÆÉÉÉÌÌÌÎÎÎÑÑÑÒÒÒÒÒÒÕÕÕÔÔÔÔÔÔÔÔÔÔÔÔÒÒÒÐÐÐÎÎÎÌÌÌÐÐÐÔÔÔ×××ÛÛÛßßßÛÛÛÕÕÕÔÔÔÒÒÒÉÉÉÐÐÐ×××ÙÙÙâââÜÜÜäääêêêíííæææÀÀÀÉÉÉÒÒÒÔÔÔÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔÒÒÒÑÑÑÐÐÐÊÊÊÍÍÍÍÍÍÉÉÉÆÆÆÇÇÇÉÉÉÆÆÆÅÅÅÅÅÅÅÅÅÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÌÌÌÇÇÇÅÅÅÅÅÅÌÌÌÌÌÌÎÎθ¸¸±±±¯¯¯¼¼¼¸¸¸¸¸¸³³³···»»»ÅÅÅÐÐи¸¸¿¿¿ÉÉɼ¼¼ÇÇÇÅÅŸ¸¸ººº»»»»»»ººººººººº»»»¾¾¾ÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÅÅÅÃÃÃÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀ¾¾¾ÅÅÅÃÃÃÉÉÉÒÒÒÇÇÇÀÀÀÐÐкººÉÉɼ¼¼´´´´´´¬¬¬³³³ÀÀÀÌÌÌÒÒÒÒÒÒÑÑÑÔÔÔÔÔÔÐÐÐÍÍÍÎÎÎÍÍÍØØØâââÜÜÜÛÛÛãããèèèëëëÜÜÜÒÒÒæææääääääÙÙÙâââßßßàààââââââàààÛÛÛ×××ÒÒÒÙÙÙØØØÕÕÕÑÑÑØØØÊÊÊÕÕÕÒÒÒÐÐÐÌÌÌÉÉÉÒÒÒàààßßßâââïïïëëëèèèäääàààãããêêêíííêêêíííÛÛÛßßßæææÙÙÙÒÒÒÙÙÙÙÙÙÔÔÔÐÐÐÊÊʰ°°¦¦¦ªªª¨¨¨¨¨¨©©©¨¨¨¤¤¤ªªª¦¦¦¨¨¨¸¸¸µµµ¼¼¼¼¼¼»»»¼¼¼¿¿¿ÃÃÃÇÇÇÊÊÊÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÍÍÍÎÎÎÐÐÐÊÊÊ¿¿¿»»»ÍÍÍãããêêêääääääëëëëëëèèèèèèæææÜÜÜÛÛÛÙÙÙÙÙÙØØØÔÔÔÌÌÌÆÆÆÌÌÌÑÑÑØØØßßßâââßßßÛÛÛØØØØØØÔÔÔÐÐÐÑÑÑÔÔÔÒÒÒÌÌÌÅÅÅÌÌÌÑÑÑÕÕÕØØØÜÜÜßßßÙÙÙÑÑÑããããããÕÕÕÛÛÛÝÝÝÙÙÙÜÜÜÐÐÐãããæææëëëëëëÊÊÊÎÎÎÒÒÒÐÐÐÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÎÎÎÌÌÌÎÎÎÍÍÍÉÉÉÉÉÉÌÌÌÉÉÉÂÂÂÆÆÆÆÆÆÆÆÆÃÃÃÂÂÂÀÀÀÃÃÃÆÆÆÅÅÅÆÆÆÇÇÇÊÊÊÍÍÍÌÌÌÇÇÇÃÃÃÌÌÌÆÆÆÊÊÊãããÙÙÙÆÆÆ¯¯¯±±±°°°···µµµ······ÂÂÂÎÎκºº¸¸¸ÆÆÆ¿¿¿¼¼¼ÇÇÇÀÀÀ¸¸¸ºººººº»»»ººº¸¸¸ººº»»»¾¾¾ÀÀÀÀÀÀ¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÇÇÇÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿¿¿¿¾¾¾ÅÅÅÂÂÂÇÇÇÐÐÐÆÆÆÂÂÂÔÔÔ···ÇÇǸ¸¸´´´»»»¯¯¯¢¢¢ŸŸŸ¤¤¤ÂÂÂÔÔÔÕÕÕÕÕÕÍÍÍÆÆÆÌÌÌÌÌÌÍÍÍÙÙÙàààØØØØØØâââäääëëëâââØØØããããããëëëÝÝÝÜÜÜàààààààààâââàààÜÜÜÙÙÙØØØØØØÔÔÔÑÑÑÑÑÑÙÙÙÉÉÉÑÑÑÐÐÐÔÔÔÒÒÒÌÌÌÍÍÍÛÛÛàààäääïïïÝÝÝÝÝÝÜÜÜÜÜÜãããëëëëëëäääÕÕÕ···°°°···¯¯¯³³³ÉÉÉÔÔÔÕÕÕÐÐÐÊÊʱ±±¨¨¨±±±¯¯¯´´´©©©¯¯¯©©©ªªª¨¨¨°°°Â···ººº»»»»»»¾¾¾ÀÀÀÃÃÃÆÆÆÇÇÇÑÑÑÐÐÐÎÎÎÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÌÌÌÊÊÊÊÊÊÇÇÇÀÀÀÂÂÂÕÕÕíííóóóêêêêêêñññëëëçççêêêãããæææÜÜÜàààãããÙÙÙ×××ÛÛÛÛÛÛÙÙÙ×××ÕÕÕ×××ÙÙÙÜÜÜÜÜÜÛÛÛâââÝÝÝÔÔÔÔÔÔÛÛÛÔÔÔÎÎÎÕÕÕÙÙÙÙÙÙÝÝÝÜÜÜÙÙÙßßßãããÝÝÝÌÌÌÎÎÎÑÑÑÒÒÒÙÙÙßßßÝÝÝ×××àààæææñññçççÉÉÉÒÒÒÊÊÊÎÎÎÐÐÐÑÑÑÔÔÔÔÔÔÔÔÔÑÑÑÎÎÎÌÌÌÍÍÍÔÔÔÍÍÍÍÍÍÌÌÌÉÉÉÐÐÐÃÃÃÀÀÀÆÆÆÉÉÉÆÆÆÃÃÃÆÆÆÉÉÉÆÆÆÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÐÐÐÌÌÌÉÉÉÆÆÆÌÌÌÍÍͪªª±±±¬¬¬±±±°°°´´´»»»ºººÂ¿¿¿°°°»»»ÀÀÀµµµÇÇÇ»»»»»»ººººººººººººººº»»»¼¼¼¾¾¾ÀÀÀÀÀÀ¿¿¿ÀÀÀÀÀÀÃÃÃÅÅÅÆÆÆÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¾¾¾¿¿¿¿¿¿ÂÂÂÂÂÂÀÀÀÃÃÃÅÅÅÜÜÜÎÎÎÆÆÆ¸¸¸ÍÍÍÃÃþ¾¾°°°¯¯¯¿¿¿¤¤¤¥¥¥¿¿¿ÑÑÑÕÕÕÕÕÕÍÍÍÎÎÎÝÝÝÝÝÝâââÝÝÝÕÕÕ×××âââäääàààäääëëëÛÛÛÙÙÙßßßÝÝÝâââÝÝÝßßß×××ßßßæææÜÜÜ×××ØØØ×××ÙÙÙÎÎÎÕÕÕÙÙÙÎÎÎÐÐÐÛÛÛØØØÑÑÑÌÌÌÐÐÐæææÛÛÛßßßãããíííÜÜܸ¸¸±±±¼¼¼ÀÀÀÑÑÑÒÒÒ´´´¼¼¼¿¿¿Â¾¾¾µµµ¬¬¬¦¦¦ÐÐÐÀÀÀ°°°ªªª±±±···µµµ°°°°°°°°°°°°´´´¸¸¸ºººººº···¸¸¸¸¸¸ººº¼¼¼¿¿¿ÃÃÃÇÇÇÉÉÉÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÇÇÇÉÉÉÉÉÉÇÇÇÊÊÊÊÊÊÀÀÀºººÃÃÃÜÜÜòòòñññíííêêêêêêíííëëëçççãããâââÜÜÜãããçççßßßÙÙÙÙÙÙ×××ÛÛÛÙÙÙØØØÙÙÙÜÜÜÝÝÝÜÜÜÛÛÛßßßÛÛÛÒÒÒÒÒÒØØØÕÕÕÔÔÔÛÛÛÙÙÙÙÙÙÝÝÝÜÜÜØØØÝÝÝâââÜÜÜÕÕÕØØØØØØÕÕÕØØØÜÜÜÛÛÛ×××ÝÝÝæææòòòãããÌÌÌÐÐÐÊÊÊÇÇÇÎÎÎÐÐÐÒÒÒÒÒÒÑÑÑÎÎÎÌÌÌÉÉÉÉÉÉÎÎÎÇÇÇÉÉÉÊÊÊÇÇÇÍÍÍÃÃÿ¿¿¿¿¿ÀÀÀÅÅÅÉÉÉÊÊÊÉÉÉÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÌÌÌÌÌÌÎÎÎÊÊÊÎÎÎÜÜÜÔÔÔÀÀÀ°°°°°°°°°±±±´´´ºººÐÐл»»°°°¾¾¾ÂµµµÍÍÍ¿¿¿»»»ºººººººººººº»»»»»»¼¼¼¾¾¾ÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÂÂÂÀÀÀ¿¿¿¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÂÂÂÂÂÂÅÅÅÆÆÆÙÙÙÇÇÇÀÀÀ¾¾¾¾¾¾»»»¿¿¿¸¸¸´´´ººº¯¯¯ªªªµµµÂÂÂÎÎÎ××××××ÑÑÑÑÑÑàààßßß×××ÍÍÍÐÐÐÜÜÜçççêêêèèèîîîßßßÛÛÛàààßßßãããßßßñññäääÝÝÝÝÝÝÜÜÜÝÝÝàààßßßÜÜÜØØØæææëëëÙÙÙÑÑÑ×××ÒÒÒÔÔÔ×××ÜÜÜÜÜÜÛÛÛóóóêêêäää¾¾¾´´´¼¼¼¿¿¿±±±···ÀÀÀ¸¸¸ÀÀÀÂÂÂÃÃþ¾¾¸¸¸³³³¯¯¯°°°­­­¬¬¬¯¯¯´´´¸¸¸¸¸¸···¸¸¸······ººº¼¼¼¾¾¾¼¼¼ºººººººººººº¼¼¼¾¾¾ÂÂÂÅÅÅÆÆÆÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÆÆÆÃÃÃÆÆÆÃÃü¼¼ÅÅÅØØØèèèîîîíííëëëèèèêêêëëëëëëçççäääâââßßßäääçççàààÛÛÛÛÛÛØØØÜÜÜÜÜÜÛÛÛÜÜÜÝÝÝÝÝÝÜÜÜÛÛÛÛÛÛØØØÒÒÒÑÑÑ××××××ÙÙÙàààÛÛÛÙÙÙÝÝÝÝÝÝÙÙÙÝÝÝßßßØØØÊÊÊÐÐÐÑÑÑÐÐÐÒÒÒØØØÜÜÜÜÜÜàààèèèòòòØØØÇÇÇÉÉÉÌÌÌÆÆÆÍÍÍÎÎÎÑÑÑÑÑÑÐÐÐÍÍÍÉÉÉÆÆÆÆÆÆÊÊÊÃÃÃÅÅÅÆÆÆÃÃÃÅÅÅ¿¿¿ÊÊÊÃÃû»»¼¼¼ÅÅÅÊÊÊÉÉÉÉÉÉÇÇÇÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÉÉÉÆÆÆÅÅÅÍÍÍÉÉÉÅÅÅÔÔÔÛÛÛÒÒÒ´´´­­­±±±µµµ´´´¸¸¸ÐÐл»»³³³¿¿¿Â···ÎÎλ»»»»»»»»ººº»»»»»»¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÃÃÃÅÅÅÆÆÆÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¾¾¾»»»»»»»»»¼¼¼¼¼¼¾¾¾ÀÀÀÀÀÀÆÆÆÆÆÆÕÕÕÀÀÀ»»»ÐÐл»»ºººÀÀÀÀÀÀ»»»³³³´´´¬¬¬¥¥¥¨¨¨³³³ÂÂÂÒÒÒÝÝÝÜÜÜÙÙÙÛÛÛÙÙÙØØØÜÜÜäääêêêíííæææêêêÙÙÙÔÔÔÛÛÛÛÛÛÜÜÜÙÙÙíííäää×××ÔÔÔàààëëëííííííàààÜÜÜäääãããÐÐÐÉÉÉÒÒÒ×××ÑÑÑÕÕÕàààÙÙÙÙÙÙäää¿¿¿µµµÂÂÂÂÂÂÊÊÊÌÌÌÂÂÂÂÂÂÆÆÆÅÅÅÇÇÇÆÆÆÅÅÅÃÃÿ¿¿¼¼¼¸¸¸···¥¥¥ªªª±±±´´´³³³³³³µµµººº¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾»»»ººººººººº»»»»»»¼¼¼¿¿¿ÀÀÀÂÂÂÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÃÃÿ¿¿¼¼¼ÅÅÅ×××êêêïïïíííæææçççèèèêêêëëëêêêçççæææäääâââàààßßßÙÙÙØØØÛÛÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛÛÛÙÙÙØØØ×××ÔÔÔÒÒÒÔÔÔ×××ÛÛÛàààÙÙÙÙÙÙßßßàààÜÜÜßßßÝÝÝÒÒÒÎÎÎÔÔÔ×××ÔÔÔÑÑÑÒÒÒ××××××èèèîîîíííÊÊÊÂÂÂÃÃÃÐÐÐÌÌÌÍÍÍÎÎÎÑÑÑÒÒÒÑÑÑÍÍÍÉÉÉÅÅÅÇÇÇÇÇÇÀÀÀÀÀÀÃÃþ¾¾»»»¼¼¼ØØØÕÕÕÆÆÆ»»»ÀÀÀÇÇÇÆÆÆÂÂÂÇÇÇÉÉÉÌÌÌÍÍÍÍÍÍÌÌÌÉÉÉÇÇÇÊÊÊÂÂÂÀÀÀÊÊÊÊÊÊÂÂÂÃÃÃÆÆÆ××׸¸¸°°°´´´»»»¸¸¸³³³¿¿¿ÇÇÇ···¿¿¿ÀÀÀ´´´ÊÊÊ¿¿¿¿¿¿»»»»»»»»»»»»¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÂÂÂÅÅÅÇÇÇÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¾¾¾¼¼¼»»»¼¼¼¼¼¼¾¾¾¼¼¼ÀÀÀÀÀÀÅÅÅÆÆÆÔÔÔ¿¿¿¾¾¾ÕÕÕÃÃü¼¼¼¼¼ÂÂÂÃÃþ¾¾»»»¿¿¿±±±¬¬¬©©©¦¦¦´´´ÇÇÇÊÊÊÛÛÛÛÛÛÙÙÙ×××ØØØÝÝÝæææêêêãããäääÙÙÙÑÑÑØØØÛÛÛÛÛÛÙÙÙæææèèèÜÜÜ×××äääëëëäääâââëëëããããããßßßÒÒÒÒÒÒàààèèèÜÜÜØØØàààââââââÕÕÕºººÇÇÇÉÉÉÇÇÇÇÇÇÉÉÉÍÍÍÍÍÍÇÇÇÅÅÅÌÌÌÊÊÊÇÇÇÅÅž¾¾»»»ººº³³³···ººº···±±±°°°···¾¾¾ººººººººº»»»»»»ººº¸¸¸¸¸¸»»»»»»»»»¼¼¼¼¼¼¾¾¾¾¾¾¾¾¾ÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀ¼¼¼ÅÅÅÙÙÙèèèëëëëëëîîîâââäääçççêêêêêêèèèçççæææàààâââßßßÙÙÙ××××××ØØØÛÛÛÙÙÙÙÙÙÙÙÙÙÙÙÙÙÙØØØØØØØØØØØØØØØØØØÔÔÔÑÑÑÔÔÔÙÙÙÜÜÜØØØÙÙÙàààãããààààààÜÜÜÎÎÎÒÒÒÛÛÛàààÝÝÝÙÙÙÛÛÛÜÜÜÜÜÜëëëîîîãããÃÃÃÂÂÂÃÃÃÑÑÑÍÍÍÍÍÍÐÐÐÒÒÒÔÔÔÒÒÒÐÐÐÊÊÊÇÇÇÅÅž¾¾¼¼¼ÀÀÀ»»»···ÃÃÃÝÝÝäääÒÒÒ»»»¼¼¼ÆÆÆÅÅÅÀÀÀÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÇÇÇÆÆÆÊÊÊÍÍÍÎÎÎÌÌÌÆÆÆÆÆÆÍÍÍ¿¿¿¼¼¼µµµ´´´···±±±···ÔÔÔ»»»¾¾¾¿¿¿°°°Â»»»Â»»»»»»»»»»»»¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÉÉÉÉÉÉÆÆÆÃÃÃÂÂÂÃÃÿ¿¿¾¾¾¾¾¾¾¾¾¾¾¾¿¿¿¼¼¼Â¿¿¿ÃÃÃÇÇÇÔÔÔÂÂÂÆÆÆÅÅÅÉÉÉ»»»³³³ºººÉÉÉÎÎÎÃÃÃÆÆÆ¾¾¾¾¾¾¸¸¸ªªª©©©¯¯¯¬¬¬ØØØÝÝÝßßßÝÝÝÜÜÜàààããããããæææçççààà×××ÜÜÜàààßßßâââÝÝÝèèèäääÝÝÝäääæææßßßßßßäääßßßàààãããßßßÝÝÝâââãããÜÜÜâââæææäääÝÝÝÅÅž¾¾ÐÐÐÅÅÅÉÉÉÉÉÉÇÇÇÉÉÉÆÆÆÅÅÅÉÉÉÌÌÌÌÌÌÊÊÊÇÇÇÅÅÅ¿¿¿»»»¸¸¸ººº»»»ººº···µµµ···¼¼¼ÀÀÀ···¸¸¸ººº»»»»»»»»»»»»»»»¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼ÂÂÂÀÀÀÀÀÀÃÃÃÇÇÇÇÇÇÆÆÆÅÅż¼¼ÇÇÇÜÜÜííííííæææäääëëëâââäääçççêêêêêêèèèçççæææÛÛÛàààßßßÛÛÛÙÙÙØØØÔÔÔÕÕÕ×××ØØØØØØ×××ÕÕÕÕÕÕØØØÙÙÙÙÙÙÙÙÙÙÙÙÔÔÔÌÌÌÐÐÐØØØÙÙÙÙÙÙÙÙÙàààãããàààâââÝÝÝÐÐÐÍÍÍ×××ÝÝÝÝÝÝÝÝÝàààããããããæææççç×××ÅÅÅÆÆÆÆÆÆÍÍÍÉÉÉÍÍÍÐÐÐÔÔÔÕÕÕÕÕÕÑÑÑÍÍÍÉÉÉÀÀÀ¾¾¾¼¼¼»»»ÀÀÀ»»»ºººÑÑÑÙÙÙãããÐÐз··»»»ÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÆÆÆÆÆÆÍÍÍÔÔÔÎÎÎÌÌÌÌÌÌÆÆÆÌÌÌÃÃÃÇÇÇÌÌ̸¸¸­­­´´´···¿¿¿ÔÔÔ¼¼¼¼¼¼¼¼¼­­­ÀÀÀ»»»ÀÀÀ»»»»»»ººº»»»»»»¼¼¼¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÇÇÇÆÆÆÃÃÃÀÀÀÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿¿¿¿¼¼¼Â¼¼¼ÀÀÀÇÇÇÔÔÔÃÃÃÎÎλ»»ÌḬ̀°°±±±ÀÀÀÉÉÉÂÂÂÀÀÀ»»»¼¼¼¾¾¾»»»ºººµµµ­­­ºººÇÇÇÒÒÒÕÕÕÙÙÙâââäääâââàààäääãããØØØÙÙÙÝÝÝÙÙÙàààÛÛÛâââãããàààâââããããããçççàààÙÙÙÙÙÙßßßàààÝÝÝÝÝÝÝÝÝëëëÿÿÿÿÿÿæææ×××ÉÉÉÉÉÉÃÃÃÉÉÉÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÊÊÊÎÎÎÌÌÌÌÌÌÌÌÌÊÊÊÇÇǾ¾¾»»»¼¼¼»»»ººº»»»»»»»»»ººº¸¸¸¸¸¸»»»¾¾¾¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼¼¼¼ÀÀÀ¿¿¿ÀÀÀÃÃÃÇÇÇÉÉÉÇÇÇÃÃ÷··×××ññññññèèèçççèèèçççæææçççèèèêêêëëëêêêçççæææÙÙÙãããàààÙÙÙÛÛÛÙÙÙÕÕÕ××××××××××××ÕÕÕÔÔÔÕÕÕÙÙÙÝÝÝÛÛÛÙÙÙÙÙÙÐÐÐÅÅÅÌÌÌÙÙÙÛÛÛÝÝÝÛÛÛßßßàààßßßãããàààÔÔÔÒÒÒÙÙÙÝÝÝÛÛÛØØØÛÛÛÜÜÜÛÛÛâââàààÆÆÆÂÂÂÅÅÅÆÆÆÇÇÇÆÆÆÊÊÊÍÍÍÒÒÒÕÕÕÕÕÕÒÒÒÍÍÍÊÊÊÅÅÅÀÀÀÀÀÀ»»»¿¿¿ººº···ØØØ×××ÕÕÕ¿¿¿±±±¼¼¼ÀÀÀ¿¿¿ÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÕÕÕÎÎÎÐÐÐÍÍÍ¿¿¿ÇÇÇÂÂÂÉÉÉÎÎξ¾¾µµµ¿¿¿ÀÀÀÆÆÆÅÅŸ¸¸¿¿¿ººº¬¬¬ÉÉÉÀÀÀ»»»ºººººººººººº»»»»»»¼¼¼¾¾¾ÂÂÂÃÃÃÆÆÆÆÆÆÆÆÆÅÅÅÃÃÃÀÀÀÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¼¼¼¾¾¾¿¿¿»»»Â»»»ÀÀÀÇÇÇÒÒÒÂÂÂÐÐо¾¾ÌÌÌÎÎλ»»³³³µµµ···ÆÆÆÉÉÉÃÃúººµµµ»»»»»»µµµ´´´¨¨¨µµµººº±±±¸¸¸ÐÐÐààààààÜÜÜàààäääÕÕÕÒÒÒÕÕÕÎÎÎÙÙÙãããßßßààààààÛÛÛØØØÜÜÜÝÝÝæææàààÜÜÜÜÜÜÝÝÝßßßäääíííæææÝÝÝÛÛÛ¿¿¿¾¾¾ÅÅÅÍÍÍÆÆÆÌÌÌÉÉÉÉÉÉÌÌÌÊÊÊÌÌÌÌÌÌÇÇÇÊÊÊÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÃÃÃÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼»»»¸¸¸···»»»¾¾¾ÀÀÀÀÀÀÀÀÀÀÀÀÂÂÂÃÃÃÀÀÀÀÀÀÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼ÂÂÂÀÀÀÀÀÀÃÃÃÇÇÇÇÇÇÃÃÿ¿¿ºººÛÛÛòòòîîîèèèîîîñññêêêíííëëëèèèêêêëëëëëëçççäääßßßçççàààÕÕÕ×××ØØØØØØÜÜÜØØØØØØ×××ÔÔÔÔÔÔÕÕÕÛÛÛàààÜÜÜÙÙÙØØØÍÍÍ¿¿¿ÉÉÉÛÛÛÝÝÝâââÜÜÜÝÝÝÜÜÜÜÜÜããããããØØØÔÔÔÙÙÙÜÜÜÛÛÛÜÜÜâââææææææâââÜÜܸ¸¸¼¼¼¿¿¿ÃÃÃÅÅÅÉÉÉÇÇÇÌÌÌÑÑÑÕÕÕÕÕÕÒÒÒÍÍÍÊÊÊÍÍÍÇÇÇÆÆÆ¾¾¾¾¾¾µµµ³³³ØØØ×××ÉÉɰ°°­­­¾¾¾¼¼¼¸¸¸ÅÅÅÉÉÉÇÇÇÅÅÅÅÅÅÅÅÅÅÅÅÇÇÇÉÉÉÌÌÌÉÉÉÐÐÐÔÔÔßßßÛÛÛÃÃÃÇÇÇÆÆÆÅÅÅÉÉÉÃÃÃÆÆÆÐÐÐÉÉÉÆÆÆ³³³µµµÂ¸¸¸­­­ÒÒÒÆÆÆµµµººººººººººººººº»»»¼¼¼¾¾¾ÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¼¼¼»»»»»»¼¼¼¾¾¾ºººÂ»»»ÀÀÀÇÇÇÑÑѾ¾¾ÍÍÍÀÀÀÃÃÃ×××ÉÉɼ¼¼µµµ°°°ÕÕÕÆÆÆÅÅŸ¸¸±±±¸¸¸µµµ±±±···´´´ÅÅÅÅÅŵµµ¸¸¸ÎÎÎÜÜÜØØØßßßäääëëëÛÛÛÔÔÔÕÕÕÍÍÍØØØÙÙÙÎÎÎÔÔÔÜÜÜØØØ×××ÜÜÜÛÛÛÛÛÛÙÙÙØØØ××××××ØØØãããñññââ⺺ºÀÀÀ¼¼¼ÊÊÊÐÐÐÎÎÎÒÒÒÍÍÍÊÊÊÐÐÐÒÒÒÌÌÌÍÍÍÐÐÐÌÌÌÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÉÉÉÉÉÉÃÃÃÃÃÿ¿¿¼¼¼¼¼¼¿¿¿Â»»»¾¾¾ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÂÂÂÀÀÀÂÂÂÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾ÃÃÃÀÀÀÀÀÀÂÂÂÆÆÆÅÅÅ¿¿¿»»»ÀÀÀ×××èèèëëëíííòòòõõõññññññíííêêêêêêíííëëëçççãããßßßààààààÝÝÝØØØ×××ÙÙÙÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝÙÙÙÎÎÎØØØÕÕÕÉÉÉ×××ßßßßßßÜÜÜÝÝÝãããæææâââÜÜÜÜÜÜÛÛÛÜÜÜÙÙÙÕÕÕÙÙÙãããäääßßßÕÕÕ¾¾¾···ºººÃÃÃÀÀÀµµµÇÇÇÃÃÃÊÊÊÒÒÒÕÕÕÒÒÒÎÎÎÎÎÎÐÐÐÉÉÉÇÇÇÆÆÆÂ¼¼¼µµµ°°°¬¬¬ªªª¬¬¬­­­±±±µµµ»»»¿¿¿ÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÇÇÇÔÔÔÊÊÊÐÐÐÝÝÝÛÛÛØØØÎÎÎÉÉÉÍÍÍÒÒÒ±±±ÆÆÆ¼¼¼ººººººÀÀÀÀÀÀ±±±¸¸¸ÆÆÆÂ¼¼¼´´´³³³´´´···¸¸¸ººº»»»¾¾¾ÀÀÀÂÂÂÃÃÃÅÅÅÆÆÆÅÅÅ¿¿¿¾¾¾¼¼¼»»»ºººººº»»»»»»ººº¸¸¸ººº»»»¸¸¸¿¿¿ÂÂÂÎÎÎÀÀÀÊÊÊÅÅÅÂÂÂÕÕÕÌÌÌ···¿¿¿¿¿¿»»»ÅÅÅÆÆÆ»»»¾¾¾±±±¸¸¸µµµ¾¾¾ººº¾¾¾Â¿¿¿¸¸¸´´´´´´µµµ±±±âââêêêëëëÎÎÎÙÙÙÎÎÎÙÙÙÛÛÛÔÔÔÙÙÙæææçççßßßÙÙÙÛÛÛÒÒÒÛÛÛÙÙÙãããäääàààæææÝÝÝ···¸¸¸¾¾¾ÃÃÃÉÉÉÎÎÎÑÑÑÔÔÔÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¿¿¿¾¾¾¾¾¾¼¼¼¾¾¾¿¿¿ÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿ÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÃÃþ¾¾ÂÂÂÅÅÅÇÇÇÃÃø¸¸¿¿¿×××äääæææëëëñññíííâââÝÝÝààààààëëëëëëêêêîîîêêêãããèèèßßßàààâââßßßÙÙÙÙÙÙÜÜÜààààààßßßÜÜÜÙÙÙÙÙÙÜÜÜßßßâââÝÝÝÜÜÜÒÒÒÙÙÙ×××ÐÐÐÛÛÛßßßßßßÝÝÝàààããããããÝÝÝÙÙÙÛÛÛßßßßßßÜÜÜÙÙÙÙÙÙßßßãããããã»»»µµµºººººº¾¾¾¼¼¼¼¼¼ÕÕÕ¾¾¾ÅÅÅÎÎÎÔÔÔÒÒÒÐÐÐÎÎÎÎÎÎÊÊÊÉÉÉÆÆÆÂ»»»´´´¯¯¯¬¬¬ªªªªªª¬¬¬°°°µµµ»»»¿¿¿ÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿ÂÂÂÅÅÅÆÆÆÊÊÊÔÔÔÎÎÎ×××âââãããæææÜÜÜÌÌÌÃÃÃÇÇǵµµÐÐо¾¾ÃÃø¸¸ÀÀÀ¸¸¸¼¼¼Â¸¸¸µµµ³³³³³³´´´···¸¸¸¸¸¸ººº¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÅÅÅÃÃÃÀÀÀ¾¾¾¼¼¼ººº···µµµµµµ···¸¸¸···µµµ»»»»»»¸¸¸¾¾¾¿¿¿ÊÊʸ¸¸¿¿¿ÍÍÍ¿¿¿ÎÎÎÐÐÐÆÆÆÊÊÊÆÆÆÀÀÀ¸¸¸ÃÃÿ¿¿¼¼¼±±±¼¼¼···³³³»»»¾¾¾ÀÀÀ¿¿¿»»»·········¸¸¸ÕÕÕÙÙÙëëëàààèèèÔÔÔÔÔÔ×××ÒÒÒØØØçççîîîæææÙÙÙÔÔÔßßßæææãããàààâââæææäää×××µµµ¸¸¸¼¼¼ÂÂÂÆÆÆÌÌÌÎÎÎÑÑÑÎÎÎÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÅÅÅ¿¿¿¼¼¼ÂÂÂÀÀÀ¸¸¸ÂÂÂÜÜÜîîîîîîíííëëëèèèãããÝÝÝÜÜÜßßßÝÝÝãããæææèèèëëëêêêçççêêêàààâââãããàààÝÝÝÝÝÝâââäääâââàààßßßÝÝÝÝÝÝßßßâââãããÜÜÜßßßÙÙÙÜÜÜÛÛÛÙÙÙààààààØØØÛÛÛâââæææãããÛÛÛØØØÙÙÙâââØØØÔÔÔÛÛÛãããäääÝÝÝÙÙÙ±±±···¿¿¿»»»¸¸¸µµµºººÑÑѺºº¿¿¿ÉÉÉÐÐÐÒÒÒÑÑÑÎÎÎÌÌÌÌÌÌÉÉÉÆÆÆ¿¿¿ººº³³³­­­ªªªªªª©©©ªªª¯¯¯···¼¼¼¿¿¿¿¿¿¾¾¾¼¼¼»»»»»»¼¼¼ÀÀÀÅÅÅÇÇÇÊÊÊÎÎÎÎÎÎÔÔÔ×××ÛÛÛàààÕÕÕÇÇÇ···»»»ºººØØØÅÅž¾¾ÊÊʰ°°ÀÀÀÀÀÀÀÀÀ¼¼¼¯¯¯°°°°°°±±±´´´···¸¸¸¸¸¸ººº»»»¾¾¾ÂÂÂÃÃÃÅÅÅÅÅÅ¿¿¿¼¼¼ººº¸¸¸µµµ´´´´´´µµµ······µµµººº»»»¸¸¸¿¿¿ÂÂÂÌÌÌ···»»»ÉÉÉ»»»ÊÊÊÜÜÜÝÝÝÛÛÛÍÍÍÀÀÀµµµÅÅÅÇÇÇÆÆÆººº¾¾¾¸¸¸´´´¼¼¼¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼»»»»»»¸¸¸ÀÀÀ»»»ÔÔÔÛÛÛîîîäääèèèââââââãããæææèèèçççæææèèèâââââââââÜÜÜßßßàààÎÎο¿¿µµµ···»»»¿¿¿ÃÃÃÇÇÇÌÌÌÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇ¿¿¿¼¼¼¾¾¾ÔÔÔíííóóóîîîîîîêêêãããÝÝÝÜÜÜÜÜÜÛÛÛÜÜÜÛÛÛâââèèèêêêêêêêêêçççâââãããäääãããââââââæææèèèàààâââãããäääãããâââßßßÜÜÜÛÛÛâââàààßßßßßßãããæææâââÊÊÊÐÐÐÜÜÜäääãããÝÝÝÝÝÝââââââÕÕÕÒÒÒÛÛÛÜÜÜÌÌ̺ºº°°°¸¸¸¾¾¾¾¾¾ººº»»»ººº¸¸¸ÀÀÀ¼¼¼¿¿¿ÅÅÅÌÌÌÐÐÐÑÑÑÍÍÍÊÊÊÊÊÊÇÇÇÃÃü¼¼µµµ°°°¬¬¬©©©©©©¨¨¨¨¨¨­­­µµµ»»»¼¼¼»»»»»»¸¸¸···¸¸¸»»»ÀÀÀÅÅÅÆÆÆÇÇÇÆÆÆÊÊÊÎÎÎÌÌÌÑÑÑ×××ÍÍͼ¼¼°°°¸¸¸¾¾¾×××···ÇÇǰ°°ÅÅÅÅÅÅÀÀÀººº¬¬¬­­­°°°±±±´´´·········¸¸¸»»»¼¼¼ÂÂÂÃÃÃÅÅÅÃÃþ¾¾ººº¸¸¸ººº···´´´´´´···¸¸¸¸¸¸¸¸¸···¸¸¸¸¸¸ÃÃÃÊÊÊÔÔÔ¾¾¾¿¿¿ÆÆÆ¼¼¼ÇÇÇØØØÝÝÝÝÝÝÔÔÔÇÇDZ±±µµµ¾¾¾ÆÆÆÃÃÿ¿¿ÀÀÀÆÆÆ¿¿¿¾¾¾¼¼¼¾¾¾ÀÀÀÂÂÂÀÀÀ¿¿¿ÇÇÇÆÆÆºººÂÂÂÀÀÀÒÒÒÒÒÒÛÛÛæææçççßßßÙÙÙÜÜÜßßßàààäääâââØØØÜÜÜàààäää×××µµµ¯¯¯···¸¸¸»»»¾¾¾ÂÂÂÆÆÆÉÉÉÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÊÊÊÊÊÊÉÉÉÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇÆÆÆÅÅÅÂÂÂÂÂÂÂÂÂÃÃÃÅÅÅÆÆÆÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÃÃÿ¿¿ºººÃÃÃÝÝÝíííîîîîîîæææèèèèèèàààÝÝÝßßßÜÜÜ×××ÛÛÛÕÕÕßßßêêêèèèççççççßßßæææææææææäääãããäääçççèèèãããäääæææäääãããàààÜÜÜÙÙÙÜÜÜâââäääâââãããëëëêêêæææãããââââââßßßØØØÎÎÎÎÎÎÒÒÒÒÒÒÑÑÑØØØßßßÔÔÔ¾¾¾µµµ»»»ººº¿¿¿»»»ºººÂÂÂÂÂÂÀÀÀ¿¿¿ÅÅÅÃÃÃÅÅÅÉÉÉÍÍÍÐÐÐÍÍÍÊÊÊÇÇÇÅÅÅ¿¿¿ººº³³³¯¯¯¬¬¬ªªªªªª©©©©©©¯¯¯µµµºººººº···¸¸¸···´´´···¼¼¼ÀÀÀÅÅÅÆÆÆÅÅÅÃÃÃÌÌÌÐÐÐÍÍÍ×××ÙÙÙÐÐг³³µµµÅÅÅÆÆÆÔÔÔ¿¿¿³³³Â···ÉÉÉÃÃþ¾¾¸¸¸°°°±±±°°°³³³´´´·········¸¸¸ººº¼¼¼ÂÂÂÃÃÃÃÃÃÃÃÃÀÀÀ¾¾¾ººº······´´´³³³±±±´´´·········´´´···¸¸¸ÆÆÆÍÍÍ××׿¿¿ÀÀÀÉÉÉÆÆÆÃÃÃÃÃÃÅÅÅÑÑÑÜÜÜØØØÃÃõµµ°°°···ÃÃÃÃÃÿ¿¿¼¼¼¾¾¾ÂÂÂÆÆÆÆÆÆÅÅÅÉÉÉÎÎÎÇÇÇÅÅźººÃÃÿ¿¿»»»ÎÎÎàààæææãããâââÜÜÜÙÙÙâââçççÝÝÝâââçççêêêÕÕÕ³³³³³³¸¸¸ººº»»»¾¾¾ÂÂÂÆÆÆÉÉÉÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÉÉÉÉÉÉÉÉÉÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÀÀÀÂÂÂØØØòòòòòòäääâââäääçççäääÜÜÜÙÙÙÜÜÜÛÛÛÕÕÕÛÛÛÔÔÔÝÝÝêêêçççãããâââÙÙÙèèèèèèçççäääääääääæææççççççæææâââßßßÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝàààæææãããçççïïïëëëêêêêêêàààØØØÒÒÒÎÎÎÍÍÍÒÒÒÛÛÛ×××ÒÒÒÒÒÒÒÒÒÉÉɺºº¸¸¸ÀÀÀ»»»ÅÅÅ¿¿¿ÀÀÀÅÅÅÀÀÀÃÃÃÅÅÅÉÉÉÇÇÇÆÆÆÇÇÇÊÊÊÍÍÍÌÌÌÊÊÊÆÆÆÃÃþ¾¾¸¸¸´´´±±±±±±°°°¯¯¯­­­¯¯¯³³³···ºººººº······µµµ´´´···¾¾¾ÃÃÃÅÅÅÃÃÃÆÆÆÅÅÅÎÎÎÎÎÎÎÎÎÔÔÔÍÍÍÅÅű±±ÀÀÀÒÒÒÑÑÑÔÔÔ³³³Â»»»ÊÊÊÃÃü¼¼ººº´´´···³³³´´´µµµ¸¸¸¸¸¸¸¸¸¸¸¸ººº¼¼¼ÂÂÂÂÂÂÃÃÃÃÃþ¾¾»»»¸¸¸µµµ³³³°°°¯¯¯±±±´´´µµµ···´´´¸¸¸»»»ÆÆÆÊÊÊÑÑѺºººººÃÃÃÌÌÌÇÇÇÀÀÀ¼¼¼ÅÅÅØØØÙÙÙÛÛÛÃÃñ±±¯¯¯ÇÇÇÒÒÒÐÐп¿¿ÅÅÅ¿¿¿¿¿¿ÃÃÃÇÇÇÊÊÊÊÊÊÃÃÃÇÇÇÇÇÇÉÉÉÅÅÅÎÎÎÉÉɼ¼¼»»»ÌÌÌÔÔÔÜÜÜçççæææãããîîîäääæææãããÝÝÝÝÝÝÍÍ͵µµ¸¸¸¸¸¸¸¸¸ººº¼¼¼ÀÀÀÅÅÅÉÉÉÌÌÌÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÅÅÅÆÆÆÇÇÇÉÉÉÇÇÇÇÇÇÆÆÆÆÆÆÆÆÆÇÇÇÇÇÇÇÇÇÂÂÂÒÒÒëëëñññëëëèèèçççëëëçççßßß×××ÔÔÔÕÕÕ×××ÕÕÕÙÙÙÕÕÕÜÜÜçççæææàààÝÝÝÜÜÜíííêêêçççäääããããããããããããäääâââÝÝÝÛÛÛÙÙÙÛÛÛÜÜÜÝÝÝàààÝÝÝæææäääèèèòòòëëëíííëëëÝÝÝÒÒÒÎÎÎÐÐÐÐÐÐÒÒÒ×××ÀÀÀ···±±±···»»»»»»¼¼¼ÀÀÀÀÀÀÊÊÊÃÃÃÆÆÆÆÆÆ¼¼¼ÀÀÀÅÅÅÆÆÆÆÆÆÆÆÆÇÇÇÊÊÊÊÊÊÊÊÊÉÉÉÆÆÆÃÃÿ¿¿ººº······¸¸¸¸¸¸´´´µµµ···ººº»»»¼¼¼»»»»»»···µµµµµµºººÀÀÀÅÅÅÅÅÅÂÂÂÅÅÅÆÆÆÍÍÍÉÉÉÍÍÍÎÎκºº´´´µµµÂÂÂÒÒÒÔÔÔÕÕÕ³³³ÆÆÆ¸¸¸ÊÊÊÃÃû»»ºººµµµººº···µµµ···¸¸¸ººº¸¸¸¸¸¸»»»¼¼¼ÀÀÀÂÂÂÃÃÃÃÃÿ¿¿¼¼¼ººº¸¸¸µµµ³³³±±±´´´¸¸¸ººº»»»¸¸¸¾¾¾¿¿¿ÉÉÉÊÊÊÐÐз··¸¸¸¼¼¼ÌÌÌÌÌÌÍÍÍÆÆÆÀÀÀÍÍÍÑÑÑÕÕÕ···°°°ÇÇÇÑÑÑØØØÑÑÑÆÆÆÃÃÃÂÂÂÂÂÂÅÅÅÉÉÉÌÌÌÍÍÍÐÐÐÌÌÌÍÍÍÎÎÎÊÊÊÍÍÍÍÍÍÅÅÅ¿¿¿¸¸¸ªªªµµµÑÑÑØØØÔÔÔÝÝÝÙÙÙâââÙÙÙ×××ÑÑѺºº­­­···µµµµµµ···ººº¾¾¾ÃÃÃÇÇÇÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÌÌÌÊÊÊÇÇÇÅÅÅÃÃÃÅÅÅÆÆÆÇÇÇÇÇÇÉÉÉÜÜÜîîîîîîîîîòòòòòòêêêâââÛÛÛ×××ÕÕÕÔÔÔÔÔÔÕÕÕÕÕÕÔÔÔ×××ßßßäääßßßßßßèèèîîîëëëèèèäääãããâââààààààÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜâââÛÛÛääääääêêêòòòëëëïïïàààÕÕÕÎÎÎÒÒÒØØØØØØÔÔÔÒÒÒºººµµµµµµ¸¸¸»»»¼¼¼ÀÀÀÅÅÅÃÃÃÇÇǾ¾¾ÅÅÅÊÊÊ¿¿¿ÃÃÃÆÆÆÂÂÂÃÃÃÆÆÆÇÇÇÉÉÉÉÉÉÉÉÉÇÇÇÇÇÇÅÅÅÀÀÀ¼¼¼»»»»»»¾¾¾¿¿¿¸¸¸»»»¼¼¼¾¾¾¿¿¿¾¾¾¾¾¾¾¾¾···µµµ···»»»ÂÂÂÆÆÆÃÃÃÀÀÀ¿¿¿ÅÅÅÌÌÌÇÇÇÑÑÑÑÑÑ···´´´···¾¾¾ÊÊÊÒÒÒÔÔÔÀÀÀ±±±ÇÇÇ´´´ÉÉÉÅÅż¼¼¸¸¸µµµººº¸¸¸µµµ¸¸¸ºººººº¸¸¸ººº»»»¼¼¼ÀÀÀÂÂÂÃÃÃÃÃÃÃÃÃÀÀÀ¾¾¾»»»¿¿¿»»»¸¸¸¸¸¸»»»¾¾¾ÀÀÀ»»»ÀÀÀÅÅÅÍÍÍÍÍÍÒÒÒ»»»¾¾¾ÂÂÂÍÍÍÌÌÌÒÒÒÌÌ̼¼¼ÉÉÉÐÐÐÕÕÕÅÅÅÀÀÀ···»»»¯¯¯¼¼¼ÊÊÊÇÇÇÅÅÅÃÃÃÂÂÂÅÅÅÉÉÉÍÍÍÐÐÐÒÒÒÌÌÌÔÔÔÙÙÙÐÐÐÆÆÆÉÉÉÊÊÊÃÃÃÅÅźºº³³³´´´¬¬¬³³³ÒÒÒÔÔÔÜÜÜÔÔÔÜÜÜÔÔÔªªª¥¥¥¸¸¸³³³³³³´´´···»»»ÀÀÀÆÆÆÉÉÉÌÌÌÌÌÌÌÌÌÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÑÑÑÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÊÊÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÌÌÌÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÎÎÎÌÌÌÇÇÇÃÃÃÂÂÂÃÃÃÆÆÆÇÇÇàààëëëíííëëëîîîèèèßßßÝÝÝâââÙÙÙ×××ÛÛÛÛÛÛ×××ÔÔÔÕÕÕÑÑÑÒÒÒÑÑÑÙÙÙãããßßßâââõõõîîîèèèãããàààâââàààÝÝÝÙÙÙØØØÛÛÛ×××ØØØßßßàààÜÜÜßßßäääæææææææææíííõõõñññçççÕÕÕÔÔÔÔÔÔÕÕÕØØØÕÕÕÌÌÌÅÅž¾¾¼¼¼»»»¼¼¼¿¿¿ÃÃÃÇÇÇÊÊÊÃÃÃÀÀÀÂÂÂÉÉÉÌÌÌÇÇÇÃÃÃÃÃÃÉÉÉÉÉÉÊÊÊÌÌÌÌÌÌÊÊÊÊÊÊÉÉÉÆÆÆÅÅż¼¼µµµ···¿¿¿Â¿¿¿¿¿¿¾¾¾¾¾¾¿¿¿ÂÂÂÃÃÃÀÀÀ¿¿¿¾¾¾ÂÂÂÃÃþ¾¾¾¾¾ÂÂÂÇÇÇÂÂÂÅÅÅÊÊÊÆÆÆÑÑÑÒÒÒ»»»»»»»»»¸¸¸¿¿¿¼¼¼ÒÒÒµµµÃÃõµµÂÂÂÆÆÆ¾¾¾»»»¿¿¿¼¼¼´´´¸¸¸¸¸¸ººº»»»¼¼¼¾¾¾¿¿¿¿¿¿ÆÆÆÂÂÂÀÀÀÂÂÂÀÀÀ»»»¸¸¸¼¼¼»»»¾¾¾¾¾¾ÀÀÀÅÅž¾¾¼¼¼ÆÆÆÃÃþ¾¾ÃÃÃÅÅÅÎÎÎÎÎλ»»¿¿¿ÆÆÆÐÐÐ×××ÔÔÔÊÊÊÂÂÂÀÀÀÅÅÅÌÌÌ×××àààèèèÙÙÙÇÇDZ±±ÊÊÊÇÇÇÍÍÍÐÐÐÌÌÌÐÐÐÕÕÕÑÑÑØØØÎÎÎÎÎÎÑÑÑÐÐÐÔÔÔÒÒÒÉÉÉÇÇÇÃÃþ¾¾»»»ººº···±±±­­­ÙÙÙÒÒÒâââÔÔÔ¯¯¯···ªªª³³³´´´»»»¸¸¸µµµ¿¿¿ÆÆÆÃÃÃÃÃÃÐÐÐÐÐÐÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÑÑÑÒÒÒÑÑÑÎÎÎÉÉÉÆÆÆÉÉÉÎÎÎÎÎÎÊÊÊÉÉÉÌÌÌÇÇǼ¼¼¿¿¿ÃÃÃÆÆÆÀÀÀÃÃÃèèèõõõúúúïïïîîîää䨨ØßßßÛÛÛÔÔÔÜÜÜÜÜÜÜÜÜàààÛÛÛØØØàààÔÔÔÐÐÐÒÒÒ×××èèèçççÛÛÛóóóëëëçççãããâââàààßßßÛÛÛ×××ÐÐÐÙÙÙÙÙÙØØØÜÜÜÑÑÑÆÆÆÆÆÆÝÝÝâââæææèèèëëëëëëçççãããØØØÛÛÛàààäääãããØØØÇÇÇ»»»ÀÀÀÀÀÀÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÇÇÇÅÅÅÂÂÂÃÃÃÂÂÂÂÂÂÆÆÆÍÍÍÆÆÆÉÉÉÍÍÍÐÐÐÐÐÐÌÌÌÇÇÇÅÅÅÆÆÆÃÃþ¾¾¸¸¸ºººÀÀÀÃÃÃÀÀÀÅÅÅÃÃÃÀÀÀÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÆÆÆÀÀÀ¼¼¼¼¼¼ÀÀÀÅÅÅÃÃÃÂÂÂÇÇÇÇÇÇÌÌÌÆÆÆÍÍÍÑÑѼ¼¼µµµ»»»¾¾¾»»»ÂÂÂÒÒÒ¼¼¼¼¼¼¾¾¾»»»Â¼¼¼ººº¾¾¾¾¾¾¸¸¸ºººººº»»»¼¼¼¾¾¾¾¾¾¿¿¿¿¿¿ÅÅÅÂÂÂÂÂÂÃÃÿ¿¿ººº¸¸¸»»»ÂÂÂÃÃÃÅÅÅÉÉÉÍÍÍÍÍÍÊÊÊÉÉÉÇÇÇ¿¿¿ÂÂÂÅÅÅÐÐÐÎÎμ¼¼ÂÂÂÇÇÇÎÎÎÔÔÔÑÑÑÆÆÆ¾¾¾¾¾¾ÀÀÀÃÃÃÊÊÊÉÉÉÍÍÍÑÑÑÜÜÜàààÊÊÊÀÀÀ¼¼¼ÊÊÊØØØÔÔÔÊÊÊÌÌÌÍÍÍãããÍÍÍÍÍÍÜÜÜØØØÍÍÍÍÍÍÒÒÒÆÆÆÂ¾¾¾¼¼¼¾¾¾¾¾¾ºººµµµ¬¬¬­­­ÑÑÑÔÔÔ¬¬¬³³³¬¬¬°°°³³³ººº¸¸¸···ÀÀÀÇÇÇÆÆÆÉÉÉÐÐÐÐÐÐÎÎÎÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÐÐÐÑÑÑÑÑÑÐÐÐÐÐÐÒÒÒÍÍÍÉÉÉÉÉÉÊÊÊÊÊÊÊÊÊÌÌÌÆÆÆÐÐÐÝÝÝäääîîîíííêêêöööêêêêêêàààààààààÝÝÝäääâââßßßàààØØØÒÒÒØØØÙÙÙØØØÜÜÜÕÕÕÒÒÒÒÒÒÕÕÕæææèèèßßßñññæææäääãããâââßßßÜÜÜØØØÕÕÕ×××ßßßØØØ×××âââÛÛÛÌÌÌÎÎÎàààãããêêêïïïëëëâââÝÝÝÝÝÝàààààààààÝÝÝÙÙÙÑÑÑÉÉÉÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÃÃÃÃÃÃÇÇÇÇÇÇÅÅÅÆÆÆÉÉÉÉÉÉÌÌÌÎÎÎÑÑÑÐÐÐÌÌÌÇÇÇÃÃÃÃÃÃÃÃÿ¿¿¼¼¼¾¾¾ÂÂÂÃÃÃÂÂÂÃÃÃÃÃÿ¿¿¼¼¼»»»»»»¼¼¼Â¿¿¿¼¼¼¾¾¾ÂÂÂÅÅÅ¿¿¿¿¿¿ÀÀÀÊÊÊÉÉÉÍÍÍÕÕÕÅÅű±±µµµ¾¾¾¸¸¸ÃÃÃÊÊÊ´´´¾¾¾µµµÃÃÃÀÀÀ¾¾¾»»»»»»¼¼¼¾¾¾¾¾¾»»»»»»¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÅÅÅÃÃÃÅÅÅÅÅÅÀÀÀ»»»ººº¼¼¼¿¿¿ÅÅÅÉÉÉÆÆÆÂÂÂÆÆÆÐÐÐ×××ÍÍÍÃÃÃÃÃÃÉÉÉÑÑÑÌÌ̾¾¾ÆÆÆÎÎÎÔÔÔ×××ÑÑÑÆÆÆ¿¿¿¾¾¾ÀÀÀ¾¾¾ÉÉÉÅÅÅ¿¿¿ÅÅÅÙÙÙàààÅÅÅÃÃû»»ÀÀÀÎÎÎÑÑÑÐÐÐÕÕÕÛÛÛÙÙÙÐÐÐØØØçççää䨨ØÔÔÔ×××ÊÊÊÆÆÆÂÂÂÂÂÂÃÃÃÃÃÃÀÀÀ¾¾¾³³³±±±×××ÜÜÜ­­­±±±´´´¸¸¸´´´»»»¼¼¼¼¼¼ÂÂÂÇÇÇÉÉÉÌÌÌÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÍÍÍÌÌÌÊÊÊÊÊÊÍÍÍÎÎÎÌÌÌÉÉÉ»»»âââøøøøøøóóóññññññîîîíííçççÙÙÙØØØÛÛÛÛÛÛßßßÛÛÛããããããØØØÎÎÎÒÒÒØØØÕÕÕÒÒÒÕÕÕÕÕÕÒÒÒÑÑÑâââêêêãããîîîããããããâââàààÝÝÝÙÙÙØØØ×××ÔÔÔÑÑѾ¾¾¿¿¿ÜÜÜãããÙÙÙÝÝÝãããÝÝÝàààæææâââÔÔÔÎÎÎÒÒÒãããàààØØØÎÎÎÇÇÇÅÅÅÆÆÆÉÉÉÇÇÇÆÆÆÅÅÅÅÅÅÇÇÇÊÊÊÍÍÍÐÐÐÇÇÇÃÃÃÅÅÅÌÌÌÐÐÐÌÌÌÆÆÆÃÃÃÐÐÐÎÎÎÍÍÍÌÌÌÊÊÊÉÉÉÇÇÇÇÇÇÂÂÂÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿ÃÃÃÇÇÇÉÉÉÇÇÇÅÅÅÃÃÃÅÅÅÃÃÃÊÊÊÐÐÐÎÎÎÆÆÆÃÃÃÆÆÆÌÌÌÒÒÒÎÎÎÎÎÎÉÉÉÍÍÍâââäääÑÑѵµµ»»»ÆÆÆÇÇÇÀÀÀ···»»»»»»ÇÇÇ¿¿¿»»»¼¼¼¿¿¿¼¼¼¾¾¾ÀÀÀ¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÅÅÅÇÇÇÇÇÇÃÃÃÀÀÀÀÀÀÂÂÂÆÆÆÉÉÉÃÃúºº´´´°°°···ÆÆÆÍÍÍÉÉÉÉÉÉÎÎÎÐÐÐÃÃü¼¼ÉÉÉÒÒÒÔÔÔÔÔÔÎÎÎÆÆÆ¿¿¿¾¾¾¿¿¿ÇÇÇÙÙÙÙÙÙÎÎÎÇÇÇÒÒÒßßßÍÍÍÇÇÇÃÃÃÃÃÃÇÇÇÎÎÎÕÕÕÔÔÔÍÍÍÙÙÙæææèèèÝÝÝ×××ÛÛÛÙÙÙÍÍÍÑÑÑÌÌÌÇÇÇÅÅÅÆÆÆÅÅÅ¿¿¿···´´´ÍÍÍÕÕÕ¯¯¯°°°°°°¸¸¸···¼¼¼ÀÀÀÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÍÍÍÐÐÐÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÐÐÐÆÆÆÌÌÌÐÐÐÐÐÐÍÍÍÊÊÊÆÆÆÀÀÀÃÃÃëëëüüüüüüóóóñññúúúñññïïïêêêâââàààâââäääèèèèèèÛÛÛâââßßßÕÕÕÕÕÕÙÙÙÕÕÕÌÌÌÕÕÕØØØÒÒÒÎÎÎÝÝÝèèèçççëëëäääãããâââßßßÛÛÛØØØ××××××ÔÔÔÐÐп¿¿ÀÀÀÜÜÜäääÝÝÝààà×××ÉÉÉÃÃÃÌÌÌÍÍÍÆÆÆÂÂÂÇÇÇÃÃÃÆÆÆÊÊÊÌÌÌÌÌÌÎÎÎÔÔÔØØØÎÎÎÎÎÎÍÍÍÌÌÌÊÊÊÌÌÌÍÍÍÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÍÍÍÇÇÇÇÇÇÊÊÊÐÐÐÎÎÎÍÍÍÊÊÊÉÉÉÇÇÇÆÆÆÆÆÆÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÀÀÀÀÀÀÀÀÀÃÃÃÆÆÆÊÊÊÊÊÊÇÇÇÅÅÅÅÅÅÅÅż¼¼ÃÃÃÆÆÆ¼¼¼­­­©©©±±±¾¾¾ÌÌÌÍÍÍÍÍÍÊÊÊÌÌÌÜÜÜÝÝÝÆÆÆ¸¸¸»»»ØØØÌÌÌ»»»ÃÃúººÊÊÊÆÆÆ¾¾¾»»»ÀÀÀ¾¾¾¾¾¾ÂÂÂÀÀÀÀÀÀÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÃÃÃÂÂÂÆÆÆÉÉÉÊÊÊÉÉÉÇÇÇÇÇÇÇÇÇÍÍÍÃÃñ±±¯¯¯ººº±±±¬¬¬ºººÊÊÊÐÐÐÐÐÐÑÑÑÊÊÊ»»»»»»ÉÉÉÐÐÐÑÑÑÐÐÐÊÊÊÅÅÅ¿¿¿¾¾¾¿¿¿ÇÇÇÕÕÕØØØÒÒÒÆÆÆÍÍÍâââßßßÊÊÊÉÉÉÅÅÅÂÂÂÆÆÆÍÍÍÑÑÑÕÕÕÒÒÒÛÛÛÕÕÕÃÃÃÂÂÂÒÒÒâââæææÒÒÒÍÍÍÇÇÇÆÆÆÇÇÇÇÇÇÅÅż¼¼¼¼¼ÌÌÌßßßÍÍÍÃÃð°°´´´µµµºººÀÀÀÆÆÆÇÇÇÉÉÉÌÌÌÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒÒÒÒÒÒÒÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÐÐÐÒÒÒÔÔÔÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÍÍÍÐÐÐÑÑÑÌÌÌÅÅÅÂÂÂÅÅÅÇÇÇèèèöööõõõøøøöööóóóöööçççÝÝÝÜÜÜÛÛÛÔÔÔÐÐÐÎÎÎÐÐÐÒÒÒÒÒÒßßßäääÜÜÜÕÕÕØØØØØØÑÑÑÔÔÔÙÙÙÒÒÒÎÎÎÙÙÙäääêêêèèèæææäääâââÝÝÝÛÛÛÕÕÕÑÑÑÎÎκºº¿¿¿¿¿¿ÀÀÀÆÆÆÂººº¸¸¸ÇÇǺºº´´´¾¾¾ÆÆÆÆÆÆÆÆÆÌÌÌÌÌÌÎÎÎÑÑÑÑÑÑÎÎÎÍÍÍÎÎÎÐÐÐÕÕÕÕÕÕÒÒÒÐÐÐÍÍÍÉÉÉÆÆÆÃÃÃÉÉÉÐÐÐÙÙÙÛÛÛÑÑÑÆÆÆÆÆÆÍÍÍÉÉÉÊÊÊÌÌÌÌÌÌÊÊÊÆÆÆÃÃÃÀÀÀÂÂÂÀÀÀÂÂÂÂÂÂÀÀÀ¼¼¼¼¼¼¿¿¿ÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÂÂÂÃÃÃÅÅÅÑÑÑÍÍ͵µµ¬¬¬¬¬¬µµµ¾¾¾ÐÐÐÝÝÝãããèèèçççàààÒÒÒµµµ³³³ºººÒÒÒÃÃ÷··ÆÆÆ···ÍÍÍÅÅÅ¿¿¿¾¾¾ÂÂÂÃÃÿ¿¿¿¿¿ÃÃÃÂÂÂÂÂÂÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÃÃÃÇÇÇÊÊÊÊÊÊÌÌÌÎÎÎÌÌÌÉÉÉÔÔÔÊÊÊ···¯¯¯´´´´´´ºººÌÌÌÉÉÉÒÒÒÍÍÍÊÊÊÃÃ÷··¾¾¾ÊÊÊÔÔÔÔÔÔÒÒÒÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÉÉÉÍÍÍÎÎÎÒÒÒÉÉÉÆÆÆÑÑÑÍÍÍÛÛÛ×××ÒÒÒÐÐÐÌÌÌÅÅÅÐÐÐäääÔÔÔÊÊÊÂÂÂÂÂÂÀÀÀ¾¾¾ÊÊÊãããÑÑÑÍÍÍÇÇÇÆÆÆÉÉÉÊÊÊÊÊÊÇÇǸ¸¸µµµ»»»ØØØ×××ÌÌÌ´´´´´´µµµ´´´¼¼¼ÆÆÆÇÇÇÊÊÊÐÐÐÑÑÑÍÍÍÍÍÍÍÍÍÎÎÎÐÐÐÑÑÑÒÒÒÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕ××××××××××××ÔÔÔÔÔÔÕÕÕÔÔÔÒÒÒÐÐÐÐÐÐÐÐÐÑÑÑÊÊÊÅÅÅÃÃÃÃÃÃÊÊÊÙÙÙèèèüüüøøøóóóöööïïïæææãããÛÛÛàààßßßâââØØØÎÎÎÌÌÌÆÆÆÌÌÌÑÑÑÙÙÙâââÜÜÜÒÒÒÕÕÕÜÜÜÛÛÛÒÒÒØØØÑÑÑÑÑÑ×××ßßßèèèæææçççäääâââßßßÙÙÙÑÑÑÆÆÆ¾¾¾¸¸¸¼¼¼ÆÆÆÇÇǾ¾¾···´´´°°°¾¾¾···¸¸¸ÀÀÀÉÉÉÊÊÊÍÍÍÒÒÒÕÕÕÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÒÒÒÔÔÔÔÔÔÑÑÑÍÍÍÉÉÉÇÇÇÇÇÇÊÊÊÌÌÌÎÎÎÒÒÒÛÛÛàààÛÛÛÎÎÎÆÆÆÆÆÆÆÆÆÇÇÇÉÉÉÉÉÉÇÇÇÅÅÅ¿¿¿ÂÂÂÀÀÀÀÀÀ¾¾¾¸¸¸¸¸¸¼¼¼¾¾¾¿¿¿ÂÂÂÆÆÆÊÊÊÌÌÌÊÊÊÉÉÉÃÃû»»°°°ªªªªªª°°°´´´···ÊÊÊ×××ÑÑÑÑÑÑÑÑÑÇÇÇÀÀÀ±±±°°°ÃÃþ¾¾¼¼¼¼¼¼ÇÇÇÂÂÂÉÉÉÃÃÃÂÂÂÀÀÀÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÉÉÉÊÊÊÉÉÉÍÍÍÐÐÐÊÊÊÃÃÃÒÒÒÑÑÑÎÎξ¾¾ªªª³³³ÉÉÉÐÐÐÊÊÊÑÑÑ»»»¼¼¼ºººÆÆÆÊÊÊÒÒÒÒÒÒÒÒÒÒÒÒÔÔÔÒÒÒÑÑÑÐÐÐÒÒÒÔÔÔÔÔÔÙÙÙÑÑÑÊÊÊÎÎÎÃÃÃÝÝÝâââãããçççâââÍÍÍÂÂÂÌÌÌÅÅÅÀÀÀÀÀÀÌÌÌÍÍÍ¿¿¿ÀÀÀØØØÕÕÕÐÐÐÊÊÊÇÇÇÊÊÊÌÌÌÌÌÌÊÊÊÀÀÀ´´´µµµÛÛÛâââãããÙÙÙÜÜÜ¿¿¿···ºººÂÂÂÂÂÂÇÇÇÐÐÐÑÑÑÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÒÒÒÔÔÔÕÕÕ××××××ØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØ×××ÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÎÎÎÌÌÌ¿¿¿¼¼¼ÍÍÍÜÜÜãããîîîúúúõõõíííõõõöööêêêääääääèèèÎÎÎÊÊÊÑÑÑÌÌÌÌÌÌÐÐÐÊÊÊÐÐÐÑÑÑÒÒÒÙÙÙÙÙÙÒÒÒÕÕÕÝÝÝÜÜÜÐÐÐÕÕÕÐÐÐÔÔÔ×××ÙÙÙçççæææèèèæææãããàààÙÙÙÍÍ;¾¾±±±ºººµµµ¼¼¼¿¿¿µµµ···¾¾¾¸¸¸´´´···¼¼¼ÃÃÃÆÆÆÇÇÇÊÊÊÎÎÎÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÍÍÍÆÆÆ¿¿¿»»»¿¿¿ÊÊÊ×××àààãããØØØÑÑÑÕÕÕÛÛÛ×××ÍÍÍÅÅÅÉÉÉÇÇÇÅÅÅÃÃÃÂÂÂÂÂÂÂÂÂÃÃÿ¿¿¿¿¿ÀÀÀ¼¼¼µµµµµµ»»»ÃÃÃÆÆÆÉÉÉÌÌÌÉÉɾ¾¾°°°¦¦¦ªªª¨¨¨¦¦¦ªªª°°°µµµ···µµµ¸¸¸ÅÅŸ¸¸¸¸¸¾¾¾´´´´´´±±±···×××´´´ÂÂÂÍÍÍÐÐÐ×××ÌÌÌÂÂÂÃÃÃÃÃÃÀÀÀ¿¿¿ÀÀÀÅÅÅÇÇÇÅÅÅÅÅÅÅÅÅÅÅÅÆÆÆÆÆÆÆÆÆÆÆÆÉÉÉÊÊÊÉÉÉÇÇÇÌÌÌÎÎÎÇÇǾ¾¾¯¯¯···ÎÎÎÊÊʵµµÊÊÊßßßÊÊÊÌÌÌÐÐи¸¸°°°¸¸¸¿¿¿ÌÌÌÊÊÊÆÆÆÇÇÇÉÉÉÊÊÊÍÍÍÎÎÎÍÍÍÊÊÊÌÌÌÎÎÎÊÊÊÌÌÌÇÇÇÊÊÊØØØÑÑÑÆÆÆÎÎÎÐÐÐØØØäääàààÍÍÍÃÃÃÊÊÊÔÔÔÒÒÒÍÍÍÌÌÌÅÅÅ¿¿¿ÆÆÆÛÛÛÕÕÕÎÎÎÊÊÊÊÊÊÌÌÌÉÉÉÇÇÇÇÇdz³³´´´ÛÛÛÛÛÛÝÝÝÛÛÛÙÙÙÊÊʼ¼¼ººº¾¾¾¼¼¼ÂÂÂÌÌÌÍÍÍÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÒÒÒÕÕÕ×××ØØØØØØÙÙÙÙÙÙÛÛÛÛÛÛÛÛÛÜÜÜÙÙÙØØØÕÕÕÕÕÕ×××ÕÕÕÑÑÑÎÎÎÉÉɼ¼¼ÂÂÂâââøøøöööîîîîîîùùùçççíííêêêàààâââÜÜÜßßßÑÑÑÇÇÇÌÌÌÇÇÇÌÌÌÒÒÒÊÊÊÍÍÍÐÐÐÌÌÌÔÔÔÙÙÙ×××ØØØÛÛÛØØØÎÎÎÔÔÔÐÐÐÕÕÕÕÕÕÕÕÕææææææÝÝÝÝÝÝãããÛÛÛÒÒÒÇÇǵµµ´´´µµµ»»»ÀÀÀÂÂÂÀÀÀ¾¾¾»»»»»»¸¸¸»»»¾¾¾ÂÂÂÇÇÇÍÍÍÒÒÒ××××××àààÜÜÜÒÒÒÔÔÔÕÕÕÒÒÒ××׿¿¿ÊÊÊÊÊÊÃÃû»»´´´µµµÇÇÇÌÌÌÉÉÉÍÍÍãããÕÕÕÐÐÐÀÀÀÅÅÅÃÃÃÂÂÂÀÀÀ¾¾¾¾¾¾¼¼¼¼¼¼»»»ÀÀÀÃÃÿ¿¿ººº¸¸¸······»»»ÊÊÊÎÎξ¾¾¯¯¯­­­¯¯¯­­­ªªª©©©¸¸¸¾¾¾¬¬¬¬¬¬ºººººº¿¿¿´´´···¼¼¼······¾¾¾¿¿¿ÍÍͼ¼¼ÀÀÀººº···ÊÊÊÌÌ̾¾¾ÀÀÀÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÅÅÅÅÅÅÉÉÉÉÉÉÅÅÅÅÅÅÌÌÌÉÉÉÇÇÇÒÒÒÒÒÒÅÅÅÐÐÐÉÉÉÌÌÌÑÑѸ¸¸µµµººº¿¿¿ÍÍÍÔÔÔÐÐÐÐÐÐÑÑÑÌÌÌØØØÊÊÊ»»»···¾¾¾ÅÅÅÆÆÆÃÃÃÀÀÀÃÃÃÃÃÃÅÅÅÅÅż¼¼ºººÅÅÅÃÃÿ¿¿ÀÀÀÅÅÅÃÃÃÆÆÆÐÐÐÐÐп¿¿ÆÆÆ×××êêêÆÆÆÉÉÉÙÙÙêêêèèèãããÕÕÕÅÅÅÀÀÀºººÔÔÔÐÐÐ×××ÑÑÑÍÍÍÎÎÎÆÆÆÍÍÍÊÊÊÀÀÀ···´´´ÐÐÐäääÛÛÛààààààÑÑÑ»»»···¾¾¾¾¾¾ÂÂÂÒÒÒÌÌÌÅÅÅÉÉÉÉÉÉÍÍÍÒÒÒÎÎÎÔÔÔÔÔÔÔÔÔÕÕÕØØØÛÛÛÜÜÜÝÝÝßßßÛÛÛÑÑÑÑÑÑ××××××ÙÙÙÔÔÔÆÆÆ¼¼¼ÇÇÇæææøøøòòòõõõõõõäääâââäääëëëäääããããããÑÑÑÆÆÆÉÉÉÊÊÊÊÊÊÌÌÌÌÌÌÍÍÍÎÎÎÎÎÎÎÎÎÑÑÑÊÊÊÙÙÙçççÛÛÛÒÒÒÒÒÒÕÕÕÐÐÐÍÍÍÎÎÎÑÑÑ×××âââîîîèèèßßßàààØØØÌÌ̾¾¾³³³»»»¼¼¼¿¿¿Â¿¿¿¼¼¼»»»»»»¼¼¼¼¼¼¿¿¿ÅÅÅÊÊÊÎÎÎÎÎÎÍÍÍÃÃÃÍÍÍÌÌÌÆÆÆÉÉÉÊÊÊÇÇÇÊÊÊÅÅÅÍÍÍÌÌÌÅÅÅÆÆÆÅÅÅ¿¿¿ÀÀÀ¾¾¾¼¼¼¾¾¾ÌÌÌãããÔÔÔÐÐÐÉÉÉÃÃÃÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾Â¼¼¼ººº¼¼¼»»»···¸¸¸¼¼¼¿¿¿Â¾¾¾±±±­­­±±±´´´±±±ªªª­­­ÂÂÂÌÌ̺ºº±±±¸¸¸¸¸¸»»»¸¸¸¿¿¿ÃÃø¸¸µµµÃÃÃÎÎμ¼¼¸¸¸¸¸¸ÂÂÂÉÉÉÎÎÎÎÎÎÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÇÇÇÊÊÊÇÇÇÉÉÉÍÍÍÉÉÉÊÊÊÕÕÕÜÜÜÐÐÐØØØÑÑÑÐÐÐÎÎεµµµµµ¾¾¾¼¼¼ººº¿¿¿ÍÍÍÕÕÕÕÕÕÒÒÒÅÅž¾¾¸¸¸¼¼¼ÅÅÅÉÉÉÆÆÆÀÀÀ¿¿¿ÀÀÀ»»»»»»ÂÂÂÃÃÃÅÅÅÐÐÐÔÔÔÒÒÒÃÃÃÀÀÀÅÅÅ¿¿¿ÃÃÃÍÍÍÕÕÕÑÑÑÐÐÐÊÊÊÌÌÌãããÑÑÑØØØãããâââÝÝÝäääßßßÑÑÑÌÌÌ¿¿¿ÇÇÇÍÍÍÙÙÙÒÒÒÑÑÑ×××ÎÎÎÍÍÍÊÊÊÅÅÅ»»»´´´ÇÇÇßßßâââãããßßßàààÝÝÝØØØÍÍÍ»»»···ÆÆÆÆÆÆÆÆÆÊÊÊÃÃÃÆÆÆÒÒÒÒÒÒÕÕÕÑÑÑÔÔÔ×××ÕÕÕÔÔÔÕÕÕÙÙÙÝÝÝßßßÙÙÙàààäääÛÛÛÑÑÑÌÌÌÅÅÅÎÎÎÝÝÝñññõõõíííêêêèèèäääßßßÝÝÝãããÛÛÛ××××××ÍÍÍÌÌÌÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÍÍÍÍÍÍÍÍÍÊÊÊÍÍÍÊÊÊÛÛÛâââ×××ÒÒÒÑÑÑÐÐÐÍÍÍÌÌÌÎÎÎÑÑÑÔÔÔÜÜÜæææçççßßßÝÝÝÍÍͼ¼¼······ÂÂÂÂÂÂÂÂÂÃÃÃÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿¼¼¼ÃÃÃÊÊÊÉÉÉÅÅÅÅÅÅÊÊÊÑÑÑÇÇÇÎÎÎÍÍÍÉÉÉÉÉÉÆÆÆÃÃÃÃÃÃÅÅÅÐÐÐÔÔÔÔÔÔÙÙÙÒÒÒÅÅž¾¾ÃÃÃÀÀÀ»»»ÃÃÃÕÕÕÍÍÍÍÍÍÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¿¿¿¿¿¿¿¿¿ÀÀÀÅÅż¼¼¼¼¼ÃÃÿ¿¿´´´³³³»»»ÊÊÊ»»»­­­­­­µµµ¼¼¼¸¸¸°°°¯¯¯­­­ÀÀÀÐÐÐÀÀÀ´´´¸¸¸»»»¾¾¾¾¾¾Âººº¸¸¸ÂÂÂÉÉÉÃÃúººÊÊÊÔÔÔÆÆÆÃÃþ¾¾ÂÂÂÂÂÂÂÂÂÂÂÂÃÃÃÅÅÅÇÇÇÇÇÇÇÇÇÌÌÌÌÌÌÌÌÌÌÌÌÊÊÊÍÍÍØØØÙÙÙÍÍÍÕÕÕÑÑÑÐÐÐÎÎο¿¿ÆÆÆÃÃÃÃÃø¸¸µµµÌÌÌÛÛÛ×××ÒÒÒ¼¼¼»»»¼¼¼ÂÂÂÉÉÉÊÊÊÅÅž¾¾¾¾¾¿¿¿¸¸¸¸¸¸ÆÆÆÑÑÑÔÔÔØØØÜÜÜßßß»»»ÅÅž¾¾ÀÀÀÌÌÌÐÐÐÐÐÐÕÕÕÎÎÎÅÅÅâââÜÜÜâââÎÎÎÅÅÅÃÃÃÔÔÔÛÛÛßßßâââÍÍÍ»»»ÇÇÇ×××ÒÒÒÔÔÔÜÜÜÕÕÕÍÍÍÊÊÊÉÉÉ¿¿¿ººº¼¼¼ÑÑÑçççäääæææîîîñññêêêØØØÅÅÅÅÅÅÕÕÕääääääâââÉÉÉÀÀÀÍÍÍÍÍÍÎÎÎÎÎÎÑÑÑÕÕÕ×××ØØØÙÙÙÜÜÜßßßÛÛÛÜÜÜããããããÒÒÒÅÅÅÆÆÆÉÉÉâââòòòùùùòòòçççààààààæææñññæææäääÙÙÙÑÑÑÍÍÍÇÇÇÐÐÐÊÊÊÊÊÊÊÊÊÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÆÆÆÆÆÆÌÌÌÝÝÝÜÜÜÑÑÑÔÔÔÐÐÐÌÌÌÊÊÊÌÌÌÐÐÐÑÑÑÐÐÐÕÕÕÜÜÜÛÛÛÜÜÜßßßÅÅű±±ººº¿¿¿ÂÂÂÃÃÃÃÃÃÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀ¾¾¾ÅÅÅÊÊÊÇÇÇÂÂÂÃÃÃÍÍÍ×××ÕÕÕ×××ÕÕÕÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÑÑÑÙÙÙØØØÕÕÕÛÛÛ×××ÊÊÊÃÃÃÌÌÌÍÍÍÀÀÀ¼¼¼ÆÆÆÊÊÊÎÎÎÀÀÀÃÃÃÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÃÃÃÃÃÿ¿¿ÂÂÂÅÅž¾¾´´´···Â¾¾¾´´´°°°···¼¼¼¾¾¾¼¼¼¾¾¾¸¸¸¬¬¬³³³ÀÀÀ»»»³³³ºººÀÀÀÆÆÆÆÆÆÃÃÃÀÀÀÅÅÅÎÎÎÌÌÌ¿¿¿ÌÌÌ¿¿¿¸¸¸ÌÌÌÑÑÑÃÃÃÃÃÃÆÆÆÃÃÃÂÂÂÂÂÂÀÀÀÂÂÂÅÅÅÉÉÉÊÊÊÉÉÉÍÍÍÎÎÎÍÍÍÊÊÊÌÌÌÒÒÒÛÛÛ¿¿¿µµµ¼¼¼»»»»»»»»»¸¸¸ÅÅÅÃÃÃÊÊÊÅÅŸ¸¸ÂÂÂÕÕÕÔÔÔÀÀÀ¾¾¾¾¾¾¾¾¾ÂÂÂÇÇÇÊÊÊÇÇÇÅÅż¼¼ÀÀÀ»»»¼¼¼ÐÐÐÜÜÜÛÛÛØØØ×××ÝÝݼ¼¼µµµÇÇÇÀÀÀÂÂÂÌÌÌÉÉÉÆÆÆÎÎÎÑÑÑÅÅÅÛÛÛÕÕÕÕÕÕÌÌÌÉÉÉÆÆÆÉÉÉÇÇÇØØØãããÆÆÆºººÂÂÂÍÍÍÎÎÎÑÑÑ×××ÔÔÔÑÑÑÍÍÍÇÇÇÀÀÀÀÀÀ···ÃÃÃææææææêêêêêêëëëêêêãããÝÝÝâââîîîëëëíííëëëÔÔÔÅÅÅÇÇÇÀÀÀÂÂÂÍÍÍÎÎÎÑÑÑ×××ÜÜÜÝÝÝÜÜÜÙÙÙâââàààÙÙÙÌÌÌÂÂÂÉÉÉÛÛÛêêêïïïöööùùùïïïãããàààäääçççæææÔÔÔÐÐÐÌÌÌÊÊÊÉÉÉÇÇÇÔÔÔÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÃÃÃÃÃÃÍÍÍßßßÙÙÙÎÎÎÕÕÕÑÑÑÊÊÊÉÉÉÍÍÍÑÑÑÒÒÒÎÎÎÐÐÐÔÔÔÙÙÙÝÝÝæææÍÍ͵µµ¼¼¼ÃÃÃÅÅÅÆÆÆÆÆÆÅÅÅÃÃÃÃÃÃÀÀÀ¿¿¿¾¾¾Â¿¿¿¿¿¿ÅÅÅÍÍÍÑÑÑÑÑÑÎÎÎÐÐÐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÒÒÒÛÛÛØØØÕÕÕÙÙÙ×××ÍÍÍÉÉÉÉÉÉÊÊÊ¿¿¿ÃÃÃÉÉÉÐÐÐÔÔÔÇÇÇÅÅÅÃÃÃÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÆÆÆÃÃÃÀÀÀ¾¾¾¼¼¼¼¼¼¿¿¿ÃÃÃÆÆÆ´´´ºººÃÃÃÉÉɾ¾¾ÌÌÌÝÝÝÉÉɳ³³­­­···¸¸¸´´´ºººÂÂÂÂÂÂÆÆÆÀÀÀ»»»ÉÉÉØØØÍÍÍ´´´ÑÑѸ¸¸ÀÀÀÎÎÎÇÇÇÃÃÃÂÂÂÇÇÇÃÃÃÃÃÃÂÂÂÂÂÂÃÃÃÇÇÇÊÊÊÌÌÌÍÍÍÎÎÎÎÎÎÌÌÌÉÉÉÍÍÍÕÕÕÙÙÙÃÃÃÀÀÀÇÇÇÇÇÇÃÃÃÀÀÀ¾¾¾ÆÆÆÀÀÀÆÆÆÇÇǸ¸¸···ÕÕÕØØØ³³³¼¼¼¼¼¼¾¾¾¿¿¿ÂÂÂÅÅÅÇÇÇÇÇǾ¾¾ÀÀÀ»»»¼¼¼ÎÎÎÛÛÛ×××ÒÒÒÐÐÐÙÙÙÀÀÀ¼¼¼ÐÐÐÊÊÊÃÃÃÊÊÊÌÌÌÅÅÅÊÊÊÕÕÕÃÃÃÉÉÉÃÃÃÉÉÉÙÙÙÙÙÙØØØÒÒÒÃÃÃÌÌÌßßßÎÎÎÃÃÃÂÂÂÂÂÂÉÉÉÊÊÊÇÇÇÍÍÍÔÔÔÐÐÐÅÅÅÂÂÂÇÇÇ···¼¼¼àààçççææææææëëëñññïïïíííîîîïïïñññòòòùùùîîîßßßÑÑÑÀÀÀ¾¾¾µµµ»»»ÃÃÃÉÉÉÍÍÍÒÒÒØØØÝÝÝÜÜÜßßß×××ÊÊÊÐÐÐãããóóóùùùöööñññóóóîîîàààãããêêêàààãããÌÌÌÆÆÆÆÆÆÊÊÊÊÊÊÅÅÅÎÎÎÊÊÊÊÊÊÊÊÊÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÂÂÂÂÂÂÌÌÌßßßÙÙÙÎÎÎ×××ÒÒÒÌÌÌÌÌÌÐÐÐÔÔÔÔÔÔÐÐÐÐÐÐÒÒÒæææßßßêêêÝÝÝ»»»¿¿¿ÇÇÇÌÌÌÉÉÉÆÆÆÃÃÿ¿¿»»»¸¸¸¼¼¼¾¾¾ÃÃÃÌÌÌÒÒÒÔÔÔÐÐÐÊÊÊÎÎÎÇÇÇÊÊÊÎÎÎÌÌÌÊÊÊÊÊÊÇÇÇÊÊÊÕÕÕØØØÕÕÕØØØ×××ÐÐÐÎÎÎÇÇÇÀÀÀ¼¼¼ÔÔÔÔÔÔÐÐÐÍÍÍÉÉÉÅÅÅÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÆÆÆÅÅÅÀÀÀÀÀÀÅÅÅÅÅż¼¼°°°µµµ´´´´´´µµµ³³³³³³¼¼¼ÉÉÉÕÕÕ¸¸¸¼¼¼¿¿¿»»»¼¼¼ÂÂÂÌÌÌÒÒÒÍÍÍÅÅÅÌÌÌÑÑÑÃÃó³³ÌÌ̸¸¸ÊÊÊÑÑÑÃÃÿ¿¿ÀÀÀÃÃÃÃÃÃÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÐÐÐÍÍÍÍÍÍÌÌÌÊÊÊÑÑÑÕÕÕÑÑÑ¿¿¿ÆÆÆÎÎÎÐÐÐÌÌÌÇÇÇÅÅÅÅÅÅÉÉÉÃÃÃÅÅÅ»»»¼¼¼àààççç»»»¿¿¿ÀÀÀÂÂÂÀÀÀ¼¼¼ºººººº»»»¼¼¼¼¼¼µµµ¸¸¸ÇÇÇÐÐÐÎÎÎÎÎÎÒÒÒÙÙÙÐÐÐÊÊÊØØØÕÕÕÃÃÃÅÅÅÆÆÆÅÅÅÇÇÇÔÔÔÃÃÃÂÂÂÂÂÂÑÑÑÑÑÑÐÐÐÒÒÒØØØÊÊÊÇÇÇÝÝÝäääÑÑÑÉÉÉ¿¿¿ÆÆÆÅÅž¾¾ÉÉÉÔÔÔÑÑÑÃÃÃÃÃÃÇÇÇ»»»ÃÃÃâââêêêëëëíííóóóõõõëëëæææèèèèèèëëëèèèòòòóóóòòòñññçççëëëëëëïïïñññäääÔÔÔÊÊÊÍÍÍÔÔÔÎÎÎÔÔÔÎÎÎÍÍÍÝÝÝñññõõõòòòøøøíííïïïëëëÜÜÜàààçççÙÙÙçççÑÑÑÌÌÌÊÊÊÍÍÍÊÊÊ¿¿¿ÅÅÅÊÊÊÉÉÉÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÂÂÂÃÃÃÇÇÇÙÙÙÛÛÛÑÑÑ×××ÔÔÔÑÑÑÐÐÐÑÑÑÔÔÔÒÒÒÐÐÐÑÑÑ×××êêêÜÜÜçççßß߸¸¸¾¾¾ÇÇÇÌÌÌÇÇÇ¿¿¿¿¿¿¿¿¿¾¾¾¼¼¼»»»ÃÃÃÍÍÍÐÐÐÍÍÍÊÊÊÌÌÌÎÎÎÎÎÎÇÇÇÍÍÍÔÔÔÐÐÐÌÌÌÉÉÉÂÂÂÑÑÑÙÙÙÔÔÔÊÊÊÊÊÊÍÍÍÔÔÔÝÝÝÊÊÊ¿¿¿»»»ÙÙÙÒÒÒÉÉÉÅÅÅÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÆÆÆÅÅÅÅÅÅÇÇÇÃÃúºº°°°¬¬¬ÎÎθ¸¸ºººÂÂÂÆÆÆÃÃÃÀÀÀÕÕÕÍÍÍÇÇÇÆÆÆÅÅÅÂÂÂÆÆÆÍÍÍßßßßßßØØØÕÕÕ×××ÌÌÌÂÂÂÅÅŸ¸¸»»»ÉÉÉÌÌÌÂÂÂÃÃÃÆÆÆÅÅÅÃÃÃÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÊÊÊÌÌÌÎÎÎÐÐÐÕÕÕÒÒÒÅÅÅÅÅÅÎÎÎÒÒÒÐÐÐÐÐÐÔÔÔÕÕÕÒÒÒÎÎÎÅÅÅÅÅÅÃÃÃÅÅÅÛÛÛßßßÅÅÅÆÆÆÇÇÇÆÆÆÀÀÀººº···¸¸¸¼¼¼µµµ···µµµ¼¼¼ÊÊÊÌÌÌÉÉÉÍÍÍÒÒÒÕÕÕÜÜÜÔÔÔÛÛÛÛÛÛÀÀÀ¿¿¿ººº¿¿¿¼¼¼ÊÊÊÇÇÇÌÌÌÊÊÊ×××ÇÇÇÅÅÅÃÃÃÒÒÒÎÎÎÅÅÅÒÒÒÜÜÜÛÛÛÕÕÕÇÇÇÇÇÇÅÅž¾¾ÌÌÌÒÒÒÐÐÐÆÆÆÇÇÇÀÀÀ¾¾¾ÔÔÔêêêññññññïïïóóóîîîàààßßßçççêêêîîîçççêêêæææêêêòòòíííëëëîîîòòòòòòêêêÛÛÛÌÌÌÃÃÃÂÂÂÍÍÍÇÇǾ¾¾ÅÅÅÜÜÜêêêîîîòòòñññííííííää䨨ØÛÛÛßßßÙÙÙÎÎÎÃÃÃÆÆÆÅÅÅÆÆÆÆÆÆÀÀÀÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÀÀÀÑÑÑÛÛÛÒÒÒÒÒÒÔÔÔÕÕÕÑÑÑÑÑÑÑÑÑÑÑÑÐÐÐÔÔÔÙÙÙâââØØØãããÕÕÕººº¸¸¸¿¿¿ÅÅÅÆÆÆÂ¼¼¼»»»¾¾¾ÀÀÀÃÃÃÅÅÅÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÇÇÇÊÊÊÎÎÎÆÆÆ¿¿¿ÉÉÉ×××ÔÔÔÐÐÐÍÍÍÅÅÅÐÐÐÛÛÛÙÙÙÍÍÍÉÉÉÉÉÉÎÎÎÙÙÙÇÇÇ¿¿¿¸¸¸ÑÑÑÉÉÉÇÇÇÇÇÇÃÃÃÂÂÂÀÀÀ¿¿¿¿¿¿¾¾¾¿¿¿¿¿¿¿¿¿Â¿¿¿ÀÀÀ¿¿¿³³³©©©´´´ÉÉɸ¸¸······»»»ÀÀÀÃÃÿ¿¿ÎÎÎÐÐÐÍÍÍÇÇÇÃÃÃÃÃÃÎÎÎÜÜÜÒÒÒÉÉÉÂÂÂÍÍÍÒÒÒÀÀÀ»»»ÌÌ̼¼¼ÎÎÎÌÌÌÆÆÆ¾¾¾¸¸¸ÀÀÀ¼¼¼ÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÍÍÍÎÎÎÎÎÎÍÍÍÇÇÇÌÌÌÑÑÑÔÔÔØØØÑÑÑ»»»ÂÂÂÌÌÌÆÆÆ¼¼¼»»»ÆÆÆÑÑÑÎÎÎÇÇÇÂÂÂÅÅÅÇÇÇÃÃÃÃÃÃÃÃþ¾¾ÃÃÃÅÅÅÅÅÅ¿¿¿»»»¿¿¿ÉÉÉÒÒÒ¯¯¯´´´»»»ÇÇÇÔÔÔÎÎÎÉÉÉÎÎÎÐÐÐÎÎÎàààÕÕÕØØØÜÜܾ¾¾»»»µµµ¿¿¿´´´ÃÃÃÍÍÍ×××ÊÊÊÊÊʾ¾¾¿¿¿¼¼¼ÊÊÊÒÒÒÎÎÎÑÑÑÒÒÒÝÝÝßßßÐÐÐÌÌÌÆÆÆÃÃÃÑÑÑÐÐÐÍÍÍÊÊÊÌÌ̺ºº¾¾¾ãããóóóöööêêêçççëëëëëëãããæææîîîëëëêêêëëëñññêêêïïïùùùêêêÜÜÜÜÜÜÝÝÝäääîîîóóóëëëØØØÇÇÇ¿¿¿»»»¾¾¾×××ñññîîîäääêêêçççíííëëëßßß××××××ÙÙÙßßßÌÌÌÇÇÇÐÐÐÌÌÌÆÆÆÆÆÆÃÃÃÎÎÎÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÂÂÂÀÀÀ¿¿¿ÀÀÀÃÃû»»ÊÊÊÛÛÛÒÒÒÐÐÐÒÒÒ×××ÒÒÒÐÐÐÐÐÐÎÎÎÎÎÎÔÔÔÜÜÜâââÜÜÜèèèÔÔÔ···»»»¾¾¾¼¼¼ÆÆÆ»»»ºººººº···¾¾¾ÅÅÅÂÂÂÃÃÃÊÊÊÍÍÍÌÌÌÌÌÌÎÎÎÌÌÌÆÆÆÉÉÉÍÍÍÑÑÑÑÑÑÎÎÎÍÍÍÎÎÎÑÑÑÝÝÝÑÑÑÌÌÌÔÔÔÕÕÕÎÎÎÌÌÌÐÐÐÑÑÑÜÜÜÔÔÔ¾¾¾ÉÉÉÔÔÔÅÅÅÆÆÆÂ¼¼¼»»»¿¿¿ÂÂÂÀÀÀ¿¿¿Â¼¼¼ÆÆÆÀÀÀ°°°­­­ººº¿¿¿¸¸¸¼¼¼µµµµµµ´´´°°°»»»ÍÍÍÑÑÑÀÀÀÍÍÍÙÙÙßßßÜÜÜ×××ÔÔÔÔÔÔÅÅż¼¼ººº¾¾¾ÀÀÀ¿¿¿ÀÀÀÆÆÆ»»»ÆÆÆÌÌÌÇÇÇÀÀÀÀÀÀÂÂÂÃÃÿ¿¿ÍÍÍÇÇÇÊÊÊÎÎÎÇÇÇÊÊÊÐÐÐÊÊÊÌÌÌÉÉÉØØØÒÒÒÕÕÕÉÉÉÊÊÊÐÐÐÅÅÅÅÅÅÍÍÍÉÉÉ¿¿¿ÅÅÅÒÒÒÆÆÆÇÇÇÇÇÇÆÆÆÆÆÆÅÅÅÅÅÅÇÇÇÃÃÃÆÆÆÊÊÊÃÃø¸¸ÕÕÕÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÇÇÇÉÉÉÊÊÊÍÍÍÎÎÎØØØÎÎÎÙÙÙ×××´´´¼¼¼ÜÜÜØØØÎÎÎÂÂÂÀÀÀÇÇÇÉÉÉÅÅÅÂÂÂÔÔÔÑÑÑÃÃÃÊÊÊÕÕÕÑÑÑÉÉÉÕÕÕäääÍÍÍÊÊÊÃÃÿ¿¿ÝÝÝÔÔÔÑÑÑÍÍÍÆÆÆ···çççëëëïïïèèèïïïîîîêêêæææèèèïïïòòòïïïõõõíííñññîîîëëëæææÙÙÙÛÛÛ×××ÙÙÙâââíííòòòñññêêêäääÇÇÇ­­­¾¾¾ãããæææàààèèèíííçççîîîëëëßßßØØØØØØÕÕÕÍÍÍÎÎÎÉÉÉÍÍÍÎÎÎÆÆÆÅÅÅÆÆÆ¿¿¿ÆÆÆÇÇÇÇÇÇÅÅÅÂÂÂÀÀÀÂÂÂÅÅÅ¿¿¿ÃÃÿ¿¿ÇÇÇÕÕÕ×××ÎÎÎÉÉÉÌÌÌÒÒÒ×××ÒÒÒÍÍÍÎÎÎÔÔÔäääÛÛÛâââ×××¼¼¼¸¸¸ÀÀÀ¿¿¿ººº¾¾¾Â¿¿¿ÃÃÃÆÆÆ¿¿¿ÉÉÉÊÊÊÉÉÉÇÇÇÆÆÆÉÉÉÊÊÊÉÉÉÔÔÔÑÑÑÍÍÍÇÇÇÃÃÃÆÆÆÍÍÍÔÔÔÝÝÝÔÔÔÐÐÐÑÑÑÑÑÑÉÉÉÂÂÂÂÂÂÊÊÊÔÔÔ×××ÀÀÀºººÊÊÊÌÌÌÉÉÉÉÉÉÆÆÆÂ¿¿¿ÀÀÀÃÃÃÆÆÆÇÇÇÇÇǾ¾¾³³³°°°³³³¸¸¸¼¼¼¾¾¾µµµ¾¾¾ÌÌÌÊÊʺºº¸¸¸ÆÆÆÍÍͼ¼¼ÃÃÃÌÌÌÐÐÐÐÐÐÊÊÊÃÃÿ¿¿ÉÉÉÅÅÅ¿¿¿»»»¼¼¼ÀÀÀÅÅÅÆÆÆÒÒÒÒÒÒÍÍÍÅÅÅÂÂÂÃÃÃÅÅÅÂÂÂÆÆÆÌÌÌÆÆÆÌÌÌÒÒÒÎÎÎÐÐÐÌÌÌÀÀÀÎÎÎÑÑÑÒÒÒÃÃÃÉÉÉÊÊÊÐÐÐÅÅÅÂÂÂÊÊÊÕÕÕÑÑÑÅÅÅÂÂÂÉÉÉÔÔÔÔÔÔÔÔÔÕÕÕÔÔÔÍÍÍÆÆÆÀÀÀÂÂÂÅÅÅÉÉÉÅÅż¼¼×××ÑÑÑÌÌÌÌÌÌÍÍÍÌÌÌÊÊÊÆÆÆÆÆÆÇÇÇÉÉÉÇÇÇÊÊÊÕÕÕÎÎÎÙÙÙÕÕÕµµµ»»»ÕÕÕ×××ÕÕÕÎÎÎÅÅÅÀÀÀÉÉÉÑÑÑÑÑÑ××××××ÐÐÐÍÍÍÔÔÔÒÒÒÊÊÊÎÎÎàààÍÍÍÍÍÍÃÃþ¾¾ÙÙÙÒÒÒÊÊÊÆÆÆ¿¿¿ÀÀÀçççîîîëëëëëëññññññïïïëëëëëëïïïïïïíííïïïàààÝÝÝÝÝÝâââæææÜÜÜÝÝÝäääâââÜÜÜØØØÝÝÝçççëëëêêêÛÛÛÆÆÆÍÍÍääääääÝÝÝâââçççòòòòòòêêêÜÜÜ×××ØØØÔÔÔÊÊÊÆÆÆÃÃÃÇÇÇÉÉÉÂÂÂÃÃÃÇÇÇÃÃÃÉÉÉÉÉÉÉÉÉÇÇÇÅÅÅÂÂÂÀÀÀÀÀÀÂÂÂÅÅÅ¿¿¿ÆÆÆÕÕÕÙÙÙÕÕÕÔÔÔÑÑÑÐÐÐÎÎÎÉÉÉÆÆÆÍÍÍÕÕÕßßßØØØÛÛÛÜÜÜÅÅŵµµ¼¼¼¼¼¼ÅÅż¼¼ººººººººº¿¿¿ÆÆÆÆÆÆÉÉÉÅÅÅÃÃÃÃÃÃÆÆÆÇÇÇÌÌÌÐÐÐÕÕÕÐÐÐÉÉÉÂÂÂÀÀÀÆÆÆÎÎÎÔÔÔàààØØØÑÑÑÐÐÐÑÑÑÑÑÑÑÑÑÒÒÒ»»»ÇÇÇÕÕÕÆÆÆ¿¿¿ÌÌÌÇÇÇÂÂÂÃÃÃÅÅÅÆÆÆÆÆÆÉÉÉÍÍÍÒÒÒÕÕÕ¼¼¼ºººµµµµµµ¼¼¼ÀÀÀ¾¾¾···´´´ÀÀÀÐÐÐÎÎξ¾¾»»»ÉÉÉÒÒÒÇÇÇ»»»ººº¾¾¾ÇÇÇÎÎÎÑÑÑÎÎÎÕÕÕÔÔÔÍÍÍÉÉÉÊÊÊÇÇÇÀÀÀÙÙÙÒÒÒÇÇÇÂÂÂÅÅÅÊÊÊÊÊÊÆÆÆÀÀÀÅÅÅÆÆÆÑÑÑÔÔÔÒÒÒØØØÐÐÐÙÙÙÎÎο¿¿ÃÃÃÇÇÇÐÐÐÅÅž¾¾»»»ÃÃÃÐÐÐÛÛÛÛÛÛÎÎÎÆÆÆÇÇÇÇÇÇÇÇÇÌÌÌÐÐÐÔÔÔÕÕÕÑÑÑÊÊÊÅÅÅÆÆÆÅÅÅÃÃü¼¼ÔÔÔÐÐÐÉÉÉÉÉÉÉÉÉÇÇÇÆÆÆÃÃÃÃÃÃÆÆÆÇÇÇÊÊÊÍÍÍ×××ÑÑÑ×××ÐÐб±±´´´ÒÒÒÒÒÒÕÕÕÕÕÕÍÍÍÅÅÅÌÌÌÙÙÙÔÔÔÌÌÌÑÑÑ×××ÑÑÑÒÒÒØØØÔÔÔÇÇÇÝÝÝÎÎÎÑÑÑÆÆÆ¾¾¾ÒÒÒÒÒÒÐÐÐÊÊÊ¿¿¿×××îîîùùùñññùùùõõõöööóóóëëëæææäääàààÜÜÜâââÜÜÜàààÛÛÛ×××ØØØØØØãããÝÝÝââââââÙÙÙÙÙÙãããëëëîîîñññææææææííííííääääääëëëããããããÜÜÜÔÔÔÔÔÔ×××ÎÎÎÃÃÃÇÇÇÆÆÆÉÉÉÇÇÇÂÂÂÀÀÀÅÅÅÃÃÿ¿¿¼¼¼ºººººº»»»¾¾¾¿¿¿ÀÀÀÅÅÅÆÆÆÃÃü¼¼¿¿¿ÌÌÌÒÒÒÒÒÒÒÒÒÑÑÑÑÑÑÐÐÐÊÊÊÆÆÆÇÇÇÌÌÌÔÔÔØØØÙÙÙàààÎÎκºº»»»°°°´´´³³³³³³µµµººº¿¿¿ÃÃÃÃÃÃÇÇÇ¿¿¿ÅÅÅÇÇÇÅÅÅÇÇÇÌÌÌÍÍÍÌÌÌÉÉÉÉÉÉÊÊÊÍÍÍÐÐÐÑÑÑÒÒÒÕÕÕØØØÙÙÙØØØÔÔÔÊÊÊÂÂÂÍÍÍÍÍÍÆÆÆ¸¸¸¾¾¾ÇÇÇÃÃÃÍÍͼ¼¼¸¸¸···±±±¬¬¬¯¯¯µµµ­­­»»»ÆÆÆÅÅÅ»»»···¾¾¾ÅÅÅÆÆÆÉÉÉÍÍÍÉÉÉÀÀÀ¼¼¼¾¾¾ÀÀÀÌÌÌÍÍÍÎÎÎÎÎÎÌÌÌÆÆÆ¿¿¿»»»¿¿¿ÆÆÆÊÊÊÆÆÆÃÃþ¾¾ºººÑÑÑÊÊÊÃÃÃÂÂÂÆÆÆÊÊÊÉÉÉÅÅÅÉÉÉÎÎÎ×××àààÕÕÕÑÑÑÜÜÜ×××ÒÒÒÐÐÐÉÉÉÆÆÆÃÃÃÆÆÆÇÇÇÊÊÊÌÌÌÕÕÕÛÛÛàààâââÜÜÜØØØÝÝÝÎÎÎÌÌÌÌÌÌÉÉÉÅÅÅÊÊÊÎÎÎÊÊÊÉÉÉÇÇÇ¿¿¿¿¿¿¸¸¸ÐÐÐÎÎÎÉÉÉÆÆÆÆÆÆÃÃÃÂÂÂÀÀÀÂÂÂÅÅÅÆÆÆÌÌÌÎÎÎÕÕÕÑÑÑÕÕÕÎÎθ¸¸¸¸¸ÔÔÔÎÎÎÍÍÍÑÑÑÕÕÕÔÔÔÒÒÒÔÔÔÎÎÎÃÃÃÇÇÇÔÔÔÒÒÒÎÎÎÔÔÔÙÙÙÉÉÉàààÑÑÑÔÔÔÆÆÆÀÀÀÎÎÎÒÒÒÍÍÍÅÅÅ»»»âââèèèõõõèèèøøøãããççççççâââÝÝÝÝÝÝÝÝÝÜÜÜàààØØØÜÜÜÜÜÜÝÝÝßßßÙÙÙßßßÝÝÝßßßàààßßßÝÝÝÜÜÜÙÙÙØØØãããæææâââàààãããÝÝÝÛÛÛääääääßßß×××ÒÒÒ×××ÛÛÛÔÔÔÉÉÉÉÉÉÊÊÊÍÍÍÌÌÌÆÆÆÃÃÃÅÅÅÅÅÅÉÉÉÀÀÀ···±±±´´´»»»ÂÂÂÆÆÆÆÆÆÇÇÇÃÃû»»¸¸¸¾¾¾ÂÂÂÂÂÂÆÆÆÉÉÉÌÌÌÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÍÍÍØØØÛÛÛàààÕÕÕÊÊÊÇÇǵµµ¯¯¯¯¯¯¬¬¬¯¯¯µµµ»»»¿¿¿Â¼¼¼¼¼¼ÃÃÃÅÅÅÀÀÀ¼¼¼¾¾¾ÌÌÌÍÍÍÎÎÎÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÍÍÍÒÒÒØØØÛÛÛÛÛÛØØØÐÐÐÇÇÇÌÌÌÉÉÉÑÑÑ×××ØØØÉÉɳ³³µµµ¼¼¼°°°¯¯¯···¸¸¸´´´¾¾¾ÑÑѺºººººÂÂÂÀÀÀ¸¸¸¿¿¿ÐÐÐÅÅÅÇÇÇÉÉÉÊÊÊÌÌÌÇÇÇ¿¿¿ººº¾¾¾ÀÀÀÂÂÂÀÀÀÂÂÂÊÊÊÕÕÕßßß¾¾¾»»»»»»¼¼¼¼¼¼¾¾¾ÅÅÅÍÍÍÎÎÎÊÊÊÅÅÅÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÐÐÐÔÔÔ×××ÛÛÛÎÎÎÆÆÆÐÐÐÇÇÇÅÅÅÇÇÇÉÉÉÆÆÆÊÊÊÎÎÎ×××ØØØÐÐÐÒÒÒÉÉÉÃÃÃÆÆÆÆÆÆÌÌÌÙÙÙÜÜÜÛÛÛÙÙÙÎÎÎÀÀÀÃÃÃÍÍÍÊÊÊÀÀÀ¼¼¼ÃÃþ¾¾ÐÐÐÐÐÐÆÆÆÅÅÅÂÂÂÀÀÀ¿¿¿¿¿¿ÂÂÂÃÃÃÅÅÅÇÇÇÉÉÉÎÎÎÍÍÍÒÒÒÒÒÒÉÉÉÊÊÊÎÎÎÊÊÊÇÇÇÉÉÉÒÒÒÛÛÛÕÕÕÊÊÊÐÐÐÉÉÉÆÆÆÎÎÎÔÔÔÊÊÊÉÉÉØØØÍÍÍçççÕÕÕÔÔÔÆÆÆÉÉÉÎÎÎÒÒÒÉÉÉÃÃÃÅÅÅîîîêêêïïïâââëëëãããæææãããÜÜÜ×××××××××ÕÕÕÝÝÝÕÕÕÙÙÙÙÙÙÛÛÛÝÝÝÙÙÙàààßßßÕÕÕÐÐÐÔÔÔÙÙÙØØØÒÒÒÐÐÐÛÛÛäääâââßßßäääßßßÛÛÛãããêêêàààÔÔÔÍÍÍÑÑÑÕÕÕÑÑÑÉÉÉÆÆÆÉÉÉÊÊÊÊÊÊÇÇÇÅÅÅÂÂÂÃÃü¼¼µµµ­­­ªªª¯¯¯···¿¿¿ÅÅÅÂÂÂÆÆÆÅÅÅ¿¿¿ººº¸¸¸¸¸¸¸¸¸ÕÕÕÔÔÔÐÐÐÍÍÍÊÊÊÊÊÊÇÇÇÆÆÆÌÌÌÕÕÕØØØÙÙÙØØØÙÙÙØØØÌÌÌÆÆÆÂ···°°°³³³´´´···»»»´´´³³³···¿¿¿ÅÅÅÅÅÅÂÂÂÀÀÀÕÕÕÕÕÕÔÔÔÑÑÑÎÎÎÍÍÍÌÌÌÌÌÌÔÔÔÒÒÒÒÒÒÕÕÕ××××××ØØØÛÛÛØØØÂÂÂÉÉÉÍÍÍÃÃÃÆÆÆÐÐÐÜÜÜÛÛÛÐÐÐÎÎÎÔÔÔÎÎμ¼¼¸¸¸ÀÀÀÉÉÉ»»»µµµ¾¾¾ÆÆÆÆÆÆÃÃÃÃÃþ¾¾ÃÃÃÅÅÅÆÆÆÌÌÌÌÌÌÌÌÌÑÑÑ­­­»»»ÍÍÍØØØØØØÕÕÕÒÒÒÔÔÔÔÔÔÍÍÍÌÌÌÐÐÐÐÐÐÌÌÌÐÐÐÙÙÙÍÍÍÉÉÉÅÅÅÃÃÃÅÅÅÆÆÆÍÍÍÒÒÒÑÑÑÎÎÎÇÇÇÍÍÍÍÍÍÉÉÉÍÍÍÂÂÂÑÑѼ¼¼¾¾¾ÌÌÌÛÛÛÎÎÎÑÑÑÙÙÙàààÛÛÛÉÉɾ¾¾ÀÀÀ¿¿¿ÉÉÉàààÕÕÕÕÕÕÙÙÙÑÑÑÂÂÂÇÇÇÑÑÑÊÊʵµµ¿¿¿¾¾¾ÎÎÎÇÇÇÒÒÒÐÐÐÃÃÃÃÃÃÀÀÀ¾¾¾¼¼¼¿¿¿ÂÂÂÅÅÅÆÆÆÊÊÊÊÊÊÊÊÊÉÉÉÌÌÌÍÍÍÊÊÊÍÍÍÃÃÃÆÆÆÅÅÅÂÂÂÇÇÇÐÐÐÐÐÐÉÉÉÊÊÊÌÌÌÆÆÆÌÌÌÕÕÕÐÐÐÎÎÎÝÝÝÐÐÐííí×××ÑÑÑÆÆÆÔÔÔÑÑÑÑÑÑÆÆÆÇÇÇÛÛÛøøøïïïíííãããßßßÛÛÛÝÝÝÝÝÝÙÙÙÙÙÙßßßâââààààààØØØÙÙÙÒÒÒÌÌÌÌÌÌÌÌÌØØØÙÙÙÙÙÙÜÜÜÜÜÜØØØÒÒÒÕÕÕÙÙÙÌÌÌÔÔÔÔÔÔÒÒÒÕÕÕÐÐÐÊÊÊÐÐÐ×××ÒÒÒÐÐÐÐÐÐÒÒÒÑÑÑÊÊÊÂÂÂÉÉÉÌÌÌÇÇÇÃÃÃÃÃþ¾¾······±±±¯¯¯¬¬¬¬¬¬¯¯¯±±±´´´µµµ»»»¿¿¿ÅÅÅÃÃÃÀÀÀ¾¾¾»»»¸¸¸ÂÂÂÅÅÅÇÇÇÊÊÊÐÐÐÔÔÔÒÒÒÍÍÍÌÌÌÌÌÌÑÑÑÔÔÔØØØÜÜÜ×××ÔÔÔÐÐÐÒÒÒÌÌÌÇÇÇÉÉÉ······µµµ···ººº¿¿¿ÇÇÇÐÐÐÑÑÑÎÎÎØØØØØØÕÕÕÐÐÐÊÊÊÉÉÉÊÊÊÎÎÎÒÒÒÐÐÐÒÒÒØØØÒÒÒÇÇÇ¿¿¿¿¿¿âââÑÑÑÛÛÛØØØÇÇÇÇÇÇÅÅÅÀÀÀ»»»»»»¿¿¿ÅÅÅÅÅž¾¾···µµµ···ÀÀÀÇÇÇÅÅÅÀÀÀÀÀÀ¿¿¿ÆÆÆÊÊÊÆÆÆÀÀÀÂÂÂÃÃÃÇÇÇÒÒÒÊÊÊÎÎÎÒÒÒÕÕÕÔÔÔÒÒÒÔÔÔ×××ÕÕÕÒÒÒÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÃÃÃÀÀÀÅÅÅÊÊÊÌÌÌÐÐÐÕÕÕ×××ÕÕÕÇÇÇÊÊÊÒÒÒÑÑÑÒÒÒÍÍÍÉÉÉÃÃÃÒÒÒ×××ÎÎα±±ÀÀÀßßßÕÕÕÐÐÐÀÀÀ¼¼¼ÀÀÀ»»»ÂÂÂÜÜÜ×××ÑÑÑÔÔÔÍÍÍ¿¿¿ÅÅÅÉÉɺºº¾¾¾ÉÉÉÆÆÆÕÕÕÌÌÌÐÐÐÎÎÎÀÀÀÅÅÅÀÀÀ¼¼¼¼¼¼¿¿¿ÃÃÃÆÆÆÇÇÇÍÍÍÌÌÌÇÇÇÅÅÅÂÂÂÀÀÀÂÂÂÀÀÀ¾¾¾¿¿¿¿¿¿¾¾¾¾¾¾ÂÂÂÆÆÆÉÉÉÅÅÅÆÆÆÇÇÇÉÉÉÐÐÐÕÕÕÙÙÙÝÝÝÍÍÍíííÔÔÔÍÍÍÆÆÆßßßÔÔÔÎÎÎÃÃÃÇÇÇäääëëëæææÝÝÝãããÕÕÕâââäääâââÝÝÝÝÝÝßßßÝÝÝÙÙÙäääÒÒÒÌÌÌÇÇÇÊÊÊÍÍÍÅÅÅÆÆÆÒÒÒäääëëëàààÔÔÔÔÔÔ××××××ÔÔÔ××××××ØØØ×××ÑÑÑÍÍÍÐÐÐÍÍÍÎÎÎÒÒÒÕÕÕ×××ÔÔÔÎÎÎÊÊÊÌÌÌÌÌ̼¼¼ÀÀÀ¾¾¾···¸¸¸ÇÇÇÆÆÆÅÅÅÀÀÀ»»»µµµ³³³³³³³³³¸¸¸¿¿¿ÃÃÃÅÅÅÀÀÀ¼¼¼ººº¸¸¸¾¾¾ÃÃÃÉÉÉÑÑÑ×××ÒÒÒÉÉÉÊÊÊÂÂÂÌÌÌÒÒÒØØØ×××ÉÉÉÍÍÍÑÑÑÕÕÕÐÐÐÎÎÎÕÕÕÒÒÒÍÍÍÐÐÐÊÊÊÊÊÊÇÇÇÅÅÅÌÌÌ×××ØØØÒÒÒÔÔÔÕÕÕÕÕÕÐÐÐÊÊÊÉÉÉÌÌÌÐÐÐ×××ÑÑÑÒÒÒÙÙÙÔÔÔÅÅž¾¾ÂÂÂÙÙÙÕÕÕØØØÒÒÒÕÕÕØØØÅÅŵµµ¾¾¾ÀÀÀ¼¼¼···»»»ÆÆÆÊÊÊÆÆÆÅÅž¾¾»»»¾¾¾ÂÂÂÀÀÀ¾¾¾¾¾¾¼¼¼ÂÂÂÀÀÀ¿¿¿ÆÆÆÅÅÅÂÂÂÉÉÉÍÍÍÎÎÎÒÒÒ×××ÙÙÙ×××ÐÐÐÊÊÊÊÊÊÊÊÊÆÆÆ¿¿¿ÀÀÀÉÉÉÊÊÊÆÆÆÉÉÉÂÂÂÀÀÀÉÉÉÎÎÎÍÍÍÇÇÇÅÅÅÒÒÒ×××ÅÅÅ¿¿¿Â¼¼¼¾¾¾ÀÀÀÃÃÃÌÌÌÔÔÔÃÃÃÃÃÿ¿¿ÊÊÊÇÇÇÆÆÆÆÆÆ¾¾¾ÃÃÃÌÌÌÂÂÂÃÃÃßßßÛÛÛÐÐÐÎÎÎÇÇǾ¾¾ÉÉÉÌÌÌ···ÐÐÐ×××ÍÍÍ×××ÇÇÇÉÉÉÊÊÊ¿¿¿ÅÅÅÀÀÀ¼¼¼»»»¿¿¿ÃÃÃÆÆÆÇÇÇÇÇÇÆÆÆÂÂÂÀÀÀ¼¼¼ººº¾¾¾¼¼¼¿¿¿¸¸¸µµµººº»»»ººº¾¾¾ÆÆÆÆÆÆÆÆÆÊÊÊÉÉÉÆÆÆÒÒÒÛÛÛÒÒÒÇÇÇëëëÑÑÑÉÉÉÇÇÇççç×××ÌÌÌÎÎÎÑÑÑïïïãããàààÙÙÙïïïßßßßßßâââàààßßßßßßàààÜÜÜÕÕÕÍÍÍÅÅÅÊÊÊÊÊÊÍÍÍÐÐÐÉÉÉÎÎο¿¿ÎÎÎÎÎÎÅÅÅÎÎÎçççëëëÛÛÛ×××ÔÔÔÔÔÔ×××ÔÔÔÐÐÐÍÍÍÎÎÎÕÕÕÑÑÑÊÊÊÅÅÅÂÂÂÃÃÃÉÉÉÍÍÍÃÃÃÃÃúºº¸¸¸ÃÃÃÇÇÇÆÆÆÊÊÊÃÃÃÃÃÃÅÅÅÃÃÃÂÂÂÂÂÂÅÅÅÉÉɯ¯¯³³³ºººÀÀÀ¾¾¾ºººµµµ»»»¼¼¼¼¼¼¾¾¾ÇÇÇÒÒÒÔÔÔÎÎÎÑÑÑÉÉÉÎÎÎÎÎÎ×××ßßßÔÔÔÔÔÔÐÐÐÑÑÑÔÔÔÙÙÙÝÝÝÝÝÝÛÛÛ×××ÒÒÒÒÒÒÒÒÒÕÕÕÙÙÙÛÛÛÙÙÙØØØ×××ÎÎÎÍÍÍÒÒÒÔÔÔÎÎÎÍÍÍÑÑÑÎÎÎÕÕÕÕÕÕÍÍÍÅÅÅÂÂÂÃÃÃÃÃÃÂÂÂÇÇÇÎÎÎÑÑÑÐÐÐÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÃÃÿ¿¿¼¼¼¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾ÀÀÀ¿¿¿ÂÂÂÆÆÆÇÇÇÆÆÆÉÉÉÎÎÎÍÍÍÒÒÒººº¸¸¸¿¿¿ÇÇÇØØØÇÇÇÅÅÅÉÉÉÌÌÌÉÉÉÃÃÃÀÀÀÅÅÅÉÉÉÂÂÂÉÉÉÉÉÉÕÕÕÕÕÕÃÃÃÉÉÉØØØ¿¿¿ÉÉÉÒÒÒØØØ×××ÔÔÔÒÒÒÒÒÒÝÝÝÑÑÑÅÅÅÀÀÀÀÀÀÀÀÀÂÂÂÆÆÆÅÅÅÂÂÂÂÂÂÅÅÅÃÃÃÃÃÃÍÍÍØØØÕÕÕÑÑÑÇÇǼ¼¼ÆÆÆÇÇÇ¿¿¿×××ÌÌÌÐÐÐÊÊÊÆÆÆÉÉÉÅÅÅ¿¿¿ÂÂÂÃÃÃÂÂÂÂÂÂÂÂÂÅÅÅÇÇÇÊÊÊÌÌÌÇÇÇÅÅÅÀÀÀ¾¾¾»»»ººººººººººººººººººººº»»»¼¼¼¿¿¿¿¿¿ÂÂÂÇÇÇÍÍÍÉÉÉÅÅÅÒÒÒÛÛÛÐÐÐÒÒÒÒÒÒâââ¼¼¼ÅÅÅàààÜÜÜÎÎÎÉÉÉâââëëë×××ßßßèèèÙÙÙäääÍÍÍÐÐÐÌÌÌÔÔÔßßßíííÐÐÐÊÊÊÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÉÉÉÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÉÉÉâââÝÝÝÐÐÐÊÊÊÐÐÐ×××¼¼¼ÇÇÇÆÆÆÃÃÃÊÊÊÉÉÉÂÂÂÃÃþ¾¾ÊÊÊÑÑÑÌÌÌÊÊÊÎÎÎÐÐÐÌÌÌÃÃÃÃÃÃÂÂÂÂÂÂÂÂÂÃÃÃÃÃÃÅÅÅÃÃÃÃÃô´´µµµ¾¾¾ÂÂÂÇÇÇ···¼¼¼ÆÆÆÃÃÿ¿¿ÇÇÇÎÎÎÎÎÎÐÐÐÐÐÐÇÇÇÍÍÍÍÍÍÔÔÔÛÛÛÒÒÒÔÔÔÔÔÔÒÒÒÑÑÑÑÑÑÕÕÕÙÙÙÜÜÜßßßÛÛÛÕÕÕÎÎÎÌÌÌÍÍÍÔÔÔÙÙÙÝÝÝÔÔÔÑÑÑÌÌÌÊÊÊÌÌÌÑÑÑÔÔÔÕÕÕÒÒÒÕÕÕÒÒÒÇÇǾ¾¾¾¾¾ÀÀÀÃÃÃÑÑÑÒÒÒÒÒÒÎÎÎÉÉÉÅÅÅÂÂÂÀÀÀÃÃÃÃÃÃÂÂÂÂÂÂÀÀÀ¾¾¾¼¼¼»»»¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾ÂÂÂÀÀÀÀÀÀÅÅÅÅÅÅÅÅÅÉÉÉÐÐд´´ÅÅźººººº¸¸¸¼¼¼ÑÑÑÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÔÔÔÀÀÀ¸¸¸ÆÆÆÔÔÔÑÑѾ¾¾ÕÕÕÒÒÒÍÍÍÉÉÉÉÉÉÎÎÎÙÙÙâââÙÙÙÎÎÎÃÃÿ¿¿¼¼¼ºººººº¼¼¼ÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿ÀÀÀÉÉÉÑÑÑÛÛÛÒÒÒÃÃþ¾¾ÇÇÇÃÃü¼¼ÍÍÍÌÌÌÍÍÍÇÇÇÅÅÅÊÊÊÆÆÆÀÀÀÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÅÅÅÆÆÆÉÉÉÊÊÊÅÅÅÃÃÃÀÀÀ¼¼¼ººº¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÀÀÀÃÃÃÆÆÆÌÌÌÊÊÊÆÆÆÑÑÑÙÙÙÕÕÕÑÑÑÔÔÔàààÉÉÉÔÔÔÜÜÜÕÕÕÍÍÍÆÆÆçççëëëÛÛÛàààßßßÐÐÐÙÙÙÑÑÑÔÔÔÎÎÎÎÎÎÒÒÒßßßÌÌÌÌÌÌÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÉÉÉÉÉÉÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÅÅż¼¼ÊÊÊÅÅÅ¿¿¿¼¼¼¿¿¿ÇÇǾ¾¾ÅÅÅÉÉÉÇÇÇÆÆÆÉÉÉÂÂÂÀÀÀÉÉÉÀÀÀÊÊÊÎÎÎÇÇÇÃÃÃÇÇÇÉÉÉÆÆÆÇÇÇÅÅÅ¿¿¿»»»»»»¿¿¿ÃÃÃÆÆÆÆÆÆÉÉɺººµµµ´´´¸¸¸ÆÆÆÂÂÂÃÃÃÉÉÉÅÅÅ¿¿¿ÃÃÃÃÃÃÂÂÂÅÅÅÍÍÍÉÉÉÌÌÌÊÊÊÎÎÎÔÔÔÐÐÐÑÑÑ×××ÔÔÔÑÑÑÎÎÎÐÐÐÔÔÔÙÙÙÝÝÝÕÕÕÔÔÔÔÔÔÕÕÕ××××××ÔÔÔÑÑÑÐÐÐÒÒÒÎÎÎÆÆÆÉÉÉÒÒÒÕÕÕÐÐÐÔÔÔÛÛÛÛÛÛÐÐÐÃÃü¼¼ººº···ÒÒÒÑÑÑÎÎÎÉÉÉÃÃÃÀÀÀ¿¿¿ÀÀÀ¼¼¼»»»»»»»»»ººº»»»»»»»»»¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÃÃÃÀÀÀ¿¿¿ÂÂÂÂÂÂÂÂÂÉÉÉÐÐа°°ÅÅÅÅÅÅÇÇÇÂÂÂÀÀÀÔÔÔÒÒÒÍÍÍÊÊÊÇÇÇÆÆÆÊÊÊÎÎÎÑÑÑÑÑÑØØØÕÕÕÇÇÇÊÊÊÍÍÍÂÂÂÃÃÃÉÉÉÉÉÉÆÆÆÂ¿¿¿¼¼¼¿¿¿ÂÂÂÆÆÆÅÅÅ¿¿¿»»»»»»»»»···¸¸¸»»»¼¼¼¿¿¿¿¿¿»»»¸¸¸¼¼¼ÂÂÂÆÆÆ×××ÑÑÑ¿¿¿ÂÂÂÌÌÌÀÀÀ¸¸¸¾¾¾ÐÐÐÎÎÎÆÆÆÂÂÂÅÅÅÃÃÃÀÀÀÀÀÀ¾¾¾¿¿¿ÀÀÀÃÃÃÅÅÅÅÅÅÆÆÆÆÆÆÀÀÀÀÀÀ¾¾¾¼¼¼ººº¸¸¸···µµµ···¸¸¸¸¸¸ººº¼¼¼¿¿¿ÀÀÀÂÂÂÅÅÅÅÅÅÊÊÊÌÌÌÉÉÉÎÎÎØØØÜÜÜÔÔÔ×××ÙÙÙÑÑÑàààÔÔÔÍÍÍÍÍ;¾¾êêêçççÜÜÜãããÕÕÕÉÉÉÒÒÒÕÕÕ×××ÒÒÒÎÎÎÍÍÍÕÕÕÉÉÉÎÎÎÒÒÒÒÒÒÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÆÆÆÃÃÃÃÃÃÊÊÊÉÉÉÂÂÂÅÅÅÃÃÿ¿¿ÆÆÆÉÉÉÉÉÉÍÍÍÇÇǾ¾¾ÀÀÀÆÆÆÅÅÅÃÃÿ¿¿ÆÆÆÆÆÆ¾¾¾¸¸¸»»»»»»¸¸¸¾¾¾ºººµµµ±±±°°°³³³···ºººÂÂÂÉÉÉ»»»±±±°°°ÀÀÀÉÉÉÀÀÀÃÃÃÀÀÀ¿¿¿ÀÀÀ¿¿¿¿¿¿ÊÊÊÍÍÍÌÌÌÌÌÌÉÉÉÉÉÉÌÌÌÊÊÊÍÍÍÕÕÕÕÕÕ×××ÔÔÔÒÒÒÑÑÑÔÔÔ×××ØØØØØØÙÙÙÜÜÜÝÝÝÛÛÛÕÕÕÑÑÑÌÌÌÑÑÑÑÑÑÍÍÍÍÍÍÐÐÐÊÊÊÀÀÀ»»»ÇÇÇÒÒÒÔÔÔÑÑÑÑÑÑÑÑÑÐÐÐÌÌÌÊÊÊÇÇÇÃÃÃÀÀÀ¿¿¿ÀÀÀÀÀÀ¼¼¼»»»ººº¸¸¸¸¸¸»»»¼¼¼¾¾¾¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿Â¿¿¿¼¼¼¿¿¿¿¿¿ÀÀÀÇÇÇÐÐи¸¸ÆÆÆÇÇÇÌÌÌÇÇÇÂÂÂÍÍÍÍÍÍÀÀÀÉÉÉÒÒÒ×××ÕÕÕÕÕÕÙÙÙÜÜÜ´´´ÊÊÊÇÇÇÃÃÃÆÆÆÎÎÎÝÝÝâââÅÅÅÅÅÅÃÃÃÃÃÃÂÂÂÀÀÀ¾¾¾¼¼¼µµµ³³³´´´¸¸¸¸¸¸···¸¸¸»»»ºººÀÀÀÀÀÀºººµµµººº¾¾¾¼¼¼ÇÇÇÌÌÌ»»»ÀÀÀÊÊÊ»»»°°°ÐÐÐÎÎÎÉÉÉ¿¿¿¾¾¾¾¾¾ÀÀÀ¼¼¼¾¾¾ÀÀÀÃÃÃÃÃÃÃÃÃÃÃþ¾¾¾¾¾¼¼¼»»»ººº···µµµ´´´······¸¸¸ººº¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÅÅÅÉÉÉÍÍÍÊÊÊÌÌÌ×××ãããÔÔÔÛÛÛÑÑÑÍÍÍßßßÉÉÉÇÇÇÊÊÊ···èèèàààÝÝÝæææÐÐÐÊÊÊÕÕÕØØØÔÔÔÔÔÔÐÐÐÐÐÐÕÕÕÍÍÍÐÐÐÑÑÑÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÑÑÑÌÌÌÌÌÌÊÊÊÉÉÉÇÇÇÅÅÅÃÃÃÃÃÃÉÉÉÅÅÅÂÂÂÇÇÇÇÇÇÅÅÅÆÆÆÊÊÊÉÉÉÆÆÆ¾¾¾¸¸¸¾¾¾ÆÆÆÅÅÅ¿¿¿ÂÂÂÇÇÇÇÇÇÀÀÀ»»»»»»ººº···¬¬¬­­­±±±´´´µµµ···µµµµµµµµµ¿¿¿ÆÆÆÅÅźºº±±±¸¸¸ÂÂÂÉÉÉÊÊÊÅÅÅÃÃúºººººÆÆÆÍÍÍÎÎÎÌÌÌÉÉÉÆÆÆÅÅÅÇÇÇÇÇÇÐÐÐÒÒÒÕÕÕÕÕÕÔÔÔÒÒÒÔÔÔÕÕÕÛÛÛÜÜÜßßßããããããàààÙÙÙÔÔÔÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÌÌÌÅÅž¾¾ÆÆÆÎÎÎÔÔÔÐÐÐÌÌÌÌÌÌÎÎÎÎÎÎÌÌÌÊÊÊÆÆÆÂ¿¿¿¼¼¼ººº¸¸¸¼¼¼»»»¸¸¸······¸¸¸»»»¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀ¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÇÇÇÐÐÐÀÀÀÊÊÊÌÌÌÐÐÐÊÊÊÃÃÃÊÊÊÎÎÎÐÐÐÑÑÑÐÐÐÉÉÉÀÀÀ¼¼¼¿¿¿ÅÅÅÂÂÂÊÊÊÃÃÃÉÉÉÐÐÐÇÇÇÃÃû»»ÆÆÆÂººº´´´´´´···¼¼¼¿¿¿···´´´´´´······´´´´´´¸¸¸»»»ÂÂÂÃÃü¼¼···¸¸¸ººº¸¸¸»»»ÇÇǺºº···¿¿¿ÂÂÂÃÃó³³ÀÀÀÅÅÅÌÌÌÊÊÊÃÃþ¾¾¾¾¾¾¾¾»»»¼¼¼¿¿¿ÂÂÂÃÃÃÃÃÃÀÀÀÀÀÀ¼¼¼¼¼¼»»»»»»ººº¸¸¸···µµµ···¸¸¸¸¸¸»»»¼¼¼¿¿¿ÂÂÂÃÃÃÅÅÅÅÅÅÇÇÇÌÌÌÍÍÍÌÌÌÕÕÕäääÎÎÎÙÙÙÌÌÌÆÆÆÙÙÙÅÅÅÅÅÅ¿¿¿¼¼¼çççÛÛÛÝÝÝæææÎÎÎÎÎÎØØØÕÕÕÊÊÊÌÌÌÇÇÇÍÍÍÔÔÔÐÐÐÐÐÐÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÎÎÎÎÎÎÐÐÐÍÍÍÌÌÌÊÊÊÇÇÇÆÆÆÅÅÅÃÃÃÃÃþ¾¾¿¿¿ÃÃÃÃÃÃÆÆÆÇÇÇÅÅÅÃÃÃÅÅŵµµ´´´ÀÀÀººº¾¾¾ÌÌÌÐÐÐÔÔÔÕÕÕÑÑÑÎÎÎÌÌÌÉÉÉÅÅÅÇÇÇÉÉÉÊÊÊÉÉÉÅÅż¼¼µµµ°°°°°°´´´ÀÀÀÇÇǸ¸¸µµµ¼¼¼ÊÊÊÌÌÌÉÉÉÇÇÇÆÆÆ¿¿¿¿¿¿ÌÌÌÌÌÌÎÎÎÉÉÉÊÊÊÇÇÇÃÃÃÇÇÇÅÅÅÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÔÔÔØØØÛÛÛØØØÙÙÙÜÜÜàààâââßßßÙÙÙÕÕÕÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÊÊÊÉÉÉÇÇǼ¼¼ÇÇÇÐÐÐÎÎÎÌÌÌÌÌÌÍÍÍÌÌÌÉÉÉÆÆÆÃÃÃÀÀÀ¾¾¾»»»···´´´¸¸¸···´´´³³³³³³´´´µµµ···»»»»»»ººº»»»»»»¼¼¼¾¾¾¿¿¿¾¾¾¼¼¼¾¾¾ÃÃÃÅÅÅÆÆÆÌÌÌÒÒÒÃÃÃÉÉÉÐÐÐÒÒÒÊÊÊÂÂÂÊÊÊÕÕÕÔÔÔÐÐÐÊÊÊÆÆÆÇÇÇÌÌÌÎÎÎÐÐÐÐÐÐÊÊÊÅÅÅÔÔÔÑÑÑ´´´³³³Â³³³µµµ¸¸¸¼¼¼ÀÀÀÅÅÅÉÉÉÌÌ̾¾¾¸¸¸µµµ···¸¸¸···¸¸¸¼¼¼¼¼¼ÂÂÂÃÃÿ¿¿ººº¸¸¸·········ÃÃþ¾¾³³³µµµ¿¿¿ÇÇÇÀÀÀ³³³ºººÇÇÇÎÎÎÉÉÉÅÅÅ»»»»»»¼¼¼¿¿¿ÂÂÂÂÂÂÂÂÂÀÀÀ¿¿¿¼¼¼¼¼¼»»»ºººººº¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸ººº»»»¾¾¾¿¿¿ÂÂÂÃÃÃÅÅÅÆÆÆÇÇÇÊÊÊÍÍÍÍÍÍÒÒÒâââÍÍÍÔÔÔÌÌÌÆÆÆØØØÇÇÇÃÃô´´ÊÊÊæææØØØÝÝÝãããÍÍÍÎÎÎÕÕÕÐÐп¿¿Â¾¾¾ÅÅÅÉÉÉÊÊÊÊÊÊÃÃÃÅÅÅÆÆÆÉÉÉÌÌÌÌÌÌÍÍÍÍÍÍÊÊÊÉÉÉÇÇÇÆÆÆÅÅÅÃÃÃÃÃÃÃÃÃÅÅÅÇÇÇÍÍÍÅÅÅÀÀÀÅÅž¾¾ººº¸¸¸³³³»»»ÃÃþ¾¾¸¸¸ÆÆÆÕÕÕ×××ØØØÛÛÛÙÙÙØØØÔÔÔÐÐÐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÌÌÌÉÉÉÇÇǸ¸¸±±±ºººÂÂÂÃÃü¼¼µµµ¾¾¾ÃÃÃÉÉÉÇÇÇÇÇÇÌÌÌÉÉÉÉÉÉÑÑÑÇÇÇÌÌÌÆÆÆÊÊÊÊÊÊÆÆÆÊÊÊÅÅÅÉÉÉÇÇÇÇÇÇÉÉÉÍÍÍÑÑÑÔÔÔÕÕÕÛÛÛÕÕÕÎÎÎÌÌÌÎÎÎÔÔÔÙÙÙÜÜÜÔÔÔÕÕÕÐÐÐÇÇÇÇÇÇÎÎÎÐÐÐÊÊʵµµÃÃÃÐÐÐÒÒÒÐÐÐÎÎÎÍÍÍÊÊÊÅÅÅ¿¿¿¾¾¾¾¾¾¼¼¼ººº···´´´³³³³³³±±±±±±³³³´´´µµµ¸¸¸¸¸¸¸¸¸ºººººº»»»¼¼¼¾¾¾¾¾¾¾¾¾ÃÃÃÊÊÊÍÍÍÍÍÍÑÑÑ××׿¿¿ÅÅÅÌÌÌÇÇÇÀÀÀÂÂÂÌÌ̸¸¸»»»ÀÀÀÆÆÆÊÊÊÇÇÇÃÃþ¾¾ÅÅÅØØØÌÌ̸¸¸´´´¼¼¼ÐÐÐÕÕÕÐÐÐ×××ÝÝÝßßßÜÜÜÕÕÕÑÑÑÎÎÎÊÊÊÀÀÀ¸¸¸¸¸¸ººº»»»¾¾¾Â¾¾¾¿¿¿ÂÂÂÃÃü¼¼µµµ´´´···¸¸¸¿¿¿ÇÇÇÀÀÀ¸¸¸¼¼¼ÂÂÂÊÊʼ¼¼···¼¼¼ÅÅÅÆÆÆÉÉÉÆÆÆ»»»¼¼¼¾¾¾¿¿¿ÀÀÀÂÂÂÀÀÀÀÀÀ¿¿¿¾¾¾¼¼¼»»»ººººººººº»»»¼¼¼ºººººº»»»»»»¾¾¾¿¿¿ÀÀÀÂÂÂÃÃÃÉÉÉÇÇÇÉÉÉÎÎÎÎÎÎÑÑÑÜÜÜ×××ÐÐÐÊÊÊÉÉÉØØØÊÊÊÆÆÆµµµ×××ààà×××ÝÝÝàààÎÎÎÎÎÎÎÎÎÆÆÆ¸¸¸ÇÇÇÂÂÂÅÅÅ¿¿¿¿¿¿¾¾¾¼¼¼¿¿¿ÃÃÃÇÇÇÊÊÊÌÌÌÌÌÌÌÌÌÆÆÆÅÅÅÃÃÃÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÅÅÅÃÃÃÆÆÆ¸¸¸±±±µµµ¯¯¯³³³···¼¼¼Â¿¿¿»»»ÉÉÉ×××ÕÕÕØØØØØØØØØØØØ×××ÒÒÒÐÐÐÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÌÌÌÌÌÌÊÊÊÃÃô´´ºººÀÀÀÃÃÿ¿¿¸¸¸ÅÅÅÇÇÇÎÎÎÌÌÌÇÇÇÊÊÊÇÇÇÃÃÃÅÅÅÅÅÅÊÊÊÃÃÃÊÊÊÍÍÍÉÉÉÎÎÎÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÌÌÌÍÍÍÊÊÊÉÉÉÍÍÍÊÊÊÉÉÉÉÉÉÍÍÍÐÐÐÒÒÒÒÒÒØØØßßßÙÙÙÉÉÉÇÇÇÒÒÒÑÑÑÅÅÅÇÇÇÐÐÐÔÔÔÐÐÐÊÊÊÊÊÊÊÊÊÊÊÊÇÇÇÃÃþ¾¾»»»»»»ººº¸¸¸µµµ³³³³³³³³³³³³´´´µµµ···¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸ººº»»»¼¼¼¾¾¾¾¾¾ÀÀÀÇÇÇÐÐÐÔÔÔÒÒÒÕÕÕÙÙÙÒÒÒÅÅÅÃÃÃÍÍÍÒÒÒÍÍÍÅÅÅÆÆÆÅÅÅÇÇÇÊÊÊÉÉÉÇÇÇÌÌÌÕÕÕßßßÀÀÀ¿¿¿¯¯¯···ÊÊÊÍÍÍÌÌÌÅÅÅÉÉÉÉÉÉÉÉÉÇÇÇÉÉÉÐÐÐÜÜÜæææÜÜÜÎÎÎÀÀÀ»»»ººº¸¸¸ººº¼¼¼¾¾¾¼¼¼ÀÀÀÅÅž¾¾´´´±±±µµµ···»»»ÒÒÒÒÒÒÃÃû»»¸¸¸ÊÊÊÐÐм¼¼´´´···¼¼¼ÇÇÇÇÇÇ»»»¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾»»»ºººººº»»»¼¼¼¾¾¾»»»»»»»»»¼¼¼¼¼¼¿¿¿ÀÀÀÂÂÂÂÂÂÊÊÊÇÇÇÆÆÆÎÎÎÐÐÐÐÐÐØØØäääÎÎÎÉÉÉÇÇÇÕÕÕÌÌÌÊÊÊ¿¿¿ÙÙÙÙÙÙÔÔÔÝÝÝßßßÒÒÒÐÐÐÍÍ;¾¾¸¸¸ÒÒÒÐÐÐÌÌÌ»»»···´´´¸¸¸¼¼¼ÂÂÂÇÇÇÌÌÌÍÍÍÌÌÌÌÌÌÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼¾¾¾¾¾¾¿¿¿¾¾¾···»»»°°°¬¬¬±±±±±±¿¿¿ÅÅž¾¾¼¼¼¾¾¾ÅÅÅØØØàààÔÔÔÝÝÝÜÜÜÙÙÙÙÙÙ×××ÕÕÕÒÒÒÑÑÑÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÎÎÎÌÌÌÊÊÊÉÉÉ···¾¾¾ÃÃÃÅÅÅÀÀÀ···ÆÆÆ¿¿¿ÉÉÉÇÇÇÃÃÃÉÉÉÌÌÌÆÆÆÅÅÅÆÆÆÅÅÅÅÅÅÉÉÉÍÍÍÐÐÐÍÍÍÉÉÉÍÍÍÉÉÉÆÆÆÆÆÆÊÊÊÎÎÎÐÐÐÑÑÑØØØ×××ÔÔÔÑÑÑÊÊÊÅÅÅÉÉÉÑÑÑÒÒÒÎÎÎÔÔÔÕÕÕÆÆÆ¿¿¿ÊÊÊÑÑÑÉÉÉÃÃÃÔÔÔØØØÑÑÑÍÍÍÅÅÅÅÅÅÃÃÿ¿¿»»»¼¼¼ÀÀÀ¾¾¾······³³³±±±µµµµµµ³³³µµµ¼¼¼µµµ···¸¸¸ººººººººººººººººººÐÐÐÇÇÇÀÀÀ¾¾¾ººº¿¿¿¸¸¸ÕÕÕÂÂÂÃÃÃÔÔÔÔÔÔÍÍÍÐÐÐÕÕÕÒÒÒÊÊʾ¾¾¿¿¿ÌÌÌÊÊÊÀÀÀ¾¾¾´´´¾¾¾ÊÊÊÎÎÎÊÊÊÆÆÆÆÆÆÉÉÉÅÅÅÃÃÃÂÂÂÂÂÂÅÅÅÉÉÉÍÍÍÐÐÐÐÐÐÒÒÒÕÕÕÒÒÒÉÉÉÀÀÀ»»»»»»¸¸¸¼¼¼ÀÀÀÀÀÀººº···ººº¼¼¼¼¼¼ÃÃÃÌÌÌÐÐÐÑÑÑÃÃø¸¸ÂÂÂÌÌÌÀÀÀÀÀÀÀÀÀµµµµµµÃÃÃÊÊÊÀÀÀ»»»¿¿¿ÀÀÀ»»»¾¾¾ÃÃþ¾¾¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀ¿¿¿¾¾¾¼¼¼»»»»»»¼¼¼¿¿¿ÀÀÀÆÆÆÌÌÌÉÉÉÍÍÍÒÒÒÍÍÍÍÍÍÛÛÛÇÇÇÑÑÑÉÉÉÉÉɸ¸¸ÑÑÑÀÀÀÆÆÆ¯¯¯ëëëßßßØØØßßßÐÐÐÑÑÑ»»»¾¾¾ÍÍÍÛÛÛÑÑѸ¸¸±±±»»»···¼¼¼ÃÃÃÉÉÉÌÌÌÌÌÌÌÌÌÌÌÌÂÂÂÀÀÀ¿¿¿¾¾¾¼¼¼ººº¸¸¸···±±±±±±±±±ÂÂÂÅÅÅÃÃÃÊÊÊ»»»ÅÅÅ»»»±±±»»»ÐÐÐÔÔÔÌÌÌÉÉÉÎÎÎÝÝÝÑÑÑÐÐÐÔÔÔÎÎÎÑÑÑÐÐÐÍÍÍÊÊÊÇÇÇÉÉÉÎÎÎÑÑÑÍÍÍÉÉɵµµººº»»»ÂÂÂÉÉÉ»»»ÀÀÀÆÆÆÆÆÆÇÇÇÉÉÉÊÊÊÊÊÊÊÊÊÉÉÉÇÇÇÉÉÉÊÊÊÉÉÉÉÉÉÊÊÊÎÎÎÒÒÒÊÊÊÊÊÊÉÉÉÊÊÊÌÌÌÍÍÍÍÍÍÌÌÌÒÒÒÑÑÑÒÒÒÒÒÒÍÍÍÅÅÅÃÃÃÇÇÇÎÎÎÉÉÉÎÎÎÒÒÒÍÍÍÌÌÌÎÎÎÌÌÌÊÊÊÀÀÀÌÌÌÎÎÎÉÉÉÊÊÊÇÇÇÊÊÊÅÅÅÇÇÇÅÅÅ¿¿¿»»»»»»¸¸¸´´´ºººººº¸¸¸¸¸¸´´´³³³µµµ»»»ººº»»»¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÃÃÃÀÀÀÒÒÒÌÌÌÊÊÊÍÍÍÌÌÌÑÑÑÎÎÎÊÊÊÇÇÇÊÊÊÉÉɼ¼¼ººº¾¾¾¾¾¾ººº¾¾¾»»»ÅÅÅÑÑѱ±±»»»ÅÅÅÌÌÌÑÑÑÐÐÐÇÇÇ¿¿¿»»»»»»¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾ÂÂÂÆÆÆÉÉÉÎÎÎÍÍÍÐÐÐÐÐÐÒÒÒÎÎÎÀÀÀ¼¼¼»»»¼¼¼ÀÀÀÂÂÂÀÀÀÀÀÀÂÂÂÂÂÂÑÑÑÔÔÔÆÆÆÃÃÃÒÒÒÎÎλ»»ºººÅÅÅÆÆÆÇÇÇÆÆÆÅÅÅÀÀÀÀÀÀÅÅÅÉÉÉÀÀÀ¿¿¿ÀÀÀ¼¼¼»»»¼¼¼¼¼¼¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀ¾¾¾¼¼¼¼¼¼»»»»»»¼¼¼¾¾¾¿¿¿ÂÂÂÉÉÉÌÌÌÌÌÌÍÍÍÌÌÌÑÑÑÜÜÜÍÍÍÐÐÐÎÎÎÒÒÒ¼¼¼ÐÐÐÂÂÂÃÃð°°çççÛÛÛÒÒÒÔÔÔÇÇÇÑÑÑÌÌ̺ºº¸¸¸¿¿¿ÉÉÉÆÆÆ¸¸¸µµµ¼¼¼¸¸¸¾¾¾ÅÅÅÊÊÊÍÍÍÍÍÍÍÍÍÍÍÍÌÌÌÅÅž¾¾ººº¸¸¸¸¸¸···´´´³³³¸¸¸»»»ÅÅÅÃÃÃÂÂÂÉÉÉ»»»···µµµµµµÃÃÃÕÕÕ×××ÍÍÍÌÌÌÍÍÍÛÛÛÔÔÔÑÑÑÔÔÔÍÍÍÑÑÑÎÎÎÎÎÎÌÌÌÌÌÌÍÍÍÎÎÎÉÉɼ¼¼³³³´´´¿¿¿ÃÃÃÃÃÿ¿¿µµµ¸¸¸ÇÇÇÆÆÆÇÇÇÇÇÇÇÇÇÇÇÇÆÆÆÇÇÇÇÇÇÅÅÅÉÉÉÌÌÌÇÇÇÃÃÃÅÅÅÍÍÍ×××ÊÊÊÍÍÍÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÎÎÎÍÍÍÎÎÎÒÒÒÑÑÑÊÊÊÇÇÇÉÉÉÆÆÆÂÂÂÅÅÅÊÊÊÎÎÎÔÔÔÑÑÑÅÅÅÎÎο¿¿ÀÀÀººº³³³······ºººÃÃÃÊÊÊÍÍÍÉÉÉÃÃÿ¿¿ººº´´´±±±µµµ···´´´´´´¸¸¸¼¼¼¿¿¿¸¸¸ºººººº¸¸¸···ººº¾¾¾Â°°°ÀÀÀÀÀÀÀÀÀ¿¿¿ÇÇÇÎÎÎÔÔÔÒÒÒÔÔÔÐÐÐÉÉÉÌÌÌÌÌÌÂÂÂÇÇÇÍÍÍÆÆÆÊÊÊÕÕÕÅÅž¾¾ÜÜÜÉÉÉÌÌÌÎÎÎÍÍÍÇÇÇÀÀÀ¼¼¼»»»»»»ººº¸¸¸¸¸¸»»»¾¾¾ÂÂÂÃÃÃÍÍÍÉÉÉÊÊÊÉÉÉØØØÙÙÙ¾¾¾¸¸¸»»»¾¾¾¼¼¼¼¼¼ÂÂÂÉÉÉÎÎÎÒÒÒÕÕÕ×××¼¼¼µµµÑÑÑÙÙÙÊÊÊÃÃþ¾¾ÊÊÊÊÊÊÇÇÇÍÍÍÉÉÉ¿¿¿ÀÀÀÌÌÌÆÆÆÀÀÀ¿¿¿¿¿¿ººº¸¸¸¾¾¾¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¿¿¿ÀÀÀ»»»»»»»»»»»»¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÅÅÅÍÍÍÌÌÌÇÇÇÌÌÌÕÕÕÙÙÙÒÒÒÍÍÍÔÔÔÛÛÛ¾¾¾ÎÎÎÅÅž¾¾¬¬¬ßßßÛÛÛ××××××ÊÊÊÑÑÑÉÉÉÀÀÀ»»»¸¸¸»»»¼¼¼ºººººº¼¼¼»»»ÀÀÀÇÇÇÌÌÌÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÉÉÉÀÀÀ»»»¸¸¸µµµ³³³°°°···¿¿¿ÃÃÃÆÆÆÂÂÂÀÀÀÅÅÅ»»»³³³»»»ÃÃÃÎÎÎØØØÑÑÑÆÆÆÆÆÆÉÉÉ×××ÕÕÕÔÔÔÒÒÒÍÍÍÎÎÎÍÍÍÅÅÅÉÉÉÍÍÍÎÎÎÊÊÊÃÃû»»µµµºººÅÅÅÆÆÆ¾¾¾µµµ¬¬¬±±±ÃÃÃÅÅÅÇÇÇÉÉÉÆÆÆÃÃÃÂÂÂÅÅÅÆÆÆÀÀÀÅÅÅÇÇÇÆÆÆÂÂÂÃÃÃÉÉÉÐÐÐÌÌÌÐÐÐÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÑÑÑÎÎÎÉÉÉÉÉÉÎÎÎÒÒÒÑÑÑÒÒÒÕÕÕÀÀÀÀÀÀ¿¿¿ÀÀÀÉÉÉÑÑÑÎÎÎÃÃÃÐÐÐÃÃÃÆÆÆÀÀÀ¸¸¸¸¸¸°°°¬¬¬µµµ¾¾¾ÃÃÃÆÆÆÇÇÇÆÆÆ¾¾¾³³³³³³µµµ´´´±±±´´´»»»¼¼¼···Â¿¿¿¿¿¿ÂÂÂÊÊÊÐÐÐÂÂÂÆÆÆÂÂÂÂÂÂÅÅÅÀÀÀÂÂÂÇÇÇÇÇÇÃÃÃÌÌÌÔÔÔ×××ÜÜÜÝÝÝØØØ×××ÝÝÝÜÜÜÜÜÜÛÛÛÇÇǼ¼¼ÌÌÌÃÃÃÅÅÅÅÅÅÆÆÆÅÅÅÃÃÃÀÀÀ¿¿¿¼¼¼»»»»»»»»»¼¼¼¿¿¿ÂÂÂÅÅÅÊÊÊÅÅÅÅÅÅÂÂÂÔÔÔØØØººº³³³ººº¿¿¿»»»···¾¾¾ÉÉÉÕÕÕàààÐÐÐÍÍ͸¸¸µµµÇÇÇÒÒÒÕÕÕÒÒÒ»»»ÆÆÆÇÇÇÆÆÆÌÌÌÌÌÌÆÆÆÂÂÂÀÀÀÊÊÊÇÇÇ¿¿¿¿¿¿»»»ºººÂ¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÀÀÀÀÀÀ¿¿¿ºººººº»»»¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¿¿¿ÂÂÂÌÌÌÍÍÍÇÇÇÐÐÐØØØÐÐÐÔÔÔÉÉÉÒÒÒÛÛÛ¼¼¼ÉÉÉÃÃúºº¬¬¬ÛÛÛÝÝÝÜÜÜÝÝÝØØØÙÙÙÇÇÇÊÊÊÆÆÆÂ¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼ÀÀÀÇÇÇÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÊÊÊÊÊÊÆÆÆÀÀÀ¸¸¸´´´³³³³³³¼¼¼ÅÅÅÇÇÇÅÅÅÀÀÀÂÂÂÀÀÀ···¸¸¸ÅÅÅÎÎÎ×××ØØØÌÌÌÂÂÂÆÆÆÆÆÆÒÒÒØØØ×××ÒÒÒÎÎÎÍÍÍÌÌÌÍÍÍÒÒÒÒÒÒÊÊʾ¾¾···¸¸¸¼¼¼ÀÀÀ»»»´´´´´´°°°­­­´´´¿¿¿ÃÃÃÇÇÇÇÇÇÃÃÃÂÂÂÃÃÃÆÆÆÂÂÂÂÂÂÃÃÃÆÆÆÉÉÉÊÊÊÉÉÉÇÇÇÉÉÉÊÊÊÍÍÍÎÎÎÍÍÍÍÍÍÐÐÐÑÑÑÌÌÌÆÆÆÆÆÆÌÌÌÑÑÑÑÑÑÒÒÒÔÔÔÃÃÃÆÆÆÃÃÿ¿¿ÃÃÃÊÊÊÌÌÌÇÇÇ¿¿¿ºººÆÆÆÆÆÆÂ···­­­ªªª­­­°°°µµµÀÀÀÇÇǸ¸¸¸¸¸···³³³³³³»»»ÃÃÃÀÀÀ······µµµ³³³¯¯¯­­­¯¯¯´´´¸¸¸ÅÅž¾¾ÃÃÃÔÔÔÛÛÛØØØÝÝÝÑÑÑÔÔÔÛÛÛ×××ÇÇǾ¾¾ÀÀÀÀÀÀ¿¿¿¾¾¾¿¿¿ÃÃÃÇÇÇÉÉÉÃÃÃÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿¾¾¾»»»¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾ÀÀÀÂÂÂÃÃÃÆÆÆÅÅÅÅÅÅÀÀÀÎÎÎÔÔÔ¿¿¿¸¸¸···ÅÅÅÅÅż¼¼¾¾¾ÃÃÃÌÌÌØØØ×××ÇÇÇ···¾¾¾¾¾¾ÀÀÀÒÒÒÍÍÍ»»»ÀÀÀÉÉÉÌÌÌÌÌÌÐÐÐÐÐÐÅÅÅ···ÎÎÎÒÒÒÃÃþ¾¾¼¼¼»»»ÀÀÀ¾¾¾¿¿¿ÂÂÂÅÅÅÅÅÅ¿¿¿¼¼¼¸¸¸ººº»»»»»»¼¼¼¼¼¼¾¾¾¾¾¾ÃÃÃÂÂÂÉÉÉÍÍÍÍÍÍÕÕÕÕÕÕÇÇÇÑÑÑÇÇÇÎÎÎÎÎλ»»ÇÇǸ¸¸±±±ÜÜÜäääàààÜÜÜÜÜÜæææ×××ÌÌÌÎÎÎÌÌÌÆÆÆÂÂÂÀÀÀ¿¿¿¼¼¼¾¾¾ÂÂÂÇÇÇÊÊÊÌÌÌÍÍÍÎÎÎÐÐÐÉÉÉÌÌÌÉÉÉÀÀÀµµµ³³³ºººÀÀÀÅÅÅÆÆÆÆÆÆÀÀÀÀÀÀ»»»´´´¾¾¾ÉÉÉÒÒÒ××××××ÌÌÌÆÆÆÎÎÎÅÅÅÐÐÐÛÛÛØØØÑÑÑÐÐÐÍÍÍÌÌÌÍÍÍÌÌÌÇÇÇÀÀÀººº···»»»¿¿¿¸¸¸¸¸¸°°°¯¯¯···¸¸¸±±±±±±ºººÀÀÀÆÆÆÉÉÉÆÆÆÃÃÃÅÅÅÆÆÆÆÆÆÃÃÃÂÂÂÆÆÆÍÍÍÎÎÎÌÌÌÆÆÆÂÂÂÃÃÃÃÃÃÅÅÅÅÅÅÆÆÆÉÉÉÌÌÌÆÆÆÃÃÃÅÅÅÊÊÊÍÍÍÉÉÉÆÆÆÅÅÅÉÉÉÎÎÎÌÌÌÆÆÆÆÆÆÇÇÇÉÉÉÍÍÍÃÃû»»¿¿¿ººº´´´¼¼¼»»»ººº³³³°°°¬¬¬¯¯¯»»»ÉÉÉÌÌÌÆÆÆÃÃÿ¿¿»»»»»»ÀÀÀÃÃÿ¿¿¸¸¸ÀÀÀÀÀÀ¿¿¿ÀÀÀÃÃÃÉÉÉÍÍÍÎÎξ¾¾ÃÃÃÇÇÇ¿¿¿ÀÀÀÆÆÆÆÆÆÔÔÔÕÕÕÛÛÛÛÛÛÌÌÌ»»»¼¼¼»»»¯¯¯¸¸¸³³³±±±°°°³³³ÃÃÃÍÍÍÅÅÅ¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¼¼¼»»»»»»»»»»»»»»»»»»¼¼¼¾¾¾ÀÀÀÀÀÀÂÂÂÆÆÆÅÅÅÆÆÆÌÌÌÒÒÒÎÎÎÀÀÀ¸¸¸ÎÎÎÒÒÒÉÉÉÇÇǾ¾¾ÃÃÃÜÜÜÃÃô´´Â»»»¼¼¼ÔÔÔÆÆÆ¼¼¼¾¾¾ÌÌÌÔÔÔÐÐÐÒÒÒÔÔÔÉÉɺººÎÎÎÕÕÕÉÉÉ¿¿¿¼¼¼¼¼¼¼¼¼¼¼¼¿¿¿ÃÃÃÅÅÅÅÅž¾¾»»»ººººººººº»»»¼¼¼¾¾¾¿¿¿¿¿¿ÆÆÆÅÅÅÉÉÉÎÎÎÒÒÒ×××ÒÒÒÉÉÉÊÊÊÌÌÌÊÊÊÀÀÀÀÀÀÍÍÍÀÀÀ¾¾¾°°°ÑÑÑæææëëëßßßÙÙÙäääßßßÇÇÇÌÌÌÍÍÍÌÌÌÉÉÉÆÆÆÃÃÃÀÀÀÀÀÀÅÅÅÉÉÉÌÌÌÍÍÍÍÍÍÎÎÎÐÐÐÎÎÎÍÍÍÆÆÆ»»»³³³···ÃÃÃÐÐÐÉÉÉÇÇÇÆÆÆ¿¿¿ÀÀÀ¿¿¿µµµ»»»ÌÌÌÒÒÒÕÕÕØØØØØØÍÍÍÇÇÇÎÎÎÇÇÇÌÌÌÛÛÛÙÙÙÑÑÑÔÔÔÎÎÎÌÌÌ¿¿¿»»»···¸¸¸¾¾¾¿¿¿¼¼¼···¨¨¨¯¯¯¯¯¯°°°»»»¾¾¾»»»¼¼¼ººº¿¿¿ÅÅÅÇÇÇÇÇÇÆÆÆÆÆÆÇÇÇÇÇǾ¾¾¿¿¿ÅÅÅÉÉÉÊÊÊÉÉÉÂÂÂÀÀÀÀÀÀÀÀÀÂÂÂÅÅÅÅÅÅÅÅÅÇÇÇÃÃÃÃÃÃÇÇÇÇÇÇÃÃÃÀÀÀÂÂÂÇÇÇÍÍÍÍÍÍÌÌÌÍÍÍÅÅÅÀÀÀÇÇÇÒÒÒÉÉÉÉÉÉ»»»±±±»»»¾¾¾¾¾¾ºººººº¸¸¸µµµºººÂÂÂÅÅÅÃÃÃÇÇÇÆÆÆÃÃþ¾¾···µµµµµµ¾¾¾»»»¸¸¸···¸¸¸ººº···´´´»»»ÇÇÇÐÐм¼¼´´´ººº»»»ÍÍÍÒÒÒÎÎÎÉÉɼ¼¼³³³¸¸¸»»»±±±ªªª±±±¿¿¿ÍÍÍÔÔÔÒÒÒÇÇǺºº¼¼¼¼¼¼¾¾¾¾¾¾¾¾¾¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¼¾¾¾¿¿¿ÀÀÀÀÀÀÃÃÃÆÆÆÂÂÂÊÊÊÊÊÊÎÎÎØØØ¼¼¼¿¿¿ÕÕÕ×××ÎÎÎÒÒÒÌÌ̼¼¼»»»ÙÙÙÉÉÉ···ÀÀÀ¼¼¼ÀÀÀÙÙÙÉÉɾ¾¾¿¿¿ÇÇÇÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÂÂÂÅÅÅÌÌÌÍÍÍÃÃÿ¿¿¿¿¿¾¾¾¿¿¿ÀÀÀÂÂÂÂÂÂÂÂÂÀÀÀ¾¾¾¼¼¼»»»»»»ººº»»»¼¼¼¾¾¾ÀÀÀÂÂÂÆÆÆÉÉÉÊÊÊÎÎÎÔÔÔÒÒÒÑÑÑÕÕÕÃÃÃÔÔÔÉÉɸ¸¸ÌÌÌØØØÃÃÃÅÅŵµµ¼¼¼ÑÑÑíííççç×××ÛÛÛÜÜÜÎÎÎÌÌÌÊÊÊÎÎÎÑÑÑÎÎÎÉÉÉÆÆÆÅÅÅÇÇÇÌÌÌÎÎÎÎÎÎÐÐÐÑÑÑÔÔÔÒÒÒÌÌÌÀÀÀººº»»»ÂÂÂÌÌÌÑÑÑÌÌÌÉÉÉÊÊÊÃÃÿ¿¿ººº´´´ÇÇÇÔÔÔ×××ØØØÛÛÛÝÝÝÒÒÒÇÇÇÉÉÉÊÊÊÊÊÊÛÛÛØØØÑÑÑ×××ÐÐÐÌÌ̾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¸¸¸°°°©©©¥¥¥°°°³³³´´´¾¾¾ÃÃÃÂÂÂÃÃÃÀÀÀÂÂÂÅÅÅÆÆÆÆÆÆÇÇÇÉÉÉÉÉÉÅÅÅ¿¿¿ºººµµµ¸¸¸¿¿¿ÆÆÆÊÊÊÆÆÆÃÃÃÂÂÂÃÃÃÆÆÆÆÆÆÅÅÅÃÃÃÌÌÌÆÆÆÃÃÃÃÃÃÃÃÃÃÃÃÆÆÆÊÊÊÂÂÂÇÇÇÉÉÉÍÍÍÐÐÐÃÃø¸¸¾¾¾ÀÀÀÀÀÀÌÌÌÅÅźººººº±±±©©©³³³ººº¾¾¾ººº´´´³³³³³³±±±©©©¯¯¯¸¸¸¿¿¿¼¼¼¸¸¸ÀÀÀÎÎδ´´´´´···ÀÀÀÎÎÎ×××ØØØ×××ÍÍÍÎÎÎÌÌÌ···¸¸¸Â¸¸¸»»»ÃÃû»»¾¾¾¾¾¾···ºººÍÍÍÛÛÛÒÒÒÎÎÎÃÃÃÂÂÂÅÅž¾¾¸¸¸¾¾¾ÀÀÀÂÂÂÂÂÂÀÀÀ¾¾¾»»»ºººººº¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÃÃÃÅÅÅÆÆÆ¾¾¾ÊÊÊÇÇÇÉÉÉ×××±±±ÆÆÆØØØÔÔÔÍÍÍØØØÕÕÕÅÅÅ¿¿¿ØØØ×××ÀÀÀ¿¿¿»»»ÀÀÀÛÛÛÌÌÌÀÀÀ¾¾¾¾¾¾Â¾¾¾ÂÂÂÒÒÒÉÉɺºº¿¿¿ÍÍÍÊÊÊÃÃÃÃÃÃÅÅÅÂÂÂÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¿¿¿¼¼¼»»»ºººººº»»»¾¾¾ÂÂÂÃÃÃÃÃÃÊÊÊÌÌÌÎÎÎÔÔÔÎÎÎÑÑÑâââÀÀÀÛÛÛÊÊÊ´´´ÕÕÕâââÆÆÆÊÊÊÉÉɯ¯¯´´´ÝÝÝæææÔÔÔ×××ÜÜÜÛÛÛÐÐÐÊÊÊÑÑÑØØØÕÕÕÎÎÎÊÊÊÇÇÇÊÊÊÎÎÎÑÑÑÑÑÑÒÒÒÔÔÔÕÕÕÒÒÒÉÉɾ¾¾¾¾¾ÆÆÆÍÍÍÍÍÍÊÊÊÌÌÌÊÊÊÐÐÐÇÇǾ¾¾´´´³³³ÒÒÒÎÎÎÑÑÑÔÔÔÜÜÜäääÜÜÜÎÎÎÍÍÍÌÌÌÊÊÊÛÛÛØØØÒÒÒØØØÑÑÑÌÌÌ´´´¾¾¾ÆÆÆÆÆÆ¼¼¼´´´±±±´´´­­­µµµµµµµµµÀÀÀÇÇÇÃÃÃÀÀÀÇÇÇÆÆÆÅÅÅÃÃÃÅÅÅÇÇÇÉÉÉÊÊÊÀÀÀ³³³°°°¸¸¸»»»µµµ¾¾¾ÎÎÎÆÆÆÇÇÇÇÇÇÆÆÆÅÅÅÆÆÆÉÉÉÌÌÌÕÕÕÒÒÒÌÌÌÀÀÀµµµÇÇÇÇÇÇÅÅÅÀÀÀÐÐÐÕÕÕÔÔÔÌÌÌ···¸¸¸···ºººÂÂÂÌÌÌÊÊʼ¼¼¾¾¾±±±°°°±±±ºººÀÀÀ¾¾¾µµµ­­­¯¯¯¼¼¼¿¿¿¸¸¸¿¿¿ÆÆÆ¸¸¸¯¯¯¯¯¯°°°±±±¬¬¬±±±±±±´´´ÝÝÝÛÛÛÃÃÿ¿¿¾¾¾¼¼¼ÀÀÀ¾¾¾¿¿¿ÆÆÆ±±±¸¸¸³³³ÀÀÀÇÇÇÉÉÉÂÂÂÀÀÀÃÃÃÆÆÆÂ¼¼¼¸¸¸»»»¾¾¾ÆÆÆ¾¾¾»»»¾¾¾»»»´´´³³³···µµµ»»»¾¾¾¼¼¼¾¾¾ÃÃÃÃÃÿ¿¿ÉÉÉ»»»ÅÅÅÇÇÇÅÅÅÌÌÌÆÆÆ¼¼¼ÆÆÆÕÕÕÑÑÑÌÌÌÅÅÅÛÛÛ´´´¿¿¿ÒÒÒÕÕÕÔÔÔººººººÑÑÑÐÐÐÌÌÌÉÉÉÂÂÂÂÂÂÌÌÌÐÐÐÉÉÉÀÀÀ¼¼¼ÅÅÅÌÌ̼¼¼ÕÕÕÌÌÌÃÃÃÇÇÇÀÀÀÀÀÀÀÀÀ¿¿¿¿¿¿¾¾¾¾¾¾¼¼¼¼¼¼¾¾¾ººº»»»¿¿¿Â¿¿¿ÀÀÀÅÅÅÃÃÃÍÍÍÉÉÉÎÎÎÙÙÙÍÍÍÇÇÇÜÜÜÊÊÊÎÎÎâââÉÉɳ³³»»»ØØØÌÌÌÀÀÀÀÀÀ¿¿¿ÌÌÌÛÛÛØØØÑÑÑÙÙÙÙÙÙèèèÕÕÕÉÉÉÎÎÎÊÊÊÐÐÐÙÙÙÑÑÑÒÒÒÒÒÒÒÒÒÔÔÔÕÕÕ×××ØØØÐÐÐÆÆÆ¸¸¸»»»ÍÍÍÍÍÍ»»»°°°¸¸¸ÌÌÌÎÎÎÃÃÿ¿¿ººº¸¸¸ÔÔÔÔÔÔÙÙÙÛÛÛØØØÙÙÙÒÒÒÃÃÃÌÌÌÒÒÒâââØØØÛÛÛÔÔÔÐÐи¸¸ºººÃÃÃÅÅźºº´´´ººº¾¾¾¾¾¾¸¸¸°°°¯¯¯³³³¸¸¸ÂÂÂÅÅż¼¼ÃÃÃÉÉÉÊÊÊÅÅÅÃÃÃÆÆÆÆÆÆÃÃû»»ºººÀÀÀÉÉɱ±±±±±¾¾¾ÉÉÉÊÊÊÌÌÌÌÌÌÌÌÌÍÍÍÑÑÑÔÔÔÑÑÑÑÑÑÇÇǵµµ¸¸¸´´´ÆÆÆÂÂÂÅÅÅÂÂÂÍÍÍÑÑÑÒÒÒÎÎμ¼¼¸¸¸¼¼¼¸¸¸»»»ÆÆÆÐÐÐÒÒÒÐÐÐÎÎÎÉÉÉÇÇÇÀÀÀººº¼¼¼ÀÀÀ¼¼¼´´´ººº¼¼¼ººº»»»ÃÃÃÀÀÀ³³³¯¯¯¯¯¯ªªªªªª©©©³³³¸¸¸ºººÒÒÒ···¼¼¼»»»ºººÀÀÀ¿¿¿¿¿¿Â¼¼¼ÕÕÕÎÎÎÑÑÑÍÍÍÇÇǾ¾¾ÀÀÀ¿¿¿¼¼¼ººº»»»¾¾¾¼¼¼¼¼¼¼¼¼»»»´´´­­­­­­±±±´´´ººº¾¾¾¼¼¼¼¼¼ÀÀÀ¿¿¿ÇÇǾ¾¾ÅÅÅÅÅÅÆÆÆÊÊÊÀÀÀ»»»ÊÊÊÔÔÔÎÎÎÍÍÍÊÊÊàààÃÃÃ×××ÍÍÍÒÒÒ×××ÆÆÆÇÇÇØØØÐÐÐÅÅÅÂÂÂÅÅÅÊÊÊÐÐÐÔÔÔÑÑÑÆÆÆ¼¼¼¾¾¾ÍÍÍÀÀÀÔÔÔÍÍÍ¿¿¿¿¿¿¿¿¿¿¿¿¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼»»»¸¸¸ººº¿¿¿ÂÂÂÀÀÀÂÂÂÆÆÆÅÅÅÅÅÅÉÉÉÎÎÎÐÐÐÍÍÍÑÑÑÜÜÜÌÌÌÕÕÕÙÙÙÉÉÉ»»»´´´ÃÃÃÒÒÒÆÆÆÃÃúºººººÍÍÍÝÝÝÛÛÛÑÑÑÜÜÜàààÍÍÍÊÊÊÕÕÕÑÑÑÌÌÌÃÃÃÌÌÌÍÍÍÐÐÐÔÔÔ×××ØØØØØØ×××ÕÕÕÐÐÐÀÀÀ···¸¸¸ººº»»»Â¸¸¸ÆÆÆÐÐÐÊÊÊÀÀÀ¾¾¾¼¼¼···ÍÍÍÎÎÎØØØÜÜÜÜÜÜâââàààÕÕÕÒÒÒÎÎÎÜÜÜÛÛÛÛÛÛÐÐÐÍÍ͸¸¸ÀÀÀÅÅÅ¿¿¿´´´°°°¸¸¸¾¾¾¼¼¼ººº°°°¯¯¯¯¯¯¬¬¬´´´ÀÀÀÅÅÅÀÀÀÅÅÅÅÅÅÂÂÂÃÃÃÇÇÇÇÇÇÃÃô´´»»»ÇÇÇÎÎγ³³···ÅÅÅÌÌÌÍÍÍÎÎÎÎÎÎÎÎÎÐÐÐÒÒÒÕÕÕÎÎÎÑÑÑÆÆÆ±±±´´´µµµÇÇÇ¿¿¿ÃÃÃÃÃÃÊÊÊÌÌÌÐÐÐÑÑÑÃÃû»»¼¼¼µµµ±±±···¼¼¼¾¾¾¾¾¾¼¼¼³³³¿¿¿ÅÅž¾¾ººº¿¿¿¾¾¾···ÃÃû»»³³³¼¼¼ÆÆÆ»»»³³³µµµ¯¯¯¬¬¬¬¬¬¦¦¦©©©±±±³³³¼¼¼¾¾¾ºººÅÅž¾¾ÅÅÅ¿¿¿Â»»»ÛÛÛÎÎÎÍÍÍÌÌÌÆÆÆÉÉɼ¼¼¼¼¼¼¼¼¼¼¼¼¼¼»»»»»»»»»¾¾¾¼¼¼µµµ¬¬¬©©©­­­°°°°°°¯¯¯µµµ»»»¼¼¼¾¾¾ÂÂÂÃÃÃÃÃÃÅÅÅÂÂÂÃÃÃÀÀÀÉÉÉÊÊÊ»»»»»»ÝÝÝØØØÇÇÇÅÅÅÃÃÃÔÔÔ···ÃÃÃÒÒÒÕÕÕÕÕÕÇÇÇÉÉÉØØØÔÔÔÌÌÌÀÀÀÉÉÉÐÐÐÐÐÐÐÐÐÐÐÐÅÅŵµµ¸¸¸ÍÍÍÃÃÃÐÐÐÍÍÍÀÀÀ¼¼¼¾¾¾¼¼¼¼¼¼¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¼¼¼»»»¼¼¼¿¿¿ÂÂÂÀÀÀÃÃÃÆÆÆÉÉÉÅÅÅÐÐÐÕÕÕÊÊÊÊÊÊÒÒÒÍÍÍÆÆÆÙÙÙÎÎÎÃÃ÷·····ÙÙÙÊÊÊÇÇǼ¼¼°°°¼¼¼ÜÜÜæææ×××ÔÔÔÜÜÜÔÔÔÎÎÎÊÊÊÆÆÆÉÉÉÅÅÅÍÍÍÌÌÌÌÌÌÎÎÎÒÒÒÕÕÕÕÕÕÔÔÔÕÕÕØØØÑÑÑÅÅż¼¼¸¸¸»»»ÃÃü¼¼¿¿¿ÍÍÍÐÐÐÃÃÿ¿¿ÀÀÀ¸¸¸ÌÌÌÐÐÐÙÙÙÝÝÝÛÛÛÝÝÝàààÙÙÙàààÑÑÑàààãããâââÔÔÔÔÔÔ¿¿¿ÆÆÆÅÅÅ»»»°°°­­­···¾¾¾¼¼¼µµµ³³³»»»ÀÀÀµµµ±±±¼¼¼ÆÆÆ¿¿¿ÀÀÀÀÀÀÀÀÀÅÅÅÉÉÉÆÆÆÂ±±±»»»ÇÇÇÎÎÎÆÆÆ»»»¿¿¿ÉÉÉÌÌÌÍÍÍÎÎÎÍÍÍÌÌÌÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐÉÉÉ»»»¿¿¿ºººÇÇÇ¿¿¿¿¿¿ÆÆÆÌÌÌÊÊÊÌÌÌÎÎÎÉÉÉÀÀÀ»»»»»»¼¼¼»»»¸¸¸µµµµµµ···­­­¼¼¼ÆÆÆÀÀÀººººººÀÀÀÅÅÅ···ººº¸¸¸ÇÇÇÎÎξ¾¾´´´µµµµµµ¸¸¸ººº¯¯¯¥¥¥ªªª±±±´´´´´´¯¯¯ººº»»»»»»ÅÅÅÅÅÅÅÅÅ¿¿¿µµµ×××ÍÍÍÍÍÍÌÌÌ¿¿¿¾¾¾¾¾¾»»»ºººººº»»»»»»ººº···µµµ´´´°°°¯¯¯¸¸¸ÀÀÀµµµ¤¤¤···»»»ÀÀÀÀÀÀ¿¿¿¾¾¾¾¾¾¿¿¿ÀÀÀÃÃþ¾¾ÍÍÍÌÌ̸¸¸¾¾¾×××ÍÍÍ»»»»»»ÀÀÀÒÒÒ···µµµ¿¿¿ÅÅÅÃÃø¸¸»»»ÊÊÊÑÑÑÑÑÑÐÐÐÔÔÔ×××ÔÔÔÐÐÐÉÉɼ¼¼±±±···ÌÌÌÀÀÀÅÅÅÍÍÍ»»»»»»»»»»»»¼¼¼¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÂÂÂÀÀÀ¿¿¿¿¿¿ÀÀÀÂÂÂÃÃÃÆÆÆÆÆÆÅÅÅÔÔÔÙÙÙÍÍÍÎÎÎÒÒÒÇÇÇÌÌÌâââÊÊÊ¿¿¿Â¿¿¿±±±ÎÎÎÌÌÌÇÇÇÅÅŸ¸¸´´´ÊÊÊäääæææÑÑÑÛÛÛÙÙÙ×××ÍÍÍÇÇÇÍÍÍÅÅÅÌÌÌÊÊÊÌÌÌÑÑÑÕÕÕ×××ÑÑÑÌÌÌÑÑÑ××××××ÔÔÔÑÑÑÎÎÎÊÊÊÇÇÇÃÃÃÀÀÀÇÇÇÍÍÍÊÊÊÆÆÆÃÃü¼¼¼¼¼ÂÂÂÑÑÑÙÙÙÙÙÙÝÝÝâââßßßàààÒÒÒãããçççäääÛÛÛÙÙÙ¿¿¿ÅÅÅÅÅÅ¿¿¿´´´°°°µµµ»»»¼¼¼´´´³³³¿¿¿ÉÉɼ¼¼±±±···ÀÀÀÀÀÀÀÀÀÀÀÀÃÃÃÇÇÇÇÇǼ¼¼ºººÀÀÀÌÌÌÑÑÑÎÎÎÅÅÅ»»»¸¸¸ÆÆÆÉÉÉÊÊÊÊÊÊÉÉÉÆÆÆÆÆÆÆÆÆÌÌÌÊÊÊÊÊÊÊÊÊÍÍͺººÂ¿¿¿ºººÆÆÆÍÍÍÌÌÌÇÇÇÉÉÉÌÌÌÉÉÉÆÆÆÊÊÊÍÍÍÊÊÊÅÅż¼¼µµµ±±±´´´···¿¿¿ÅÅŸ¸¸´´´µµµ¬¬¬¿¿¿ÃÃÃÍÍÍÎÎλ»»´´´°°°¬¬¬±±±±±±ªªª¦¦¦­­­¸¸¸···ÆÆÆµµµ¸¸¸ººººººÂÂÂÂÂÂÅÅÅÆÆÆ¿¿¿ÜÜÜÒÒÒÑÑÑÊÊÊ¿¿¿¼¼¼¿¿¿»»»¸¸¸¸¸¸ººº¸¸¸µµµ³³³³³³±±±­­­¯¯¯¿¿¿ÎÎÎÅÅ۰°³³³···¼¼¼ÂÂÂÃÃÃÃÃÃÅÅÅÆÆÆ¾¾¾ÃÃþ¾¾ÎÎÎÍÍ͸¸¸¿¿¿ÅÅÅÉÉÉÃÃÃÃÃÃÇÇÇÕÕÕÀÀÀ¸¸¸¯¯¯¸¸¸¼¼¼»»»¼¼¼ÅÅÅÐÐÐÒÒÒ××××××ÙÙÙÜÜÜ×××ÆÆÆ¸¸¸±±±»»»ÉÉɼ¼¼¸¸¸ÉÉÉÅÅž¾¾ººº»»»»»»¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÂÂÂÂÂÂÀÀÀ¿¿¿ÂÂÂÆÆÆÊÊÊÍÍÍÎÎÎÒÒÒ×××ÕÕÕÍÍÍÉÉÉÉÉÉÅÅÅßßßäääÊÊÊÂÂÂÀÀÀ¾¾¾¬¬¬¼¼¼ÐÐÐÅÅÅÆÆÆÅÅÅ´´´µµµÐÐÐäääèèèäääÕÕÕÔÔÔÔÔÔ×××ÙÙÙÌÌÌÃÃÃÇÇÇÐÐÐÛÛÛãããâââÛÛÛÒÒÒÔÔÔÔÔÔÔÔÔÔÔÔ×××ÝÝÝÝÝÝ×××ÎÎÎÊÊÊÂÂÂÅÅÅÐÐÐÐÐÐÆÆÆÃÃúºº¾¾¾ÍÍÍÙÙÙÙÙÙÜÜÜßßßÜÜÜÔÔÔÐÐÐàààÝÝÝßßßÛÛÛ×××···ÀÀÀÆÆÆÅÅż¼¼µµµµµµ»»»¾¾¾¾¾¾±±±±±±µµµ­­­©©©´´´¿¿¿ÃÃÃÃÃÃÆÆÆÉÉÉÉÉÉÃÃü¼¼···ÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÊÊÊ¿¿¿´´´¿¿¿ÃÃÃÇÇÇÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÅÅÅÃÃÃÊÊÊÐÐÐÒÒÒ···¾¾¾¼¼¼¸¸¸ÆÆÆÊÊÊÌÌÌÇÇÇÃÃÃÌÌÌÊÊÊÎÎÎÍÍÍÌÌÌÉÉÉÉÉÉÃÃ÷··ªªª¯¯¯¤¤¤¨¨¨¾¾¾ÍÍÍÅÅÅ···°°°»»»ÌÌÌÀÀÀ¼¼¼ººº¯¯¯···³³³¬¬¬³³³­­­±±±¿¿¿ÉÉÉÐÐÐÌÌÌÝÝÝÍÍÍÊÊÊÀÀÀ»»»ÂÂÂÂÂÂÂÂÂÆÆÆÇÇÇÝÝÝÕÕÕÐÐÐÅÅÅÉÉÉÇÇǾ¾¾»»»¸¸¸¸¸¸¸¸¸···´´´±±±µµµ´´´­­­ªªªºººÎÎÎÕÕÕÍÍͱ±±³³³¸¸¸ÂÂÂÆÆÆÇÇÇÇÇÇÉÉɾ¾¾Â¿¿¿ÍÍÍÌÌÌ···¼¼¼ºººÇÇÇÑÑÑÒÒÒÊÊÊÆÆÆ¸¸¸´´´¸¸¸¾¾¾ºººººº¸¸¸¸¸¸ÃÃÃÃÃÃÃÃÃÃÃÃÊÊÊÕÕÕÔÔÔÃÃó³³­­­¼¼¼ÅÅż¼¼±±±ÂÂÂÅÅÅ»»»¼¼¼¼¼¼¾¾¾¾¾¾¿¿¿ÀÀÀÀÀÀÀÀÀ¿¿¿ÂÂÂÂÂÂÃÃÃÇÇÇÎÎÎÔÔÔÔÔÔÑÑÑÔÔÔÐÐÐÊÊÊÉÉÉÆÆÆÆÆÆÐÐÐàààÒÒÒÂÂÂÅÅÅÀÀÀººº´´´¿¿¿ÕÕÕÅÅÅÂÂÂÆÆÆººº­­­ºººÎÎÎÝÝÝêêêäääßßßØØØÒÒÒÛÛÛÛÛÛàààßßßÝÝÝÝÝÝßßßÝÝÝÙÙÙÕÕÕÛÛÛÜÜÜßßßØØØÔÔÔÙÙÙÛÛÛÒÒÒÕÕÕÒÒÒÅÅÅÂÂÂÑÑÑÔÔÔÌÌÌÊÊÊÆÆÆÅÅÅÐÐÐÜÜÜÝÝÝÜÜÜÜÜÜ×××ÑÑÑÕÕÕâââÙÙÙßßßÛÛÛÔÔÔ¸¸¸ÀÀÀÅÅÅÆÆÆ¿¿¿¸¸¸···»»»¿¿¿ÅÅŵµµ¯¯¯¯¯¯ªªª­­­¸¸¸¾¾¾ÂÂÂÅÅÅÇÇÇÊÊÊÅÅż¼¼¸¸¸¸¸¸ÊÊÊÇÇÇÃÃÃÃÃÃÉÉÉÍÍÍÆÆÆ¼¼¼ººº¾¾¾ÃÃÃÆÆÆÆÆÆÅÅÅÅÅÅÅÅÅÀÀÀÆÆÆÎÎÎÎÎÎÎÎη··¿¿¿¾¾¾¼¼¼ÃÃÃÂÂÂÊÊÊÊÊÊÃÃÃÊÊÊÉÉÉÉÉÉÇÇÇÃÃÃÃÃÃÉÉÉÎÎÎÌÌÌÅÅž¾¾¬¬¬¢¢¢­­­ÀÀÀÉÉÉÇÇÇÅÅÅÃÃÃÍÍÍ´´´¯¯¯¯¯¯¨¨¨´´´°°°©©©´´´©©©±±±ÂÂÂÂÂÂÀÀÀ¾¾¾ÉÉÉÊÊÊÐÐо¾¾µµµÇÇÇÍÍÍÊÊÊÊÊÊÎÎÎÜÜÜÛÛÛÕÕÕÃÃÃÊÊÊ¿¿¿»»»ººº¸¸¸¸¸¸······µµµ³³³­­­­­­¬¬¬±±±ÃÃÃÕÕÕØØØÑÑѼ¼¼¸¸¸»»»ÂÂÂÅÅÅÀÀÀ»»»ººº¿¿¿ÀÀÀÀÀÀ¿¿¿ÉÉÉÇÇÇ´´´µµµ°°°µµµÅÅÅÔÔÔÎÎξ¾¾µµµ¸¸¸»»»ººº¯¯¯³³³µµµ±±±µµµ­­­³³³´´´»»»ÅÅÅÉÉÉÃÃø¸¸°°°¸¸¸¿¿¿ÃÃñ±±»»»ÂÂÂÇÇÇ¿¿¿¾¾¾¾¾¾¿¿¿¿¿¿ÀÀÀÀÀÀÀÀÀ¿¿¿ÅÅÅÉÉÉÊÊÊÎÎÎÔÔÔÕÕÕÑÑÑ¿¿¿ÀÀÀÀÀÀÅÅÅÊÊÊÉÉÉÐÐÐßßßÉÉɾ¾¾¾¾¾¾¾¾¾¾¾»»»ÅÅÅÍÍÍÎÎÎÉÉÉÃÃÃÃÃÃÀÀÀ¸¸¸···Â´´´ÕÕÕàààäääâââÔÔÔÔÔÔØØØÜÜÜÙÙÙ××××××ÛÛÛâââçççëëëßßßâââçççâââÙÙÙÜÜÜÛÛÛÎÎÎØØØØØØÑÑÑÉÉÉÍÍÍÔÔÔÔÔÔÐÐÐÇÇÇÀÀÀÇÇÇØØØßßßäääæææàààØØØÝÝÝãããÙÙÙâââ×××ÎÎÎÀÀÀÆÆÆÂ¼¼¼ººº¸¸¸ººº¼¼¼¿¿¿ÀÀÀ¸¸¸¸¸¸¸¸¸´´´···»»»¸¸¸¼¼¼¿¿¿ÅÅÅÅÅż¼¼µµµ¸¸¸ÂÂÂÆÆÆÉÉÉÉÉÉÉÉÉÍÍÍÎÎÎÃÃô´´···»»»ÀÀÀ¿¿¿¾¾¾¼¼¼ÀÀÀÌÌÌÔÔÔÍÍÍÊÊʺººÅÅÅÀÀÀÀÀÀÀÀÀ»»»ÉÉÉÎÎÎÆÆÆÉÉÉÅÅÅÇÇÇÇÇÇÃÃû»»»»»ÃÃÃÊÊÊÍÍÍÆÆÆººº¬¬¬¦¦¦¬¬¬³³³³³³°°°µµµ¿¿¿­­­···¼¼¼­­­¬¬¬žžžÉÉÉÛÛÛÎÎÎÐÐÐØØØÇÇÇÀÀÀÂÂÂÀÀÀÔÔÔâââÆÆÆ¸¸¸ÑÑÑÙÙÙÑÑÑóóóèèèÜÜÜÒÒÒÐÐп¿¿ÌÌ̺ºº¸¸¸¸¸¸¸¸¸············µµµ³³³©©©¤¤¤­­­ÆÆÆÛÛÛÛÛÛÑÑѰ°°­­­°°°¼¼¼ÆÆÆÆÆÆÂÂÂÂÂÂÀÀÀ¿¿¿ÀÀÀ¿¿¿ÅÅÅÃÃð°°¯¯¯¸¸¸­­­···ÔÔÔØØØÀÀÀµµµ¸¸¸´´´´´´°°°ÅÅÅÒÒÒÍÍÍÅÅű±±···ºººººº»»»ÃÃÃÌÌÌÉÉÉ¿¿¿³³³¼¼¼ÉÉÉ´´´···¾¾¾ÉÉÉ¿¿¿¿¿¿¿¿¿ÀÀÀÀÀÀÀÀÀÂÂÂÂÂÂÂÂÂÊÊÊÐÐÐÑÑÑÒÒÒÕÕÕÑÑÑÊÊÊÃÃÃÀÀÀÅÅÅÍÍÍÊÊÊÂÂÂÂÂÂÍÍ͵µµºººÃÃõµµ···ºººÎÎÎÐÐÐÂÂÂÐÐÐÌÌÌÂÂÂÅÅÅÆÆÆÂÂÂÃÃúººÀÀÀ°°°ºººÛÛÛâââÛÛÛÔÔÔÙÙÙÛÛÛÝÝÝßßßÝÝÝÛÛÛØØØ×××ÝÝÝÝÝÝâââàààßßßêêêíííÝÝÝ×××ÙÙÙÛÛÛÑÑÑÇÇÇÑÑÑÛÛÛÒÒÒÑÑÑÃÃÃÆÆÆÔÔÔÜÜÜââââââÛÛÛÛÛÛÝÝÝÝÝÝÔÔÔßßßÌÌÌÃÃÃÂÂÂÌÌÌÀÀÀ´´´±±±···¼¼¼¿¿¿¾¾¾¸¸¸µµµ¸¸¸¸¸¸±±±´´´¸¸¸³³³µµµ»»»ÀÀÀ¿¿¿µµµ±±±»»»ÊÊÊÃÃÃÂÂÂÀÀÀÃÃÃÇÇÇÌÌÌÍÍÍÍÍÍÇÇÇ»»»ººº¾¾¾ÀÀÀÀÀÀ¿¿¿ÎÎÎÌÌÌÍÍÍÐÐÐÊÊÊÀÀÀ¿¿¿ÅÅÅÃÃÃÂÂÂÂÂÂÅÅÅÉÉÉÊÊÊÉÉÉÆÆÆÂ¸¸¸¿¿¿ºººººº¾¾¾»»»ÌÌÌÌÌ̺ºº¨¨¨¥¥¥¦¦¦¨¨¨©©©­­­³³³­­­¯¯¯µµµ±±±©©©°°°Â»»»ÃÃÃÅÅž¾¾ÃÃÃÉÉÉÃÃÃÂÂÂÊÊÊÉÉÉÙÙÙÎÎÎÒÒÒãããÔÔÔÕÕÕÜÜÜÛÛÛØØØÒÒÒÍÍÍÇÇǾ¾¾¸¸¸······´´´³³³³³³´´´µµµ¥¥¥¢¢¢³³³ÊÊÊÒÒÒ××××××ÐÐÐ¥¥¥°°°ººº¾¾¾ÂÂÂÇÇÇÆÆÆ¿¿¿ÀÀÀ¾¾¾¿¿¿ÀÀÀÂÂÂÉÉÉÇÇÇ»»»­­­¬¬¬¼¼¼××××××¾¾¾°°°···³³³´´´±±±ÃÃÃßßßÛÛÛÉÉÉÊÊʵµµ······±±±»»»Â¾¾¾ÍÍÍÆÆÆ±±±ºººÇÇÇÌÌ̾¾¾³³³ÇÇÇÅÅÅ¿¿¿ÀÀÀÃÃÃÃÃÃÃÃÃÃÃÃÊÊÊÊÊÊÎÎÎÔÔÔÒÒÒÌÌÌÇÇÇÉÉÉÌÌÌÔÔÔÎÎÎÂÂÂÀÀÀÍÍÍÐÐÐÇÇǼ¼¼¿¿¿±±±¸¸¸ÌÌÌÑÑÑÑÑÑÊÊÊÊÊÊÊÊÊÉÉÉÆÆÆÅÅÅÅÅÅÅÅÅÆÆÆÍÍÍÊÊÊ¿¿¿ÃÃü¼¼···×××îîîÔÔÔØØØ×××ØØØ×××ÝÝÝèèèÛÛÛñññííííííúúúñññàààçççààààààæææÝÝÝÙÙÙÜÜÜÍÍÍÂÂÂÑÑÑØØØÔÔÔÀÀÀÂÂÂÝÝÝäääÙÙÙÝÝÝÑÑÑÙÙÙàààÙÙÙÊÊÊÀÀÀÂÂÂÇÇÇ¿¿¿ÇÇDZ±±¸¸¸Â¼¼¼ÅÅÅ»»»ÀÀÀ¼¼¼¸¸¸ººº¸¸¸±±±±±±»»»ºººÂÂÂÊÊÊ···µµµÊÊÊÍÍÍÍÍÍÅÅÅ¿¿¿ÂÂÂÆÆÆÊÊÊÊÊÊÊÊÊÉÉÉÃÃþ¾¾ººº»»»¼¼¼»»»ºººÌÌÌÎÎÎÑÑÑÎÎÎÅÅž¾¾ÀÀÀÆÆÆÅÅÅÃÃÃÂÂÂÂÂÂÃÃÃÅÅÅÅÅÅÃÃû»»···»»»ººº»»»¾¾¾¿¿¿ÉÉÉÀÀÀ¸¸¸­­­©©©¨¨¨¤¤¤¡¡¡¡¡¡¢¢¢©©©°°°³³³±±±³³³¸¸¸¿¿¿ÂÂÂ×××ÙÙÙÇÇÇÀÀÀÂÂÂÂÂÂÅÅÅÆÆÆÌÌÌÜÜÜÍÍÍÐÐÐæææÝÝÝßßßÛÛÛÙÙÙ×××ÒÒÒÌÌÌÆÆÆÀÀÀ¾¾¾´´´±±±±±±µµµ¸¸¸µµµ°°°ªªªµµµ±±±¿¿¿ÐÐÐÔÔÔ××××××ÒÒÒ¯¯¯°°°···¾¾¾¾¾¾ººº···¸¸¸¾¾¾»»»¿¿¿ÀÀÀÀÀÀÆÆÆÇÇǼ¼¼³³³±±±ºººÆÆÆÉÉÉÀÀÀ¸¸¸¸¸¸´´´ººº´´´¾¾¾ÛÛÛâââÑÑÑÉÉÉ´´´³³³´´´¬¬¬¬¬¬±±±°°°¾¾¾¾¾¾Â¿¿¿´´´¼¼¼ÆÆÆ¿¿¿ÌÌÌÍÍÍÇÇÇÀÀÀ¾¾¾ÃÃÃÇÇÇÇÇÇÃÃÃÃÃÃÇÇÇÎÎÎÑÑÑÌÌÌÂÂÂÀÀÀÅÅÅÑÑÑÊÊÊÂÂÂÀÀÀÍÍÍÕÕÕÎÎο¿¿»»»¼¼¼···ÊÊÊÜÜÜÕÕÕÎÎÎÌÌÌÎÎÎÊÊÊÊÊÊÍÍÍÍÍÍÊÊÊÌÌÌÐÐÐÉÉÉÉÉÉÂÂÂÌÌÌÍÍ;¾¾³³³æææßßßÙÙÙàààÛÛÛÙÙÙææææææíííêêêâââïïïöööíííïïïïïïãããæææãããßßßÙÙÙ×××ÐÐÐÉÉÉÕÕÕØØØÌÌÌÃÃÃÒÒÒÜÜÜÜÜÜßßßÜÜÜÙÙÙÔÔÔÊÊÊÃÃÃÀÀÀÃÃÃÇÇÇÉÉÉÇÇǪªª¯¯¯»»»¸¸¸Â¼¼¼¾¾¾»»»»»»···­­­©©©­­­³³³¸¸¸¾¾¾Âµµµ»»»ÉÉÉÃÃÃÂÂÂÅÅÅÀÀÀ¼¼¼¿¿¿ÅÅÅÊÊÊÌÌÌÌÌÌÌÌÌÉÉÉÃÃÿ¿¿¼¼¼»»»ººººººÌÌÌÒÒÒÔÔÔÊÊʾ¾¾»»»ÂÂÂÇÇÇÅÅÅÅÅÅÃÃÃÀÀÀ¿¿¿¾¾¾¿¿¿Âººº¾¾¾»»»¾¾¾¼¼¼¿¿¿ÉÉÉÆÆÆ¾¾¾¼¼¼ºººµµµ±±±¯¯¯©©©¢¢¢¤¤¤¯¯¯±±±ªªª¬¬¬ºººÅÅÅÇÇǸ¸¸ÑÑÑÒÒÒ¼¼¼ÃÃÃÍÍÍÔÔÔ¿¿¿ÎÎÎããã××××××èèèßßßØØØÛÛÛÙÙÙ×××ÑÑÑÌÌÌÆÆÆÂ¿¿¿´´´¯¯¯¯¯¯´´´···³³³°°°¯¯¯ÊÊÊÇÇÇÐÐÐØØØØØØØØØØØØÕÕÕÉÉɺºº´´´¿¿¿ÃÃúººµµµººº¸¸¸¸¸¸¾¾¾ÀÀÀ¿¿¿ÃÃÃÇÇÇÀÀÀººº³³³±±±ºººÀÀÀ¿¿¿¼¼¼ººº···ÀÀÀººº¸¸¸ÑÑÑààà×××ÊÊÊÆÆÆÂÂÂÉÉɼ¼¼­­­°°°±±±···ºººÇÇÇÍÍͺºº¸¸¸ÅÅÅÀÀÀ¼¼¼ÇÇÇÍÍÍÍÍÍÇÇÇÃÃÃÇÇÇÊÊÊÊÊÊÉÉÉÎÎÎÕÕÕÔÔÔÉÉɾ¾¾ÀÀÀÊÊÊÑÑѾ¾¾ºººÅÅÅÙÙÙÔÔÔÇÇÇ»»»ººº¸¸¸»»»ÙÙÙæææÒÒÒÌÌÌÎÎÎÐÐÐÊÊÊÉÉÉÌÌÌÌÌÌÉÉÉÊÊÊÎÎÎÑÑÑÑÑÑÇÇÇÉÉÉÐÐÐÒÒÒÑÑÑÅÅÅÉÉÉÀÀÀ¸¸¸¾¾¾»»»¼¼¼ÒÒÒÜÜÜäääãããÐÐÐÆÆÆÃÃþ¾¾ÎÎÎçççÝÝÝëëëîîîæææØØØÝÝÝØØØÍÍÍÒÒÒÛÛÛ×××ÉÉÉÆÆÆÒÒÒÛÛÛÛÛÛÜÜÜÑÑÑÆÆÆÀÀÀÂÂÂÆÆÆÇÇÇÇÇÇÉÉÉÅÅŪªª¯¯¯µµµ­­­···»»»ººº¸¸¸¿¿¿¾¾¾´´´¼¼¼ÆÆÆÂ´´´···ººº¸¸¸ÆÆÆÎÎÎÅÅÅÆÆÆÆÆÆÀÀÀ»»»»»»ÀÀÀÉÉÉÍÍÍÐÐÐÎÎÎÎÎÎÌÌÌÇÇÇÃÃÃÀÀÀÂÂÂÃÃÃÎÎÎÒÒÒÐÐÐÃÃû»»¾¾¾ÃÃÃÅÅÅÃÃÃÃÃÃÅÅÅ¿¿¿¾¾¾¿¿¿ÀÀÀ¿¿¿ÇÇǾ¾¾ÀÀÀ¿¿¿¿¿¿ÑÑÑÅÅž¾¾¾¾¾¸¸¸´´´µµµººº´´´©©©¢¢¢­­­°°°©©©ªªª···¿¿¿¿¿¿¿¿¿ÍÍÍÇÇÇÃÃÃÆÆÆÆÆÆÉÉÉÆÆÆ×××ÝÝÝëëëãããäääîîîâââÛÛÛÜÜÜÛÛÛ×××ÒÒÒÍÍÍÉÉÉÅÅÅÃÃø¸¸···´´´±±±­­­¯¯¯»»»ÉÉÉØØØØØØÜÜÜßßßÝÝÝÛÛÛÙÙÙØØØÕÕÕ»»»ªªª°°°¸¸¸···³³³³³³´´´µµµ¼¼¼ÀÀÀ¾¾¾ÂÂÂÆÆÆÃÃÃÃÃ󳳬¬¬···¿¿¿»»»ººº¾¾¾¼¼¼ÅÅż¼¼´´´ÃÃÃÒÒÒÔÔÔÑÑÑÉÉÉÅÅÅÒÒÒÇÇÇ­­­¬¬¬­­­©©©³³³°°°ÅÅÅÍÍÍÀÀÀÂÂÂÇÇÇÀÀÀ¾¾¾ÊÊÊÑÑÑÎÎÎÌÌÌÎÎÎÐÐÐÍÍÍÔÔÔÔÔÔÔÔÔÐÐÐÆÆÆ¿¿¿ÆÆÆÐÐÐÊÊʸ¸¸¿¿¿ÐÐÐÝÝÝÇÇǾ¾¾¼¼¼¸¸¸ººº¿¿¿ÙÙÙàààÎÎÎÎÎÎÑÑÑÍÍÍÌÌÌÉÉÉÇÇÇÉÉÉÍÍÍÐÐÐÐÐÐÕÕÕÍÍÍ¿¿¿»»»ÀÀÀÊÊÊÑÑÑÐÐÐÊÊÊÎÎÎÊÊÊÊÊÊÃÃþ¾¾ÉÉÉÊÊÊ¿¿¿ÃÃÃÅÅÅÌÌÌÒÒÒÎÎÎÐÐÐÙÙÙÒÒÒòòòøøøîîîÝÝÝÜÜÜÕÕÕÛÛÛÒÒÒÕÕÕÙÙÙÒÒÒÆÆÆÌÌÌÔÔÔÑÑÑÌÌÌÆÆÆÀÀÀÃÃÃÊÊÊÎÎÎÌÌÌÇÇÇÆÆÆÊÊÊÀÀÀÅÅÅ¿¿¿¬¬¬±±±¼¼¼¿¿¿»»»ÀÀÀ¾¾¾´´´ÂÂÂÍÍ;¾¾ÃÃÃÆÆÆÂÂÂÅÅÅÎÎÎÉÉÉ¿¿¿ÆÆÆÎÎÎÉÉÉÀÀÀ¼¼¼¾¾¾ÃÃÃÊÊÊÎÎÎÑÑÑÒÒÒÒÒÒÑÑÑÍÍÍÌÌÌÍÍÍÐÐÐÑÑÑÐÐÐÇÇǾ¾¾»»»ÂÂÂÃÃÿ¿¿¿¿¿ÂÂÂÆÆÆÆÆÆÃÃÃÀÀÀÀÀÀ¿¿¿ÆÆÆºººÀÀÀ¾¾¾¿¿¿×××ÆÆÆ¼¼¼´´´¨¨¨¢¢¢ªªª´´´°°°¥¥¥©©©···ÇÇÇÒÒÒÔÔÔÐÐÐÇÇÇÂÂÂÆÆÆÊÊÊ¿¿¿ÇÇÇÒÒÒÌÌÌÍÍÍÉÉÉßßßÔÔÔÐÐÐÍÍÍÐÐÐÕÕÕÒÒÒÕÕÕÜÜÜÛÛÛØØØÔÔÔÐÐÐÍÍÍÊÊÊÉÉÉ¿¿¿¸¸¸°°°¯¯¯¸¸¸ÌÌÌÜÜÜÜÜÜàààâââââââââßßßÛÛÛÙÙÙÜÜÜÌÌÌ···­­­­­­±±±´´´´´´³³³³³³»»»ÀÀÀ¾¾¾¿¿¿ÆÆÆÅÅÅÊÊÊ»»»°°°³³³¸¸¸¸¸¸¼¼¼ÀÀÀÂÂÂÃÃü¼¼´´´µµµ¼¼¼ÉÉÉØØØ¾¾¾¼¼¼ÒÒÒÌÌ̱±±°°°°°°¦¦¦···©©©ºººÑÑÑÆÆÆºººÃÃÃÆÆÆÀÀÀÂÂÂÃÃÃÇÇÇÑÑÑØØØÕÕÕÌÌÌØØØÎÎÎÅÅÅÀÀÀ¿¿¿ÀÀÀÉÉÉÑÑÑÉÉɸ¸¸ÆÆÆÕÕÕßßß¿¿¿¸¸¸¼¼¼µµµÀÀÀÊÊÊÛÛÛÛÛÛÐÐÐÔÔÔÒÒÒÌÌÌÑÑÑÐÐÐÉÉÉÍÍÍÙÙÙÜÜÜÔÔÔÃÃþ¾¾ÀÀÀÌÌÌØØØÛÛÛÔÔÔÐÐÐÇÇÇ×××ßßßëëëäääÒÒÒÎÎÎÍÍÍÍÍÍÍÍÍØØØàààßßßßßßààààààÒÒÒêêêñññöööãããßßßÕÕÕàààÕÕÕÌÌÌÔÔÔÛÛÛÐÐÐÊÊÊÌÌÌÆÆÆÂÂÂÃÃÃÆÆÆÍÍÍÑÑÑÑÑÑÍÍÍÉÉÉÀÀÀÇÇÇÅÅÅÉÉɬ¬¬©©©³³³¾¾¾¾¾¾ÇÇÇÀÀÀ±±±¾¾¾ÌÌÌ¿¿¿ÆÆÆÊÊÊÉÉÉÌÌÌÍÍÍÂÂÂÃÃÃÒÒÒÙÙÙÔÔÔÌÌÌÃÃþ¾¾¿¿¿ÅÅÅÉÉÉÑÑÑÒÒÒÕÕÕÕÕÕÒÒÒÑÑÑÑÑÑÒÒÒÐÐÐÊÊÊÀÀÀ»»»¾¾¾ÂÂÂÀÀÀ¼¼¼¾¾¾ÀÀÀÅÅÅÇÇÇÆÆÆÅÅÅ»»»¾¾¾´´´¿¿¿¼¼¼¿¿¿×××ÇÇǾ¾¾°°°¡¡¡¤¤¤ªªª©©©¡¡¡ŸŸŸ©©©¾¾¾ÑÑÑÕÕÕÊÊÊÀÀÀ¾¾¾ÀÀÀÃÃí­­´´´ÂÂÂÉÉÉßßßèèèäääÕÕÕÎÎÎÔÔÔÙÙÙØØØØØØÝÝÝÛÛÛÙÙÙ×××ÔÔÔÑÑÑÎÎÎÎÎÎÍÍÍÉÉÉÆÆÆ»»»³³³ºººÌÌÌÙÙÙÜÜÜÜÜÜââââââàààäääãããßßßÜÜÜààààààÕÕÕ¾¾¾¯¯¯°°°µµµ¸¸¸³³³±±±ºººÂ¾¾¾¿¿¿ÅÅÅÆÆÆÌÌÌÊÊÊ¿¿¿±±±¯¯¯ºººÀÀÀÂÂÂÃÃÿ¿¿ºººµµµ¯¯¯¯¯¯ÀÀÀÛÛÛ¾¾¾¿¿¿ÕÕÕÐÐм¼¼ÂÂÂÀÀÀ···³³³´´´···ÊÊÊÍÍÍ»»»···»»»ÀÀÀ¿¿¿¾¾¾ÀÀÀÆÆÆÍÍÍÒÒÒÔÔÔ×××ÉÉɼ¼¼¼¼¼ÂÂÂÇÇÇÐÐÐ×××ÌÌ̺ººÇÇÇÑÑÑâââÀÀÀ»»»¸¸¸´´´ÉÉÉÙÙÙäääÜÜÜÕÕÕÙÙÙÐÐÐÑÑÑ×××ÕÕÕÍÍÍÎÎÎÔÔÔÐÐÐÃÃúºº»»»ÊÊÊÒÒÒÒÒÒÍÍÍÂÂÂÆÆÆÉÉÉÌÌÌÎÎÎãããàààÅÅÅÃÃÃÐÐÐëëëàààäääÛÛÛÊÊÊÐÐÐÛÛÛäääÛÛÛÙÙÙàààúúúäääçççÜÜÜÛÛÛÙÙÙÊÊÊÐÐÐÝÝÝÙÙÙÐÐÐÉÉÉÂÂÂÅÅÅÉÉÉÍÍÍÐÐÐÐÐÐÍÍÍÊÊÊÉÉÉÇÇÇÅÅÅ¿¿¿ÂÂÂÃÃ÷··­­­±±±´´´¿¿¿ÊÊʰ°°¸¸¸ÉÉÉÇÇǼ¼¼ÂÂÂÅÅÅÌÌÌÇÇÇÀÀÀÑÑÑàààÛÛÛÙÙÙÕÕÕÌÌÌ¿¿¿ÂÂÂÇÇÇÐÐÐÑÑÑÒÒÒÑÑÑÎÎÎÌÌÌÊÊÊÉÉÉÌÌÌÃÃþ¾¾¾¾¾¿¿¿¾¾¾¼¼¼¼¼¼¿¿¿ÀÀÀÂÂÂÅÅÅÆÆÆÅÅÅÂÂÂÀÀÀ»»»¸¸¸ÇÇÇÂÂÂÂÂÂÒÒÒÅÅŸ¸¸¯¯¯¨¨¨¦¦¦©©©©©©¨¨¨¦¦¦¬¬¬¯¯¯µµµ¿¿¿ÃÃÃÅÅÅÇÇÇÍÍÍÃÃÃÍÍͰ°°©©©³³³ÂÂÂàààäääÒÒÒÐÐÐÐÐÐ××××××ÑÑÑÒÒÒÕÕÕ×××ÕÕÕÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÉÉÉÌÌ̵µµ¾¾¾ÕÕÕÝÝÝ×××ÝÝÝãããßßßÛÛÛãããæææâââàààÛÛÛâââÝÝÝÊÊʺººµµµ³³³¯¯¯µµµ±±±¸¸¸Â¿¿¿ÀÀÀÅÅÅÅÅÅÉÉÉÑÑÑÐÐп¿¿´´´¸¸¸¾¾¾¾¾¾¿¿¿ººº···´´´¯¯¯¯¯¯ÀÀÀÕÕÕÃÃÃÂÂÂÎÎÎÅÅźººÂÂÂÀÀÀºººžžž­­­¬¬¬¼¼¼ÎÎÎÇÇÇÃÃÃÀÀÀ¾¾¾¿¿¿Âººº···ÆÆÆØØØÉÉÉÀÀÀ»»»¿¿¿ÇÇÇÍÍÍÔÔÔÙÙÙÌÌ̾¾¾ÊÊÊÍÍÍßßßÅÅÅÀÀÀ¸¸¸´´´ÌÌÌßßßèèèÛÛÛÒÒÒÙÙÙÐÐÐÕÕÕÔÔÔÔÔÔ×××ÔÔÔÊÊʼ¼¼³³³¾¾¾ÇÇÇØØØÑÑÑÌÌÌÐÐÐÑÑÑÝÝÝÆÆÆÂ¿¿¿ÕÕÕÛÛÛÉÉÉÔÔÔíííÐÐÐÍÍÍÛÛÛßßßäääêêêßßßÛÛÛØØØÑÑÑÕÕÕöööäääëëëÝÝÝ×××ÜÜÜÒÒÒÑÑÑÙÙÙÜÜÜ×××ÎÎÎÆÆÆÇÇÇÊÊÊÎÎÎÐÐÐÎÎÎÌÌÌÉÉÉÆÆÆÎÎÎÌÌÌÅÅÅÃÃÃÊÊÊÇÇÇ¿¿¿ÀÀÀ³³³ººº¾¾¾···¯¯¯³³³»»»¼¼¼ÆÆÆÆÆÆÇÇÇÐÐÐÀÀÀ¼¼¼ÒÒÒØØØÕÕÕÙÙÙÙÙÙÒÒÒÇÇÇÂÂÂÅÅÅÊÊÊÎÎÎÐÐÐÎÎÎÍÍÍÊÊÊÅÅÅ¿¿¿ÆÆÆÀÀÀ¿¿¿ÀÀÀ¿¿¿ºººººº¿¿¿ÂÂÂÀÀÀÀÀÀÀÀÀÃÃÃÃÃÃÀÀÀ¿¿¿ÍÍÍÂÂÂÃÃÃÑÑÑÊÊÊÅÅÅÎÎά¬¬©©©ªªª¯¯¯­­­¨¨¨¨¨¨¬¬¬´´´³³³¯¯¯¯¯¯³³³¼¼¼ÇÇÇÐÐо¾¾ÕÕÕÀÀÀ¸¸¸ÃÃÃÐÐÐßßßÍÍÍÍÍÍÒÒÒÔÔÔÒÒÒÍÍÍÊÊÊÑÑÑÕÕÕÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÐÐÐÐÐÐÆÆÆÑÑÑÊÊÊ···ºººÑÑÑÝÝÝØØØàààäääÜÜÜØØØâââçççääääääâââãããâââÙÙÙÒÒÒÊÊʼ¼¼¯¯¯···±±±¸¸¸ÂÂÂÀÀÀÀÀÀÅÅÅÅÅÅÅÅÅÐÐÐØØØÒÒÒ···µµµººº¼¼¼···´´´´´´±±±µµµÂÂÂÐÐÐÐÐÐÌÌÌÍÍͼ¼¼´´´¿¿¿¼¼¼¸¸¸¦¦¦¬¬¬¢¢¢¯¯¯¿¿¿ÆÆÆÐÐÐÇÇÇ¿¿¿¼¼¼ÀÀÀÃÃúºº±±±»»»ÎÎεµµ³³³µµµ¾¾¾ÆÆÆÉÉÉÎÎÎÒÒÒÉÉÉ¿¿¿ÐÐÐÊÊÊÜÜÜÃÃÃÆÆÆ¾¾¾···ÊÊÊÜÜÜæææÕÕÕÊÊÊÕÕÕÒÒÒÑÑÑÌÌÌÒÒÒâââãããÐÐо¾¾»»»ÂÂÂÉÉÉÕÕÕÇÇÇÅÅÅÎÎÎÃÃÿ¿¿ÃÃÃÆÆÆÀÀÀÎÎÎÒÒÒÅÅÅÊÊÊÛÛÛÎÎÎÕÕÕàààÝÝÝââââââÒÒÒÙÙÙÎÎÎÕÕÕÔÔÔïïïãããëëëÙÙÙÛÛÛßßßÛÛÛÕÕÕÕÕÕÙÙÙÛÛÛÔÔÔÍÍÍÅÅÅÇÇÇÌÌÌÐÐÐÑÑÑÎÎÎÉÉÉÅÅż¼¼¿¿¿¿¿¿»»»ÀÀÀ»»»¿¿¿±±±±±±¯¯¯±±±¿¿¿ÊÊÊÌÌÌÊÊÊÉÉÉÅÅÅÇÇÇÒÒÒÂÂÂÂÂÂÜÜÜØØØ×××ÔÔÔÔÔÔÕÕÕÎÎÎÅÅÅÂÂÂÅÅÅÊÊÊÃÃÃÅÅÅÆÆÆÂÂÂÆÆÆÊÊÊÃÃÃÆÆÆÃÃÃÀÀÀ¿¿¿ÀÀÀÂÂÂÀÀÀ¿¿¿¾¾¾¿¿¿ÃÃþ¾¾»»»ÌÌÌÕÕÕÌÌ̺ºº­­­°°°···±±±¬¬¬°°°³³³ªªªªªª©©©©©©ªªª­­­¯¯¯¯¯¯³³³±±±······­­­ÅÅÅÂÂÂÇÇÇàààÙÙÙÑÑÑÐÐÐÔÔÔÕÕÕÒÒÒÍÍÍÔÔÔÔÔÔÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÒÑÑÑÐÐÐÎÎÎÎÎÎÎÎÎÐÐÐÌÌÌÐÐÐÍÍÍ¿¿¿»»»ÒÒÒçççÛÛÛææææææâââäääàààâââîîîèèèêêêêêêçççääääääßßßÐÐп¿¿°°°³³³ºººÂÂÂÃÃÃÀÀÀÀÀÀÃÃÃÇÇÇÀÀÀÉÉÉÐÐÐÃÃø¸¸¸¸¸···´´´±±±°°°³³³³³³³³³»»»ÅÅÅÅÅÅÅÅÅÇÇÇÃÃû»»ºººµµµ©©©ŸŸŸ¤¤¤©©©¯¯¯´´´¾¾¾ÇÇÇÎÎÎÆÆÆ¸¸¸¼¼¼ÅÅž¾¾´´´±±±°°°³³³µµµ´´´ºººÅÅÅÆÆÆÇÇÇÔÔÔÊÊʾ¾¾ÇÇÇÒÒÒàààÌÌÌÃÃþ¾¾ÂÂÂÆÆÆßßßãããÔÔÔÍÍÍÉÉÉÎÎÎÍÍÍ×××ÜÜÜÜÜÜØØØÊÊʾ¾¾¿¿¿ÍÍÍÜÜÜÊÊÊÊÊÊÐÐÐÂÂÂÀÀÀºººÑÑÑÎÎÎÍÍÍÐÐÐÒÒÒÔÔÔÐÐÐÌÌÌÌÌÌâââæææçççÝÝÝÕÕÕÝÝÝÙÙÙÔÔÔÛÛÛÎÎÎÀÀÀèèèàààçççØØØâââàààÕÕÕ¿¿¿ÙÙÙÜÜÜÔÔÔÍÍÍÂÂÂßßßÎÎÎÆÆÆÆÆÆÃÃÃÊÊʸ¸¸¿¿¿¸¸¸···¾¾¾ÃÃÃÃÃÃÃÃÃÅÅÅ©©©¯¯¯°°°ÃÃÃÌÌÌÃÃÃÊÊÊÇÇÇÇÇÇÇÇÇÆÆÆÅÅÅÆÆÆÊÊÊÑÑÑÕÕÕ¿¿¿¾¾¾¾¾¾ÀÀÀÀÀÀ¿¿¿ÂÂÂÆÆÆÉÉÉÃÃÃÇÇÇÌÌÌÇÇÇÇÇÇÇÇÇÀÀÀ¿¿¿ÂÂÂÆÆÆÊÊÊÌÌÌÉÉÉÅÅÅÀÀÀÅÅÅ¿¿¿»»»¾¾¾ÅÅÅÍÍÍÃÃð°°¸¸¸¬¬¬¯¯¯µµµ°°°¬¬¬°°°³³³­­­¬¬¬ªªªªªª¬¬¬­­­¯¯¯°°°¸¸¸···ººº¸¸¸¬¬¬ÃÃÃÇÇÇÐÐÐÝÝÝÝÝÝàààæææèèèäääÙÙÙÑÑÑÕÕÕÕÕÕÕÕÕÔÔÔÔÔÔÒÒÒÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÐÐÐÐÐÐÐÐÐÐÐÐÑÑÑÌÌÌÌÌÌÊÊÊÀÀÀ¾¾¾ÐÐÐääääääçççãããâââëëëäääàààííííííïïïíííçççààààààâââÛÛÛÒÒÒ¸¸¸±±±°°°¸¸¸¿¿¿¿¿¿¿¿¿ÃÃÃÆÆÆÇÇÇÌÌÌÇÇǼ¼¼»»»¼¼¼···³³³¯¯¯°°°······±±±¬¬¬ªªª¸¸¸···¿¿¿ÀÀÀ´´´©©©¤¤¤¢¢¢¤¤¤¨¨¨¬¬¬­­­³³³ÀÀÀÎÎθ¸¸¼¼¼ÅÅž¾¾µµµ´´´³³³³³³µµµµµµºººÃÃÃÅÅÅÇÇÇÔÔÔÐÐп¿¿ÆÆÆÑÑÑßßßÌÌÌÅÅÅÀÀÀ¼¼¼¾¾¾ÕÕÕßßßÛÛÛÙÙÙÕÕÕ×××ÐÐÐÙÙÙÕÕÕÊÊÊÆÆÆÂÂÂÀÀÀÆÆÆÐÐÐÐÐÐÀÀÀÉÉÉÎÎÎÅÅÅÊÊÊÐÐÐÍÍÍÌÌÌÊÊÊÌÌÌÎÎÎÐÐÐÍÍÍÌÌÌÉÉÉÔÔÔÒÒÒ×××ÕÕÕÕÕÕãããâââçççßßßØØØÌÌÌëëëëëëäääÐÐÐÙÙÙâââÛÛÛÉÉÉßßßàààÔÔÔÉÉÉçççóóóÛÛÛÎÎÎÆÆÆºººÃÃÿ¿¿ÌÌÌÀÀÀººº¿¿¿ÉÉÉÌÌÌÉÉÉÆÆÆÆÆÆÊÊÊÅÅÅÉÉÉÆÆÆÀÀÀÊÊÊÊÊÊÊÊÊÍÍÍÐÐÐÐÐÐÌÌÌÇÇÇÅÅÅÅÅÅÊÊÊÉÉÉÅÅÅÀÀÀÃÃÃÉÉÉÍÍÍÎÎÎÊÊÊÆÆÆÇÇÇÉÉÉÆÆÆÅÅÅÃÃü¼¼¿¿¿ÅÅÅÍÍÍÒÒÒÒÒÒÐÐÐÌÌÌÇÇÇÊÊÊÉÉÉÅÅÅÇÇÇÎÎÎÉÉɺºº¯¯¯···­­­¯¯¯´´´±±±­­­°°°³³³±±±°°°¯¯¯¬¬¬¬¬¬­­­±±±³³³ººº······ººº¯¯¯ÅÅÅÍÍÍÙÙÙÜÜÜØØØÔÔÔÒÒÒÕÕÕØØØØØØÙÙÙÙÙÙÙÙÙÙÙÙØØØ×××ÔÔÔÑÑÑÐÐÐÔÔÔÒÒÒÑÑÑÐÐÐÐÐÐÑÑÑÒÒÒÒÒÒÎÎÎÉÉÉÆÆÆÀÀÀººº¿¿¿ÐÐÐàààèèèãããäääñññêêêàààîîîòòòñññïïïèèèããããããææææææãããÑÑÑ¿¿¿´´´ºººÀÀÀ¿¿¿¾¾¾ÀÀÀÆÆÆÍÍÍÎÎÎÀÀÀµµµ¾¾¾ÀÀÀµµµ¸¸¸±±±°°°µµµ»»»¸¸¸±±±¬¬¬¨¨¨¥¥¥°°°···¬¬¬¤¤¤¥¥¥¨¨¨©©©¨¨¨¨¨¨ªªª©©©­­­¼¼¼ÍÍ;¾¾¸¸¸¾¾¾ÃÃþ¾¾···µµµµµµ³³³µµµ···ºººÀÀÀÃÃÃÊÊÊÕÕÕØØØÅÅÅÉÉÉÔÔÔäääÐÐÐÉÉÉÆÆÆ¾¾¾ºººÌÌÌØØØÝÝÝàààÙÙÙØØØÕÕÕÛÛÛÎÎλ»»µµµ»»»ÂÂÂÌÌÌÝÝÝÑÑÑÀÀÀÇÇÇÍÍÍÀÀÀÆÆÆÙÙÙÇÇÇÇÇÇÇÇÇÇÇÇÊÊÊÌÌÌÌÌÌÌÌÌÑÑÑÔÔÔÐÐÐÕÕÕÕÕÕÑÑÑÕÕÕÕÕÕäääÐÐÐØØØÐÐÐàààòòòæææÙÙÙÜÜÜäääÛÛÛÌÌÌÛÛÛÝÝÝÙÙÙÒÒÒçççëëëÜÜÜÝÝÝÕÕÕÃÃÃÎÎÎÕÕÕÕÕÕÊÊÊÀÀÀÀÀÀÃÃÃÅÅÅÃÃÃÃÃÃÀÀÀÊÊÊÊÊÊÉÉÉÃÃÿ¿¿ÇÇÇÇÇÇÅÅÅÊÊÊÐÐÐÒÒÒÐÐÐÌÌÌÇÇÇÆÆÆÒÒÒÒÒÒÌÌÌÃÃÃÅÅÅÍÍÍÎÎÎÌÌÌÐÐÐÊÊÊÅÅÅÂÂÂÀÀÀÀÀÀÀÀÀ¿¿¿ÉÉÉÌÌÌÐÐÐÑÑÑÐÐÐÐÐÐÑÑÑÑÑÑÍÍÍÐÐÐÌÌÌÍÍÍÑÑÑÅÅŸ¸¸¼¼¼¸¸¸±±±°°°´´´´´´±±±³³³´´´···µµµ±±±¯¯¯­­­°°°³³³···µµµ±±±°°°¼¼¼¸¸¸ÌÌÌÑÑÑÙÙÙÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕ×××ÙÙÙÙÙÙÝÝÝÝÝÝÝÝÝÜÜÜÙÙÙ×××ÒÒÒÐÐÐÔÔÔÑÑÑÐÐÐÐÐÐÑÑÑÒÒÒÒÒÒÑÑÑÊÊÊÂÂÂÂÂÂÀÀÀ»»»···ÃÃÃãããêêêèèèêêêñññèèèãããóóóöööïïïïïïïïïíííêêêèèèçççäääÔÔÔ···¾¾¾Â¾¾¾¼¼¼ÂÂÂÃÃÃÍÍÍÌÌÌ¿¿¿···¼¼¼¾¾¾µµµººº´´´³³³µµµ»»»¼¼¼¸¸¸³³³­­­¨¨¨ªªª¬¬¬¨¨¨¬¬¬µµµ···­­­­­­ªªª©©©¬¬¬µµµÀÀÀÆÆÆ»»»¼¼¼ÀÀÀÃÃþ¾¾¸¸¸µµµµµµ´´´µµµ¸¸¸»»»¿¿¿ÅÅÅÍÍÍÕÕÕÙÙÙÇÇÇÐÐÐÜÜÜëëëÕÕÕÎÎÎÊÊÊÅÅÅ¿¿¿ÊÊÊÑÑÑ×××ØØØÑÑÑÔÔÔÛÛÛÛÛÛÎÎξ¾¾ººº¸¸¸¿¿¿ÌÌÌãããÙÙÙÉÉÉÆÆÆÎÎλ»»×××ÅÅÅÅÅÅÅÅÅÆÆÆÇÇÇÉÉÉÌÌÌÎÎÎÍÍÍÍÍÍÎÎÎ×××ÙÙÙÕÕÕÙÙÙßßßÕÕÕ¾¾¾ÔÔÔÉÉÉÇÇÇããã××××××ÝÝÝàààÕÕÕÑÑÑÛÛÛØØØÛÛÛÜÜÜæææèèèâââæææÜÜÜÊÊÊÔÔÔÜÜÜÕÕÕÒÒÒÌÌÌ···´´´¸¸¸¿¿¿ÂÂÂÉÉÉÇÇÇÀÀÀ¼¼¼¾¾¾Â¿¿¿ÂÂÂÆÆÆÊÊÊÍÍÍÍÍÍÎÎÎÑÑÑÒÒÒÍÍÍÎÎÎÌÌÌÆÆÆÉÉÉÐÐÐÑÑÑÍÍÍÍÍÍÊÊÊÆÆÆÅÅÅÇÇÇÉÉÉÉÉÉÊÊÊÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÑÑÑÔÔÔÎÎÎÎÎÎÇÇÇÊÊÊÎÎÎÀÀÀ´´´ººººººµµµ³³³µµµ¸¸¸¸¸¸µµµ¸¸¸ººº¸¸¸···³³³°°°±±±···»»»¼¼¼´´´±±±ÉÉÉÊÊÊÕÕÕÒÒÒÑÑÑÎÎÎÒÒÒÙÙÙßßßàààßßßÜÜÜÛÛÛàààààààààßßßÜÜÜØØØÒÒÒÑÑÑÒÒÒÑÑÑÎÎÎÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÊÊÊÂÂÂÆÆÆÃÃÿ¿¿µµµ»»»ãããëëëòòòñññïïïçççêêêúúúöööñññòòòòòòòòòîîîçççãããâââ»»»´´´´´´¼¼¼ÀÀÀ¼¼¼¾¾¾ÅÅÅÂÂÂÆÆÆÇÇÇÅÅÅ¿¿¿ººº···¸¸¸´´´µµµ¸¸¸ººº»»»ººº´´´¯¯¯³³³¯¯¯¬¬¬©©©¯¯¯ÂÂÂÌÌ̬¬¬­­­¨¨¨¥¥¥±±±ÂÂÂÃÃø¸¸¸¸¸ÀÀÀÅÅż¼¼¸¸¸´´´´´´´´´···ººº¼¼¼¿¿¿ÇÇÇÐÐÐÒÒÒÑÑÑÇÇÇÔÔÔßßßêêêÔÔÔÍÍÍÉÉÉÂÂÂÂÂÂÌÌÌÍÍÍÍÍÍÍÍÍÊÊÊÕÕÕÜÜÜÜÜÜÕÕÕÐÐÐÌÌÌ¿¿¿»»»ÅÅÅÑÑÑÙÙÙÑÑÑÃÃÃÑÑÑÌÌ̺ººØØØÅÅÅÅÅÅÆÆÆÆÆÆÇÇÇÊÊÊÍÍÍÎÎÎÔÔÔÐÐÐÑÑÑÑÑÑÎÎÎÐÐÐÙÙÙèèèÑÑÑ¿¿¿ÛÛÛ×××ÜÜÜöööêêêîîî××××××ÎÎÎßßßãããÕÕÕØØØßßßííííííæææãããØØØÒÒÒÜÜÜàààØØØÙÙÙÕÕÕÉÉɼ¼¼¸¸¸¼¼¼ÃÃÃÇÇÇÃÃÿ¿¿···¼¼¼ÊÊÊÎÎÎÎÎÎÇÇÇÉÉÉÊÊÊÌÌÌÊÊÊÌÌÌÐÐÐÑÑÑÑÑÑÒÒÒÒÒÒÑÑÑÒÒÒÔÔÔÒÒÒÐÐÐÆÆÆÌÌÌÍÍÍÑÑÑØØØØØØÔÔÔÕÕÕÒÒÒÒÒÒÒÒÒÒÒÒÐÐÐÎÎÎÎÎÎÐÐÐÐÐÐÑÑÑÒÒÒÐÐÐÉÉÉ»»»µµµ»»»»»»ºººµµµµµµ¼¼¼¼¼¼¸¸¸»»»ººº»»»ººº···´´´µµµººº¿¿¿ÆÆÆ¾¾¾¸¸¸×××ØØØÙÙÙÒÒÒÊÊÊÐÐÐÑÑÑÑÑÑÒÒÒÕÕÕÙÙÙÝÝÝßßßààààààßßßÝÝÝÙÙÙÕÕÕÒÒÒÐÐÐÑÑÑÎÎÎÎÎÎÐÐÐÑÑÑÐÐÐÌÌÌÇÇǾ¾¾¼¼¼Â»»»¼¼¼¸¸¸¸¸¸æææîîîøøøöööñññèèèïïïÿÿÿõõõõõõóóóòòòòòòíííæææââââââ³³³µµµ¼¼¼Â¿¿¿ÀÀÀÅÅÅÀÀÀÃÃÃÆÆÆÌÌÌÊÊÊ»»»µµµ¼¼¼ººº»»»»»»»»»¼¼¼ÂÂÂÃÃü¼¼»»»¸¸¸³³³ºººÍÍÍÎÎκºº©©©¨¨¨¢¢¢¥¥¥µµµÆÆÆÀÀÀ¯¯¯µµµÃÃÃÉÉɼ¼¼¸¸¸´´´´´´······»»»¿¿¿ÂÂÂÌÌÌÒÒÒÐÐÐÉÉÉÉÉÉØØØØØØÝÝÝÊÊÊÇÇÇÃÃþ¾¾ÃÃÃÐÐÐÎÎÎÌÌÌÉÉÉÇÇÇÙÙÙÙÙÙÝÝÝÜÜÜÜÜÜÛÛÛÌÌ̾¾¾¼¼¼ÂÂÂÒÒÒÙÙÙÃÃÃÎÎÎÐÐз··ÔÔÔÆÆÆÅÅÅÆÆÆÇÇÇÊÊÊÌÌÌÍÍÍÍÍÍÆÆÆÆÆÆÐÐÐÎÎÎÍÍÍÒÒÒØØØæææÎÎÎÂÂÂÍÍÍÉÉÉÝÝÝäääÒÒÒÎÎÎ×××ÕÕÕÇÇÇßßßßßßÔÔÔÝÝÝèèèæææææææææäääßßßàààãããÝÝÝÛÛÛÛÛÛØØØÒÒÒÐÐÐÐÐÐÐÐÐÍÍ͸¸¸´´´ººº¼¼¼ÉÉÉ×××ÔÔÔÒÒÒÆÆÆÉÉÉÍÍÍÍÍÍÍÍÍÌÌÌÌÌÌÍÍÍÒÒÒÑÑÑÒÒÒÔÔÔÑÑÑÌÌÌÉÉÉÉÉÉÉÉÉÐÐÐÑÑÑÕÕÕÝÝÝÜÜÜÕÕÕÕÕÕÕÕÕÔÔÔÒÒÒÑÑÑÑÑÑÑÑÑÐÐÐÐÐÐÔÔÔÔÔÔÕÕÕÎÎο¿¿···¼¼¼ÀÀÀººº»»»´´´´´´¼¼¼¾¾¾ººº»»»ººº»»»¼¼¼»»»¸¸¸¸¸¸¼¼¼ÂÂÂÅÅÅ¿¿¿»»»ÛÛÛØØØÔÔÔÑÑÑÍÍÍÎÎÎÐÐÐÒÒÒÕÕÕÙÙÙÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÛÛÛØØØÕÕÕÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÍÍÍÐÐÐÑÑÑÎÎÎÇÇÇÀÀÀººº¾¾¾Â´´´¼¼¼ÂÂÂÂÂÂñññòòòøøøøøøøøøñññòòòüüüòòòóóóññññññóóóñññêêêäääää人ºÀÀÀÅÅÅÅÅÅÅÅÅÅÅÅÃÃÃÂÂÂÀÀÀÆÆÆÊÊÊÑÑÑÑÑѺººÂÂÂÅÅÅÀÀÀ»»»ºººÂÂÂÐÐÐÕÕÕÒÒÒÐÐÐÍÍÍÊÊÊÅÅÅÂÂÂÉÉÉÃÃð°°­­­¥¥¥¢¢¢¬¬¬¼¼¼Âººº°°°°°°ÅÅÅÊÊÊÀÀÀ¼¼¼ºººµµµµµµ¸¸¸···¼¼¼ÀÀÀÅÅÅÐÐÐÕÕÕÍÍÍÌÌÌÔÔÔßßßÒÒÒÎÎÎÀÀÀÆÆÆÅÅÅÇÇÇÐÐÐÛÛÛ×××ÑÑÑÉÉÉÂÂÂÒÒÒÕÕÕâââàààÙÙÙÛÛÛ×××ÆÆÆ¸¸¸ÀÀÀÇÇÇÝÝÝÉÉÉÆÆÆÌÌ̸¸¸ÐÐÐÆÆÆÅÅÅÅÅÅÇÇÇÌÌÌÍÍÍÌÌÌÊÊÊÉÉÉÌÌÌ×××ÑÑÑÐÐÐÔÔÔÌÌÌÎÎÎÑÑÑÎÎÎÃÃû»»ãããÙÙÙÒÒÒÒÒÒØØØÙÙÙÆÆÆÙÙÙØØØÙÙÙêêêñññëëëãããäääæææàààÝÝÝ×××ÌÌÌÑÑÑÕÕÕØØØ××××××ÙÙÙ×××ÑÑÑ´´´³³³ÅÅÅÍÍÍÒÒÒÐÐп¿¿¼¼¼ÅÅÅÇÇÇÌÌÌÍÍÍÍÍÍÌÌÌÌÌÌÍÍÍÑÑÑÐÐÐÒÒÒÕÕÕÒÒÒÊÊÊÉÉÉÎÎÎÑÑÑÕÕÕÑÑÑÑÑÑØØØÕÕÕÎÎÎÑÑÑÛÛÛÕÕÕÐÐÐÎÎÎÐÐÐÒÒÒÔÔÔÔÔÔÛÛÛÊÊʺºº³³³ºººÀÀÀ»»»¸¸¸»»»´´´³³³¼¼¼¾¾¾¸¸¸ººº¸¸¸¼¼¼¾¾¾¼¼¼ºººººº¿¿¿ÃÃû»»ººº···ØØØÑÑÑÌÌÌÐÐÐÒÒÒÊÊÊÌÌÌÎÎÎÒÒÒ×××ÙÙÙÙÙÙØØØÛÛÛÙÙÙ×××ÔÔÔÐÐÐÎÎÎÍÍÍÌÌÌÍÍÍÌÌÌÌÌÌÎÎÎÑÑÑÍÍÍÅÅż¼¼ßßßâââÜÜÜ¿¿¿ÂÂÂÅÅž¾¾èèèõõõööööööÿÿÿøøøòòòùùùñññíííëëëïïïøøøøøøïïïæææããã···¾¾¾¿¿¿¾¾¾ÀÀÀÇÇÇÇÇÇÀÀÀÀÀÀÊÊÊÎÎÎÒÒÒÔÔÔÇÇÇ¿¿¿ÆÆÆÆÆÆÂ¼¼¼¾¾¾ÉÉÉÒÒÒÎÎÎÃÃÃÆÆÆÃÃÃÇÇÇÌÌÌÌÌÌÑÑÑÒÒÒÊÊÊ´´´¦¦¦¥¥¥···Â¾¾¾···¸¸¸¬¬¬ÃÃÃÊÊÊÀÀÀ¾¾¾»»»¸¸¸¸¸¸ººº···¼¼¼ÂÂÂÇÇÇÒÒÒ×××ÌÌÌÕÕÕßßßçççÐÐÐÆÆÆ¼¼¼ÉÉÉÉÉÉ×××ÝÝÝçççààà×××ÉÉɺººÆÆÆÒÒÒäääàààÐÐÐÕÕÕÝÝÝÎÎθ¸¸¾¾¾ºººÜÜÜÍÍ;¾¾ÉÉɾ¾¾ÔÔÔÆÆÆÃÃÃÃÃÃÆÆÆÌÌÌÍÍÍÊÊÊÆÆÆÊÊÊÇÇÇÐÐÐÉÉÉÐÐÐÝÝÝ×××ØØØßßßçççÊÊÊ···ãããÎÎÎ×××âââÐÐÐÜÜÜÊÊÊÝÝÝÛÛÛãããñññëëëñññÜÜÜØØØÙÙÙ××××××ÒÒÒÌÌÌÂÂÂÎÎÎØØØ×××ÑÑÑÑÑÑÐÐÐÎÎδ´´´´´ÊÊÊÔÔÔÔÔÔÎÎξ¾¾ÀÀÀÌÌÌÌÌÌÌÌÌÊÊÊÇÇÇÇÇÇÉÉÉÌÌÌÐÐÐÊÊÊÑÑÑÕÕÕÌÌÌÉÉÉÒÒÒØØØÕÕÕÑÑÑÌÌÌÉÉÉÊÊÊÍÍÍÐÐÐÑÑÑÕÕÕÕÕÕÔÔÔÔÔÔÔÔÔÕÕÕØØØØØØÌÌÌ»»»···ººº¸¸¸»»»¼¼¼µµµ´´´´´´µµµ¸¸¸»»»¼¼¼¸¸¸µµµ»»»¼¼¼¾¾¾¿¿¿¿¿¿¿¿¿ÃÃÃÇÇǼ¼¼ºººÍÍÍãããÔÔÔÔÔÔÊÊÊÒÒÒÕÕÕÎÎÎÑÑÑØØØÙÙÙßßßãããÜÜÜÕÕÕÔÔÔÑÑÑÍÍÍÍÍÍÍÍÍÊÊÊÇÇÇÌÌÌÊÊÊÉÉÉÌÌÌÑÑÑÒÒÒÊÊʾ¾¾âââäääâââæææçççíííóóóãããóóóõõõîîîèèèñññóóóïïïïïïêêêïïïöööüüüÿÿÿùùùñññêêêäää¾¾¾ÅÅÅÃÃÃÃÃÃÐÐÐÆÆÆÅÅÅÆÆÆÌÌÌÌÌÌÊÊÊÐÐз··¼¼¼ÂÂÂÅÅÅÆÆÆ¿¿¿ÃÃÃÕÕÕÛÛÛÉÉɺºº»»»ÀÀÀÅÅÅÇÇÇÆÆÆÆÆÆÊÊÊÎÎγ³³¯¯¯­­­´´´¾¾¾ÀÀÀººº±±±­­­»»»ÇÇÇÉÉÉÅÅÅÂÂÂÂÂÂÀÀÀ¿¿¿¾¾¾ÂÂÂÉÉÉÔÔÔÜÜÜÒÒÒÅÅÅÔÔÔèèèÒÒÒÉÉÉÇÇÇÂÂÂØØØÝÝÝòòòêêêçççèèèàààÒÒÒÌÌÌÐÐÐÝÝÝÝÝÝÐÐÐÒÒÒÊÊÊÌÌÌØØØµµµ¾¾¾¼¼¼ÍÍÍÑÑÑ¿¿¿ÍÍÍÆÆÆÔÔÔÍÍÍÊÊÊÇÇÇÇÇÇÊÊÊÊÊÊÉÉÉÆÆÆÉÉÉÎÎÎÎÎÎÐÐÐÌÌÌÒÒÒäääÝÝÝÒÒÒßßßÀÀÀ¼¼¼æææçççÐÐÐÕÕÕÎÎÎæææÇÇÇÛÛÛØØØíííñññãããÛÛÛØØØÕÕÕÔÔÔÒÒÒÑÑÑÍÍÍÊÊÊÉÉÉÃÃÃÆÆÆÆÆÆÅÅÅÔÔÔÐÐа°°°°°¿¿¿ÀÀÀÌÌÌÊÊʸ¸¸»»»ÀÀÀÇÇÇÍÍÍÎÎÎÅÅÅÉÉÉÌÌÌÅÅÅÐÐÐÎÎÎÌÌÌÍÍÍÊÊÊÀÀÀÅÅÅÒÒÒØØØÐÐÐÍÍÍÊÊÊÊÊÊÌÌÌÎÎÎÐÐÐÐÐÐÒÒÒÔÔÔÔÔÔÔÔÔÕÕÕÕÕÕÕÕÕÕÕÕÌÌ̺ºº´´´······¸¸¸»»»µµµ´´´´´´µµµ¸¸¸»»»»»»¸¸¸µµµ···ººº¼¼¼¼¼¼¾¾¾ÀÀÀ¼¼¼ÀÀÀÑÑÑàààÕÕÕÕÕÕÉÉÉÒÒÒÕÕÕÒÒÒÙÙÙßßßÛÛÛÛÛÛÜÜÜÕÕÕ×××ÔÔÔÌÌÌ¿¿¿¸¸¸¼¼¼ÆÆÆÍÍÍÉÉÉÊÊÊÇÇÇÉÉÉÉÉÉÇÇÇÃÃÃÅÅÅííííííæææçççêêêíííèèèÌÌÌàààíííîîîçççèèèêêêêêêíííëëëíííîîîòòòööööööóóóïïïààà»»»ÃÃÃÇÇÇÇÇÇÑÑÑÇÇÇÇÇÇÉÉÉÍÍÍÌÌÌÉÉÉÍÍ͵µµ»»»ÂÂÂÀÀÀÃÃÃÅÅÅÍÍÍÙÙÙÔÔÔÅÅž¾¾¼¼¼ÃÃÃÇÇÇÉÉÉÉÉÉÉÉÉÊÊÊÊÊÊÉÉÉÃÃÿ¿¿ÂÂÂÆÆÆÅÅźºº°°°­­­»»»ÇÇÇÉÉÉÅÅÅÅÅÅÅÅÅÅÅÅ¿¿¿ÆÆÆÐÐÐÕÕÕÛÛÛÜÜÜÔÔÔÊÊÊÛÛÛâââÊÊÊÃÃÿ¿¿¿¿¿ÝÝÝèèèÑÑÑÒÒÒßßßïïïòòòçççààààààÝÝÝ×××ÇÇÇÎÎÎÍÍÍÑÑÑßßßÂÂÂÅÅÅÂÂÂÌÌÌÎÎÎÆÆÆÐÐÐÅÅÅÜÜÜÌÌÌÊÊÊÇÇÇÉÉÉÌÌÌÍÍÍÌÌÌÌÌÌÊÊÊÍÍÍÊÊÊÐÐÐÐÐÐÕÕÕâââØØØÇÇÇÊÊÊÉÉÉÑÑÑàààãããÜÜÜÙÙÙÍÍÍÛÛÛÉÉÉÜÜÜÔÔÔëëëîîîÝÝÝÛÛÛØØØÕÕÕÒÒÒÒÒÒÐÐÐÍÍÍÊÊÊÇÇÇÃÃÃÆÆÆÆÆÆÆÆÆÕÕÕÒÒÒ···»»»ÀÀÀ···ººº»»»±±±»»»ÃÃÃÃÃÃÂÂÂÇÇÇÃÃÃÅÅÅÇÇÇÂÂÂÌÌÌÎÎÎÉÉÉÇÇÇÅÅÅÅÅÅÍÍÍÕÕÕÕÕÕÍÍÍÌÌÌÊÊÊÊÊÊÍÍÍÎÎÎÎÎÎÎÎÎÐÐÐÑÑÑÒÒÒÔÔÔÔÔÔÒÒÒÑÑÑÐÐÐÌÌÌ»»»±±±³³³´´´···¸¸¸µµµµµµµµµ···¸¸¸»»»»»»ººº¸¸¸···¼¼¼ÀÀÀÂÂÂÆÆÆÌÌÌÌÌÌÇÇÇ¿¿¿ÌÌÌÛÛÛßßß××××××ÌÌÌÕÕÕ×××ØØØÝÝÝàààÛÛÛØØØØØØÔÔÔÒÒÒÉÉɾ¾¾¸¸¸´´´»»»ÇÇÇÀÀÀÃÃþ¾¾ÀÀÀ¿¿¿¿¿¿ÅÅÅÜÜÜíííîîîæææèèèîîîñññäää¼¼¼ÇÇÇãããïïïèèèçççèèèêêêïïïòòòíííèèèêêêïïïóóóõõõóóóããã¿¿¿ÂÂÂÇÇÇÉÉÉÎÎÎÉÉÉÍÍÍÉÉÉÍÍÍÍÍÍÍÍÍÌÌÌ´´´¸¸¸¾¾¾¼¼¼ÅÅÅÍÍÍØØØÛÛÛÌÌÌ¿¿¿ÂÂÂÆÆÆÍÍÍÐÐÐÍÍÍÊÊÊÌÌÌÇÇÇÂÂÂÆÆÆÂ¿¿¿ÂÂÂÆÆÆÃÃúºº±±±¬¬¬»»»ÇÇÇÊÊÊÇÇÇÉÉÉÌÌÌÌÌ̾¾¾ÊÊÊÑÑÑÔÔÔÒÒÒÐÐÐÎÎÎÍÍÍÜÜÜ×××ÆÆÆÉÉÉÀÀÀ¾¾¾ÜÜÜçççÔÔÔÕÕÕßßßëëëîîîæææàààâââããã×××ÆÆÆÍÍÍÎÎÎÐÐÐÝÝÝÊÊʾ¾¾ÇÇÇÑÑÑÊÊÊÌÌÌ×××ÊÊÊßßßÐÐÐÍÍÍÌÌÌÊÊÊÌÌÌÍÍÍÍÍÍÍÍÍÊÊÊÊÊÊÇÇÇÎÎÎÒÒÒ×××ÝÝÝÑÑÑÊÊÊÌÌÌÎÎÎÔÔÔÜÜÜÜÜÜ×××ÕÕÕÔÔÔÕÕÕÔÔÔãããÔÔÔòòòóóóàààÛÛÛØØØÕÕÕÒÒÒÑÑÑÎÎÎÌÌÌÉÉÉÆÆÆÂÂÂÅÅÅÆÆÆÇÇÇ×××ØØØÂÂÂÌÌÌÉÉÉ···³³³······ÀÀÀÇÇǺººÃÃÃÇÇÇÆÆÆÇÇÇÆÆÆÎÎÎÌÌÌÅÅÅÆÆÆÐÐÐÙÙÙÜÜÜ×××ÑÑÑÐÐÐÎÎÎÌÌÌÌÌÌÍÍÍÎÎÎÐÐÐÎÎÎÐÐÐÐÐÐÑÑÑÑÑÑÐÐÐÎÎÎÎÎÎÍÍÍÐÐÐÀÀÀµµµ´´´´´´´´´´´´´´´µµµµµµ···ººº»»»»»»»»»»»»ÂÂÂÇÇÇÊÊÊÉÉÉÊÊÊÎÎÎÉÉÉ¿¿¿ÃÃÃ×××âââÛÛÛØØØÙÙÙÐÐÐÛÛÛÙÙÙÙÙÙÛÛÛÛÛÛÙÙÙØØØ×××ÕÕÕÆÆÆ»»»¿¿¿ÑÑÑÕÕÕÃÃø¸¸»»»ÀÀÀµµµ»»»¸¸¸¸¸¸ÂÂÂæææèèèíííèèèêêêîîîòòòäää¾¾¾¿¿¿ÝÝÝïïïîîîîîîñññòòòöööùùùñññèèèçççíííòòòóóóòòòèèèÆÆÆÂÂÂÆÆÆÆÆÆÉÉÉÆÆÆÎÎÎÇÇÇÍÍÍÍÍÍÒÒÒÊÊÊ´´´µµµ¸¸¸¾¾¾ÌÌÌÕÕÕØØØ×××ÉÉɼ¼¼¾¾¾ÂÂÂÇÇÇÉÉÉÃÃÃÃÃÃÆÆÆÃÃü¼¼¸¸¸······»»»¿¿¿¿¿¿¸¸¸³³³­­­»»»ÉÉÉÍÍÍÎÎÎÐÐÐÑÑÑÑÑÑÎÎÎ×××ÐÐÐÌÌÌÉÉÉÅÅÅÉÉÉÍÍÍâââÎÎÎÆÆÆÍÍÍ¿¿¿»»»ØØØààà×××ÙÙÙäääïïïòòòêêêãããàààÔÔÔÊÊÊÂÂÂÎÎÎÑÑÑÔÔÔäääààà´´´ÊÊÊÝÝÝÊÊÊÉÉÉÜÜÜÒÒÒ×××ÕÕÕÒÒÒÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÊÊÊÆÆÆÍÍÍÐÐÐÐÐÐ×××ÐÐÐÂÂÂÎÎÎÀÀÀ¸¸¸ÙÙÙãããÒÒÒßßßØØØÎÎÎÛÛÛãããÐÐÐóóóõõõàààÛÛÛØØØÔÔÔÒÒÒÐÐÐÎÎÎÊÊÊÇÇÇÆÆÆÂÂÂÅÅÅÇÇÇÉÉÉÕÕÕÙÙÙÍÍÍÑÑÑÎÎξ¾¾µµµ»»»¿¿¿ÂÂÂÅÅÅÀÀÀ±±±¿¿¿ÉÉÉÅÅÅÆÆÆÆÆÆÍÍÍÃÃÃÂÂÂÌÌÌÜÜÜãããÛÛÛÔÔÔ×××ØØØÔÔÔÎÎÎÌÌÌÍÍÍÎÎÎÐÐÐÐÐÐÑÑÑÐÐÐÎÎÎÍÍÍÌÌÌÌÌÌÌÌÌÌÌÌÒÒÒÇÇǼ¼¼¸¸¸···³³³±±±´´´´´´µµµ···ººº»»»¼¼¼¾¾¾¿¿¿¾¾¾ÃÃÃÇÇÇÉÉÉÌÌÌÎÎÎÉÉÉÀÀÀÅÅÅ×××âââÕÕÕÕÕÕ×××ÑÑÑÛÛÛÜÜÜÛÛÛØØØÙÙÙÜÜÜÙÙÙÑÑÑÍÍ;¾¾ÀÀÀÎÎÎâââæææØØØÇÇÇ¿¿¿³³³´´´­­­¾¾¾¸¸¸»»»ÂÂÂäääêêêñññïïïîîîêêêëëëæææÇÇÇÊÊÊâââîîîîîîóóóøøøóóóòòòöööïïïêêêëëëïïïóóóñññíííßßßÅÅÅÂÂÂÇÇÇÉÉÉÇÇÇÅÅÅÌÌÌÍÍÍÎÎÎÌÌÌÐÐа°°µµµ»»»ÂÂÂÔÔÔØØØÐÐÐÎÎÎÉÉɾ¾¾···µµµ¸¸¸¸¸¸µµµ···¼¼¼¾¾¾ººº¼¼¼»»»»»»¼¼¼¾¾¾»»»···³³³°°°¼¼¼ÉÉÉÎÎÎÒÒÒ×××ÕÕÕÒÒÒÔÔÔÙÙÙÊÊÊÍÍÍ×××ÕÕÕÝÝÝâââæææÌÌÌÂÂÂÆÆÆ¸¸¸¼¼¼ÛÛÛãããçççææææææêêêêêêèèèèèèëëëÍÍÍÉÉÉÉÉÉÔÔÔÒÒÒÑÑÑÝÝÝããã¾¾¾ÊÊÊãããÍÍÍÀÀÀÑÑÑÐÐÐÐÐÐÔÔÔÒÒÒÐÐÐÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÅÅÅÌÌÌÆÆÆÊÊÊÊÊÊÆÆÆÐÐÐÑÑÑ¿¿¿ÌÌ̾¾¾¬¬¬ÌÌÌâââÒÒÒÙÙÙÑÑÑÇÇÇØØØÙÙÙÊÊÊëëëíííÝÝÝÛÛÛØØØÕÕÕÒÒÒÐÐÐÍÍÍÊÊÊÇÇÇÆÆÆÃÃÃÅÅÅÇÇÇÊÊÊÒÒÒØØØÕÕÕÐÐÐÍÍÍÀÀÀ´´´ºººÀÀÀ¾¾¾¼¼¼¾¾¾­­­»»»ÅÅÅÂÂÂÂÂÂÂÂÂÇÇÇ»»»ÇÇÇÔÔÔÛÛÛ×××ÌÌÌÎÎÎÝÝÝÛÛÛ×××ÐÐÐÍÍÍÍÍÍÎÎÎÑÑÑÑÑÑÑÑÑÐÐÐÍÍÍÊÊÊÉÉÉÉÉÉÉÉÉÉÉÉÐÐÐÌÌÌÅÅž¾¾ººº±±±¯¯¯µµµ±±±´´´···ººº»»»¾¾¾ÀÀÀÃÃÃÉÉÉÊÊÊÐÐÐÔÔÔÕÕÕÒÒÒÍÍÍÉÉÉÃÃÃÎÎÎßßßÔÔÔÕÕÕÔÔÔÒÒÒØØØÛÛÛÝÝÝÙÙÙÙÙÙÜÜÜÕÕÕÇÇÇÂÂÂÂÂÂØØØæææãããßßßâââÝÝÝÑÑѳ³³······ÌÌ̺ºº»»»¾¾¾ØØØæææîîîïïïñññêêêèèèîîîßßßÜÜÜæææçççêêêóóóóóóëëëèèèíííêêêêêêîîîñññïïïèèèãããÉÉÉ¿¿¿ÀÀÀÉÉÉÍÍÍÊÊÊÆÆÆÇÇÇÑÑÑÑÑÑÉÉÉÍÍ͸¸¸­­­···¿¿¿ÂÂÂ×××ØØØÉÉÉÆÆÆÇÇÇ¿¿¿···ÂÂÂÀÀÀ¿¿¿»»»ººº¸¸¸¸¸¸ººº¼¼¼»»»ººººººººº¸¸¸µµµ´´´µµµ¾¾¾ÅÅÅÊÊÊÑÑÑØØØ×××ÑÑÑÍÍÍÕÕÕÅÅÅÒÒÒæææãããæææää䨨ØÇÇÇÅÅÅÆÆÆ¾¾¾ÇÇÇÜÜÜÝÝÝÝÝÝàààæææêêêçççÝÝÝÒÒÒÍÍÍÑÑÑÑÑÑÔÔÔ×××ÑÑÑÊÊÊÎÎÎÔÔÔ×××ÇÇÇÛÛÛÍÍÍÂÂÂÃÃÃÆÆÆÎÎÎÉÉÉÊÊÊÊÊÊÊÊÊÇÇÇÆÆÆÆÆÆÆÆÆÂÂÂÊÊÊÅÅÅÇÇÇÆÆÆ¿¿¿ÇÇÇÎÎÎÉÉÉÂÂÂÇÇǺºº¿¿¿ÙÙÙÔÔÔÌÌÌÍÍÍÍÍÍÙÙÙÕÕÕÒÒÒëëëèèèàààÜÜÜÙÙÙÕÕÕÒÒÒÑÑÑÎÎÎÊÊÊÇÇÇÇÇÇÅÅÅÆÆÆÉÉÉÊÊÊÎÎÎÔÔÔ×××ÒÒÒÒÒÒÇÇÇ´´´¸¸¸ÅÅÅ¿¿¿ÀÀÀÃÃ÷··¿¿¿ÃÃÃÅÅÅÆÆÆÂÂÂÇÇǼ¼¼ÑÑÑØØØÑÑÑÌÌÌÊÊÊÍÍÍ×××ØØØÔÔÔÐÐÐÍÍÍÎÎÎÐÐÐÐÐÐÐÐÐÐÐÐÎÎÎÍÍÍÌÌÌÉÉÉÇÇÇÆÆÆÆÆÆÇÇÇÌÌÌÇÇǼ¼¼±±±­­­···°°°³³³···ººº»»»¿¿¿ÃÃÃÇÇÇäääââââââäääÝÝÝÎÎÎÆÆÆÇÇÇÆÆÆÉÉÉâââÜÜÜÝÝÝÙÙÙÛÛÛÙÙÙÙÙÙßßßÛÛÛÕÕÕÒÒÒÌÌÌÅÅÅÇÇÇÒÒÒçççïïïäääÜÜÜâââãããÝÝÝÒÒÒÕÕÕÕÕÕßßß´´´µµµ¼¼¼ÔÔÔæææëëëîîîóóóíííëëëõõõïïïêêêèèèâââæææñññîîîççççççæææçççëëëîîîíííää䨨ØÎÎο¿¿¾¾¾¾¾¾ÅÅÅÉÉÉÉÉÉÆÆÆÅÅÅÌÌÌÍÍÍÉÉÉÔÔÔººº°°°µµµ»»»¾¾¾ÑÑÑÕÕÕÉÉÉÂÂÂÀÀÀ¾¾¾¾¾¾ÑÑÑÍÍÍÊÊÊÉÉɸ¸¸···¼¼¼·········µµµµµµµµµ¸¸¸ººº¼¼¼¼¼¼¼¼¼ÀÀÀÊÊÊÔÔÔÔÔÔÎÎÎÕÕÕÝÝÝÇÇÇÔÔÔãããÔÔÔÐÐÐÊÊÊÉÉÉÇÇÇÌÌÌÇÇÇÅÅÅÒÒÒÛÛÛÑÑÑÑÑÑÔÔÔ×××ØØØ×××ÔÔÔÐÐÐÍÍÍÉÉÉÊÊÊÎÎÎÒÒÒÒÒÒÒÒÒÑÑÑÒÒÒàààÃÃÃÍÍÍÊÊÊÑÑÑÉÉÉ¿¿¿ÊÊÊÂÂÂÅÅÅÇÇÇÇÇÇÅÅÅÂÂÂÂÂÂÂÂÂÀÀÀÇÇÇ¿¿¿ÃÃÃÇÇÇ¿¿¿ÂÂÂÆÆÆÎÎκººÂ¾¾¾ÇÇÇàààØØØÔÔÔÉÉÉØØØÜÜÜ×××âââïïïçççãããÝÝÝÛÛÛ×××ÔÔÔÑÑÑÎÎÎÊÊÊÇÇÇÉÉÉÇÇÇÇÇÇÊÊÊÊÊÊÉÉÉÍÍÍÕÕÕÒÒÒÕÕÕÍÍÍ´´´µµµÅÅÅÂÂÂÅÅÅÃÃÿ¿¿ÀÀÀ¼¼¼ÂÂÂÃÃû»»ÂÂÂÅÅÅÛÛÛÙÙÙÊÊÊÌÌÌÔÔÔÐÐÐÊÊÊÒÒÒÑÑÑÎÎÎÎÎÎÐÐÐÐÐÐÐÐÐÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÊÊÊÇÇÇÅÅÅÃÃÃÀÀÀÉÉÉÉÉÉÅÅž¾¾°°°¬¬¬¸¸¸¯¯¯±±±µµµººº¼¼¼ÀÀÀÆÆÆÊÊÊßßßÛÛÛÝÝÝæææàààÑÑÑÌÌÌÒÒÒÌÌÌÊÊÊèèèèèèèèèâââãããÝÝÝØØØßßßÙÙÙÍÍÍÇÇÇÃÃÃÇÇÇ×××ãããçççëëëíííçççàààÜÜÜÛÛÛßßßààààààççç³³³¾¾¾ÕÕÕóóóñññññññññøøøïïïèèèòòòîîîïïïçççßßßäääïïïíííèèèîîîæææèèèííííííçççØØØÇÇǼ¼¼ÂÂÂÃÃü¼¼¼¼¼¿¿¿ÃÃÃÆÆÆÃÃÃÂÂÂÉÉÉÍÍÍÝÝÝ´´´±±±³³³¸¸¸ÌÌÌÒÒÒÌÌ̺ºº»»»ÆÆÆÉÉÉÃÃÃÅÅÅÊÊÊÅÅÅ······Â¾¾¾¼¼¼»»»¸¸¸µµµ···ººº»»»ÀÀÀ¼¼¼······ÃÃÃÐÐÐÒÒÒÍÍÍÒÒÒÜÜÜÆÆÆÒÒÒâââÐÐÐÍÍÍÉÉÉÌÌÌÐÐÐÐÐÐÀÀÀÀÀÀÕÕÕÙÙÙÎÎÎÑÑÑÔÔÔ×××ØØØ×××ÕÕÕÒÒÒÐÐÐÍÍÍÌÌÌÌÌÌÍÍÍÔÔÔÕÕÕÎÎÎÊÊÊ××׿¿¿ÆÆÆÆÆÆàààØØØÂÂÂÅÅÅÂÂÂÅÅÅÇÇÇÆÆÆÂ¾¾¾»»»»»»ÀÀÀÅÅźººÂÂÂÌÌ̾¾¾¿¿¿ãããÉÉɺºº···ÙÙÙäääÉÉÉØØØ¿¿¿ÛÛÛÙÙÙÔÔÔçççíííßßßàààßßßÜÜÜØØØÔÔÔÒÒÒÎÎÎÊÊÊÇÇÇÉÉÉÉÉÉÉÉÉÌÌÌÊÊÊÅÅÅÉÉÉÒÒÒÉÉÉÎÎÎÌÌ̱±±±±±ÀÀÀ»»»¾¾¾ºººººº···­­­µµµ¸¸¸­­­³³³ \ No newline at end of file diff --git a/Extras/ode/include/drawstuff/drawstuff.h b/Extras/ode/include/drawstuff/drawstuff.h deleted file mode 100644 index 0c8cdab22..000000000 --- a/Extras/ode/include/drawstuff/drawstuff.h +++ /dev/null @@ -1,172 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -Draw Stuff ----------- - -this is a library for rendering simple 3D objects in a virtual environment. - -NOTES ------ - -in the virtual world, the z axis is "up" and z=0 is the floor. - -the user is able to click+drag in the main window to move the camera: - * left button - pan and tilt. - * right button - forward and sideways. - * left + right button (or middle button) - sideways and up. - -*/ - - -#ifndef __DRAWSTUFF_H__ -#define __DRAWSTUFF_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -#include - - -/* texture numbers */ -#define DS_NONE 0 /* uses the current color instead of a texture */ -#define DS_WOOD 1 - - -typedef struct dsFunctions { - int version; /* put DS_VERSION here */ - /* version 1 data */ - void (*start)(); /* called before sim loop starts */ - void (*step) (int pause); /* called before every frame */ - void (*command) (int cmd); /* called if a command key is pressed */ - void (*stop)(); /* called after sim loop exits */ - /* version 2 data */ - char *path_to_textures; /* if nonzero, path to texture files */ -} dsFunctions; - - -/* the main() function should fill in the dsFunctions structure then - * call this. - */ -void dsSimulationLoop (int argc, char **argv, - int window_width, int window_height, - struct dsFunctions *fn); - -/* these functions display an error message then exit. they take arguments - * in the same way as printf(), except you do not have to add a terminating - * '\n'. Debug() tries to dump core or start the debugger. - */ -void dsError (char *msg, ...); -void dsDebug (char *msg, ...); - -/* dsPrint() prints out a message. it takes arguments in the same way as - * printf() (i.e. you must add a '\n' at the end of every line). - */ -void dsPrint (char *msg, ...); - -/* set and get the camera position. xyz is the cameria position (x,y,z). - * hpr contains heading, pitch and roll numbers in degrees. heading=0 - * points along the x axis, pitch=0 is looking towards the horizon, and - * roll 0 is "unrotated". - */ -void dsSetViewpoint (float xyz[3], float hpr[3]); -void dsGetViewpoint (float xyz[3], float hpr[3]); - -/* stop the simulation loop. calling this from within dsSimulationLoop() - * will cause it to exit and return to the caller. it is the same as if the - * user used the exit command. using this outside the loop will have no - * effect. - */ -void dsStop(); - -/* change the way objects are drawn. these changes will apply to all further - * dsDrawXXX() functions. the texture number must be a DS_xxx texture - * constant. the red, green, and blue number are between 0 and 1. - * alpha is between 0 and 1 - if alpha is not specified it's assubed to be 1. - * the current texture is colored according to the current color. - * at the start of each frame, the texture is reset to none and the color is - * reset to white. - */ -void dsSetTexture (int texture_number); -void dsSetColor (float red, float green, float blue); -void dsSetColorAlpha (float red, float green, float blue, float alpha); - -/* draw objects. - * - pos[] is the x,y,z of the center of the object. - * - R[] is a 3x3 rotation matrix for the object, stored by row like this: - * [ R11 R12 R13 0 ] - * [ R21 R22 R23 0 ] - * [ R31 R32 R33 0 ] - * - sides[] is an array of x,y,z side lengths. - * - all cylinders are aligned along the z axis. - */ -void dsDrawBox (const float pos[3], const float R[12], const float sides[3]); -void dsDrawSphere (const float pos[3], const float R[12], float radius); -void dsDrawTriangle (const float pos[3], const float R[12], - const float *v0, const float *v1, const float *v2, int solid); -void dsDrawCylinder (const float pos[3], const float R[12], - float length, float radius); -void dsDrawCone(const float pos[3], const float R[12], - float length, float radius); - -void dsDrawCylinder2 (const float pos[3], const float R[12], - float length, float radius,float radius2); - - - -void dsDrawCappedCylinder (const float pos[3], const float R[12], - float length, float radius); -void dsDrawLine (const float pos1[3], const float pos2[3]); - -/* these drawing functions are identical to the ones above, except they take - * double arrays for `pos' and `R'. - */ -void dsDrawBoxD (const double pos[3], const double R[12], - const double sides[3]); -void dsDrawSphereD (const double pos[3], const double R[12], - const float radius); -void dsDrawTriangleD (const double pos[3], const double R[12], - const double *v0, const double *v1, const double *v2, int solid); -void dsDrawCylinderD (const double pos[3], const double R[12], - float length, float radius); -void dsDrawCappedCylinderD (const double pos[3], const double R[12], - float length, float radius); -void dsDrawLineD (const double pos1[3], const double pos2[3]); - -/* Set the drawn quality of the objects. Higher numbers are higher quality, - * but slower to draw. This must be set before the first objects are drawn to - * be effective. - */ -void dsSetSphereQuality (int n); /* default = 1 */ -void dsSetCappedCylinderQuality (int n); /* default = 3 */ - - -/* closing bracket for extern "C" */ -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/drawstuff/version.h b/Extras/ode/include/drawstuff/version.h deleted file mode 100644 index 71d95f461..000000000 --- a/Extras/ode/include/drawstuff/version.h +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef __VERSION_H -#define __VERSION_H - -/* high byte is major version, low byte is minor version */ -#define DS_VERSION 0x0002 - -#endif diff --git a/Extras/ode/include/ode/README b/Extras/ode/include/ode/README deleted file mode 100644 index 9d7e99a8f..000000000 --- a/Extras/ode/include/ode/README +++ /dev/null @@ -1,18 +0,0 @@ - -this is the public C interface to the ODE library. - -all these files should be includable from C, i.e. they should not use any -C++ features. everything should be protected with - - #ifdef __cplusplus - extern "C" { - #endif - - ... - - #ifdef __cplusplus - } - #endif - -the only exceptions are the odecpp.h and odecpp_collisioh.h files, which define a C++ wrapper for -the C interface. remember to keep this in sync! diff --git a/Extras/ode/include/ode/collision.h b/Extras/ode/include/ode/collision.h deleted file mode 100644 index bc9624d95..000000000 --- a/Extras/ode/include/ode/collision.h +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_COLLISION_H_ -#define _ODE_COLLISION_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* ************************************************************************ */ -/* general functions */ - -void dGeomDestroy (dGeomID); -void dGeomSetData (dGeomID, void *); -void *dGeomGetData (dGeomID); -void dGeomSetBody (dGeomID, dBodyID); -dBodyID dGeomGetBody (dGeomID); -void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z); -void dGeomSetRotation (dGeomID, const dMatrix3 R); -void dGeomSetQuaternion (dGeomID, const dQuaternion); -const dReal * dGeomGetPosition (dGeomID); -const dReal * dGeomGetRotation (dGeomID); -void dGeomGetQuaternion (dGeomID, dQuaternion result); -void dGeomGetAABB (dGeomID, dReal aabb[6]); -int dGeomIsSpace (dGeomID); -dSpaceID dGeomGetSpace (dGeomID); -int dGeomGetClass (dGeomID); -void dGeomSetCategoryBits (dGeomID, unsigned long bits); -void dGeomSetCollideBits (dGeomID, unsigned long bits); -unsigned long dGeomGetCategoryBits (dGeomID); -unsigned long dGeomGetCollideBits (dGeomID); -void dGeomEnable (dGeomID); -void dGeomDisable (dGeomID); -int dGeomIsEnabled (dGeomID); - -/* ************************************************************************ */ -/* collision detection */ - -int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, - int skip); -void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback); -void dSpaceCollide2 (dGeomID o1, dGeomID o2, void *data, - dNearCallback *callback); - -/* ************************************************************************ */ -/* standard classes */ - -/* the maximum number of user classes that are supported */ -enum { - dMaxUserClasses = 4 -}; - -/* class numbers - each geometry object needs a unique number */ -enum { - dSphereClass = 0, - dBoxClass, - dCCylinderClass, - dCylinderClass, - dPlaneClass, - dRayClass, - dGeomTransformClass, - dTriMeshClass, - dConvexClass, - - dFirstSpaceClass, - dSimpleSpaceClass = dFirstSpaceClass, - dHashSpaceClass, - dQuadTreeSpaceClass, - dLastSpaceClass = dQuadTreeSpaceClass, - - dFirstUserClass, - dLastUserClass = dFirstUserClass + dMaxUserClasses - 1, - dGeomNumClasses -}; - - -dGeomID dCreateSphere (dSpaceID space, dReal radius); -void dGeomSphereSetRadius (dGeomID sphere, dReal radius); -dReal dGeomSphereGetRadius (dGeomID sphere); -dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z); - -dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz); -void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz); -void dGeomBoxGetLengths (dGeomID box, dVector3 result); -dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z); - -dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); -void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d); -void dGeomPlaneGetParams (dGeomID plane, dVector4 result); -dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal z); - -dGeomID dCreateCCylinder (dSpaceID space, dReal radius, dReal length); -void dGeomCCylinderSetParams (dGeomID ccylinder, dReal radius, dReal length); -void dGeomCCylinderGetParams (dGeomID ccylinder, dReal *radius, dReal *length); -dReal dGeomCCylinderPointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z); - -dGeomID dCreateRay (dSpaceID space, dReal length); -void dGeomRaySetLength (dGeomID ray, dReal length); -dReal dGeomRayGetLength (dGeomID ray); -void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz, - dReal dx, dReal dy, dReal dz); -void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir); - -/* - * Set/get ray flags that influence ray collision detection. - * These flags are currently only noticed by the trimesh collider, because - * they can make a major differences there. - */ -void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull); -void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull); -void dGeomRaySetClosestHit (dGeomID g, int closestHit); -int dGeomRayGetClosestHit (dGeomID g); - -#include "collision_trimesh.h" - -dGeomID dCreateGeomTransform (dSpaceID space); -void dGeomTransformSetGeom (dGeomID g, dGeomID obj); -dGeomID dGeomTransformGetGeom (dGeomID g); -void dGeomTransformSetCleanup (dGeomID g, int mode); -int dGeomTransformGetCleanup (dGeomID g); -void dGeomTransformSetInfo (dGeomID g, int mode); -int dGeomTransformGetInfo (dGeomID g); - -/* ************************************************************************ */ -/* utility functions */ - -void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, - const dVector3 b1, const dVector3 b2, - dVector3 cp1, dVector3 cp2); - -int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1, - const dVector3 side1, const dVector3 _p2, - const dMatrix3 R2, const dVector3 side2); - -void dInfiniteAABB (dGeomID geom, dReal aabb[6]); -void dCloseODE(void); - -/* ************************************************************************ */ -/* custom classes */ - -typedef void dGetAABBFn (dGeomID, dReal aabb[6]); -typedef int dColliderFn (dGeomID o1, dGeomID o2, - int flags, dContactGeom *contact, int skip); -typedef dColliderFn * dGetColliderFnFn (int num); -typedef void dGeomDtorFn (dGeomID o); -typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]); - -typedef struct dGeomClass { - int bytes; - dGetColliderFnFn *collider; - dGetAABBFn *aabb; - dAABBTestFn *aabb_test; - dGeomDtorFn *dtor; -} dGeomClass; - -int dCreateGeomClass (const dGeomClass *classptr); -void * dGeomGetClassData (dGeomID); -dGeomID dCreateGeom (int classnum); - -/* ************************************************************************ */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/collision_space.h b/Extras/ode/include/ode/collision_space.h deleted file mode 100644 index 0ab3d132c..000000000 --- a/Extras/ode/include/ode/collision_space.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_COLLISION_SPACE_H_ -#define _ODE_COLLISION_SPACE_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct dContactGeom; - -typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); - - -dSpaceID dSimpleSpaceCreate (dSpaceID space); -dSpaceID dHashSpaceCreate (dSpaceID space); -dSpaceID dQuadTreeSpaceCreate (dSpaceID space, dVector3 Center, dVector3 Extents, int Depth); - -void dSpaceDestroy (dSpaceID); - -void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel); -void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel); - -void dSpaceSetCleanup (dSpaceID space, int mode); -int dSpaceGetCleanup (dSpaceID space); - -void dSpaceAdd (dSpaceID, dGeomID); -void dSpaceRemove (dSpaceID, dGeomID); -int dSpaceQuery (dSpaceID, dGeomID); -void dSpaceClean (dSpaceID); -int dSpaceGetNumGeoms (dSpaceID); -dGeomID dSpaceGetGeom (dSpaceID, int i); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/collision_trimesh.h b/Extras/ode/include/ode/collision_trimesh.h deleted file mode 100644 index 396fc84c0..000000000 --- a/Extras/ode/include/ode/collision_trimesh.h +++ /dev/null @@ -1,184 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - * TriMesh code by Erwin de Vries. - * - * Trimesh data. - * This is where the actual vertexdata (pointers), and BV tree is stored. - * Vertices should be single precision! - * This should be more sophisticated, so that the user can easyly implement - * another collision library, but this is a lot of work, and also costs some - * performance because some data has to be copied. - */ - -#ifndef _ODE_COLLISION_TRIMESH_H_ -#define _ODE_COLLISION_TRIMESH_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Data storage for triangle meshes. - */ -struct dxTriMeshData; -typedef struct dxTriMeshData* dTriMeshDataID; - -/* - * These dont make much sense now, but they will later when we add more - * features. - */ -dTriMeshDataID dGeomTriMeshDataCreate(void); -void dGeomTriMeshDataDestroy(dTriMeshDataID g); - -enum { TRIMESH_FACE_NORMALS, TRIMESH_LAST_TRANSFORMATION }; -void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data); -void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); - -/* - * Build TriMesh data with single pricision used in vertex data . - */ -void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride); -/* same again with a normals array (used as trimesh-trimesh optimization) */ -void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride, - const void* Normals); -/* -* Build TriMesh data with double pricision used in vertex data . -*/ -void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride); -/* same again with a normals array (used as trimesh-trimesh optimization) */ -void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride, - const void* Normals); - -/* - * Simple build. Single/double precision based on dSINGLE/dDOUBLE! - */ -void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, - const dReal* Vertices, int VertexCount, - const int* Indices, int IndexCount); -/* same again with a normals array (used as trimesh-trimesh optimization) */ -void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, - const dReal* Vertices, int VertexCount, - const int* Indices, int IndexCount, - const int* Normals); -/* - * Per triangle callback. Allows the user to say if he wants a collision with - * a particular triangle. - */ -typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex); -void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); -dTriCallback* dGeomTriMeshGetCallback(dGeomID g); - -/* - * Per object callback. Allows the user to get the list of triangles in 1 - * shot. Maybe we should remove this one. - */ -typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount); -void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback); -dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); - -/* - * Ray callback. - * Allows the user to say if a ray collides with a triangle on barycentric - * coords. The user can for example sample a texture with alpha transparency - * to determine if a collision should occur. - */ -typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v); -void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback); -dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); - -/* - * Trimesh class - * Construction. Callbacks are optional. - */ -dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); - -void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); -dTriMeshDataID dGeomTriMeshGetData(dGeomID g); - - -// enable/disable/check temporal coherence -void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); -int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); - -/* - * Clears the internal temporal coherence caches. When a geom has its - * collision checked with a trimesh once, data is stored inside the trimesh. - * With large worlds with lots of seperate objects this list could get huge. - * We should be able to do this automagically. - */ -void dGeomTriMeshClearTCCache(dGeomID g); - - -/* - * returns the TriMeshDataID - */ -dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); - -/* - * Gets a triangle. - */ -void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2); - -/* - * Gets the point on the requested triangle and the given barycentric - * coordinates. - */ -void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out); - -/* - -This is how the strided data works: - -struct StridedVertex{ - dVector3 Vertex; - // Userdata -}; -int VertexStride = sizeof(StridedVertex); - -struct StridedTri{ - int Indices[3]; - // Userdata -}; -int TriStride = sizeof(StridedTri); - -*/ - - -int dGeomTriMeshGetTriangleCount (dGeomID g); - - -#ifdef __cplusplus -} -#endif - -#endif /* _ODE_COLLISION_TRIMESH_H_ */ - diff --git a/Extras/ode/include/ode/common.h b/Extras/ode/include/ode/common.h deleted file mode 100644 index 035513cc9..000000000 --- a/Extras/ode/include/ode/common.h +++ /dev/null @@ -1,338 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_COMMON_H_ -#define _ODE_COMMON_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* configuration stuff */ - -/* the efficient alignment. most platforms align data structures to some - * number of bytes, but this is not always the most efficient alignment. - * for example, many x86 compilers align to 4 bytes, but on a pentium it - * is important to align doubles to 8 byte boundaries (for speed), and - * the 4 floats in a SIMD register to 16 byte boundaries. many other - * platforms have similar behavior. setting a larger alignment can waste - * a (very) small amount of memory. NOTE: this number must be a power of - * two. this is set to 16 by default. - */ -#define EFFICIENT_ALIGNMENT 16 - - -/* constants */ - -/* pi and 1/sqrt(2) are defined here if necessary because they don't get - * defined in on some platforms (like MS-Windows) - */ - -#ifndef M_PI -#define M_PI REAL(3.1415926535897932384626433832795029) -#endif -#ifndef M_SQRT1_2 -#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490) -#endif - - -/* debugging: - * IASSERT is an internal assertion, i.e. a consistency check. if it fails - * we want to know where. - * UASSERT is a user assertion, i.e. if it fails a nice error message - * should be printed for the user. - * AASSERT is an arguments assertion, i.e. if it fails "bad argument(s)" - * is printed. - * DEBUGMSG just prints out a message - */ - -#ifndef dNODEBUG -#ifdef __GNUC__ -#define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ - "assertion \"" #a "\" failed in %s() [%s]",__FUNCTION__,__FILE__); -#define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \ - msg " in %s()", __FUNCTION__); -#define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \ - msg " in %s()", __FUNCTION__); -#else -#define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ - "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__); -#define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \ - msg " (%s:%d)", __FILE__,__LINE__); -#define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \ - msg " (%s:%d)", __FILE__,__LINE__); -#endif -#else -#define dIASSERT(a) ; -#define dUASSERT(a,msg) ; -#define dDEBUGMSG(msg) ; -#endif -#define dAASSERT(a) dUASSERT(a,"Bad argument(s)") - -/* floating point data type, vector, matrix and quaternion types */ - -#if defined(dSINGLE) -typedef float dReal; -#elif defined(dDOUBLE) -typedef double dReal; -#else -#error You must #define dSINGLE or dDOUBLE -#endif - - -/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified - * (used to compute matrix leading dimensions) - */ -#define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a)) - -/* these types are mainly just used in headers */ -typedef dReal dVector3[4]; -typedef dReal dVector4[4]; -typedef dReal dMatrix3[4*3]; -typedef dReal dMatrix4[4*4]; -typedef dReal dMatrix6[8*6]; -typedef dReal dQuaternion[4]; - - -/* precision dependent scalar math functions */ - -#if defined(dSINGLE) - -#define REAL(x) (x ## f) /* form a constant */ -#define dRecip(x) ((float)(1.0f/(x))) /* reciprocal */ -#define dSqrt(x) ((float)sqrtf(float(x))) /* square root */ -#define dRecipSqrt(x) ((float)(1.0f/sqrtf(float(x)))) /* reciprocal square root */ -#define dSin(x) ((float)sinf(float(x))) /* sine */ -#define dCos(x) ((float)cosf(float(x))) /* cosine */ -#define dFabs(x) ((float)fabsf(float(x))) /* absolute value */ -#define dAtan2(y,x) ((float)atan2f(float(y),float(x))) /* arc tangent with 2 args */ -#define dFMod(a,b) ((float)fmodf(float(a),float(b))) /* modulo */ -#define dCopySign(a,b) ((float)copysignf(float(a),float(b))) - -#elif defined(dDOUBLE) - -#define REAL(x) (x) -#define dRecip(x) (1.0/(x)) -#define dSqrt(x) sqrt(x) -#define dRecipSqrt(x) (1.0/sqrt(x)) -#define dSin(x) sin(x) -#define dCos(x) cos(x) -#define dFabs(x) fabs(x) -#define dAtan2(y,x) atan2((y),(x)) -#define dFMod(a,b) (fmod((a),(b))) -#define dCopySign(a,b) (copysign((a),(b))) - -#else -#error You must #define dSINGLE or dDOUBLE -#endif - - -/* utility */ - - -/* round something up to be a multiple of the EFFICIENT_ALIGNMENT */ - -#define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1) - - -/* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste - * up to 15 bytes per allocation, depending on what alloca() returns. - */ - -#define dALLOCA16(n) \ - ((char*)dEFFICIENT_SIZE(((size_t)(alloca((n)+(EFFICIENT_ALIGNMENT-1)))))) - - -// Use the error-checking memory allocation system. Becuase this system uses heap -// (malloc) instead of stack (alloca), it is slower. However, it allows you to -// simulate larger scenes, as well as handle out-of-memory errors in a somewhat -// graceful manner - -// #define dUSE_MALLOC_FOR_ALLOCA - -#ifdef dUSE_MALLOC_FOR_ALLOCA -enum { - d_MEMORY_OK = 0, /* no memory errors */ - d_MEMORY_OUT_OF_MEMORY /* malloc failed due to out of memory error */ -}; - -#endif - - - -/* internal object types (all prefixed with `dx') */ - -struct dxWorld; /* dynamics world */ -struct dxSpace; /* collision space */ -struct dxBody; /* rigid body (dynamics object) */ -struct dxGeom; /* geometry (collision object) */ -struct dxJoint; -struct dxJointNode; -struct dxJointGroup; - -typedef struct dxWorld *dWorldID; -typedef struct dxSpace *dSpaceID; -typedef struct dxBody *dBodyID; -typedef struct dxGeom *dGeomID; -typedef struct dxJoint *dJointID; -typedef struct dxJointGroup *dJointGroupID; - - -/* error numbers */ - -enum { - d_ERR_UNKNOWN = 0, /* unknown error */ - d_ERR_IASSERT, /* internal assertion failed */ - d_ERR_UASSERT, /* user assertion failed */ - d_ERR_LCP /* user assertion failed */ -}; - - -/* joint type numbers */ - -enum { - dJointTypeNone = 0, /* or "unknown" */ - dJointTypeBall, - dJointTypeHinge, - dJointTypeSlider, - dJointTypeContact, - dJointTypeUniversal, - dJointTypeHinge2, - dJointTypeFixed, - dJointTypeNull, - dJointTypeAMotor -}; - - -/* an alternative way of setting joint parameters, using joint parameter - * structures and member constants. we don't actually do this yet. - */ - -/* -typedef struct dLimot { - int mode; - dReal lostop, histop; - dReal vel, fmax; - dReal fudge_factor; - dReal bounce, soft; - dReal suspension_erp, suspension_cfm; -} dLimot; - -enum { - dLimotLoStop = 0x0001, - dLimotHiStop = 0x0002, - dLimotVel = 0x0004, - dLimotFMax = 0x0008, - dLimotFudgeFactor = 0x0010, - dLimotBounce = 0x0020, - dLimotSoft = 0x0040 -}; -*/ - - -/* standard joint parameter names. why are these here? - because we don't want - * to include all the joint function definitions in joint.cpp. hmmmm. - * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument, - * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and - * paste between these two. - */ - -#define D_ALL_PARAM_NAMES(start) \ - /* parameters for limits and motors */ \ - dParamLoStop = start, \ - dParamHiStop, \ - dParamVel, \ - dParamFMax, \ - dParamFudgeFactor, \ - dParamBounce, \ - dParamCFM, \ - dParamStopERP, \ - dParamStopCFM, \ - /* parameters for suspension */ \ - dParamSuspensionERP, \ - dParamSuspensionCFM, - -#define D_ALL_PARAM_NAMES_X(start,x) \ - /* parameters for limits and motors */ \ - dParamLoStop ## x = start, \ - dParamHiStop ## x, \ - dParamVel ## x, \ - dParamFMax ## x, \ - dParamFudgeFactor ## x, \ - dParamBounce ## x, \ - dParamCFM ## x, \ - dParamStopERP ## x, \ - dParamStopCFM ## x, \ - /* parameters for suspension */ \ - dParamSuspensionERP ## x, \ - dParamSuspensionCFM ## x, - -enum { - D_ALL_PARAM_NAMES(0) - D_ALL_PARAM_NAMES_X(0x100,2) - D_ALL_PARAM_NAMES_X(0x200,3) - - /* add a multiple of this constant to the basic parameter numbers to get - * the parameters for the second, third etc axes. - */ - dParamGroup=0x100 -}; - - -/* angular motor mode numbers */ - -enum{ - dAMotorUser = 0, - dAMotorEuler = 1 -}; - - -/* joint force feedback information */ - -typedef struct dJointFeedback { - dVector3 f1; /* force applied to body 1 */ - dVector3 t1; /* torque applied to body 1 */ - dVector3 f2; /* force applied to body 2 */ - dVector3 t2; /* torque applied to body 2 */ -} dJointFeedback; - - -/* private functions that must be implemented by the collision library: - * (1) indicate that a geom has moved, (2) get the next geom in a body list. - * these functions are called whenever the position of geoms connected to a - * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or - * when the ODE step function updates the body state. - */ - -void dGeomMoved (dGeomID); -dGeomID dGeomGetBodyNext (dGeomID); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/compatibility.h b/Extras/ode/include/ode/compatibility.h deleted file mode 100644 index b3709866b..000000000 --- a/Extras/ode/include/ode/compatibility.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_COMPATIBILITY_H_ -#define _ODE_COMPATIBILITY_H_ - -/* - * ODE's backward compatibility system ensures that as ODE's API - * evolves, user code will not break. - */ - -/* - * These new rotation function names are more consistent with the - * rest of the API. - */ -#define dQtoR(q,R) dRfromQ((R),(q)) -#define dRtoQ(R,q) dQfromR((q),(R)) -#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q)) - - -#endif diff --git a/Extras/ode/include/ode/config.h b/Extras/ode/include/ode/config.h deleted file mode 100644 index 5f2adceb1..000000000 --- a/Extras/ode/include/ode/config.h +++ /dev/null @@ -1,53 +0,0 @@ -/* per-machine configuration. this file is automatically generated. */ - -#ifndef _ODE_CONFIG_H_ -#define _ODE_CONFIG_H_ - -/* standard system headers */ -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* is this a pentium on a gcc-based platform? */ -/* #define PENTIUM 1 -- not a pentium */ - -/* integer types (we assume int >= 32 bits) */ -typedef char int8; -typedef unsigned char uint8; -typedef short int16; -typedef unsigned short uint16; -typedef int int32; -typedef unsigned int uint32; - -/* an integer type that we can safely cast a pointer to and - * from without loss of bits. - */ -typedef unsigned int intP; - -/* select the base floating point type */ -#define dSINGLE 1 - -/* the floating point infinity */ -#define dInfinity FLT_MAX - - - - -/* available functions */ -#define copysignf _copysign -#define copysign _copysign -#define snprintf _snprintf -#define vsnprintf _vsnprintf - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Extras/ode/include/ode/contact.h b/Extras/ode/include/ode/contact.h deleted file mode 100644 index 926d77f6c..000000000 --- a/Extras/ode/include/ode/contact.h +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_CONTACT_H_ -#define _ODE_CONTACT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -enum { - dContactMu2 = 0x001, - dContactFDir1 = 0x002, - dContactBounce = 0x004, - dContactSoftERP = 0x008, - dContactSoftCFM = 0x010, - dContactMotion1 = 0x020, - dContactMotion2 = 0x040, - dContactSlip1 = 0x080, - dContactSlip2 = 0x100, - - dContactApprox0 = 0x0000, - dContactApprox1_1 = 0x1000, - dContactApprox1_2 = 0x2000, - dContactApprox1 = 0x3000 -}; - - -typedef struct dSurfaceParameters { - /* must always be defined */ - int mode; - dReal mu; - - /* only defined if the corresponding flag is set in mode */ - dReal mu2; - dReal bounce; - dReal bounce_vel; - dReal soft_erp; - dReal soft_cfm; - dReal motion1,motion2; - dReal slip1,slip2; -} dSurfaceParameters; - - -/* contact info set by collision functions */ - -typedef struct dContactGeom { - dVector3 pos; - dVector3 normal; - dReal depth; - dGeomID g1,g2; -} dContactGeom; - - -/* contact info used by contact joint */ - -typedef struct dContact { - dSurfaceParameters surface; - dContactGeom geom; - dVector3 fdir1; -} dContact; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/error.h b/Extras/ode/include/ode/error.h deleted file mode 100644 index 6d93fa091..000000000 --- a/Extras/ode/include/ode/error.h +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* this comes from the `reuse' library. copy any changes back to the source */ - -#ifndef _ODE_ERROR_H_ -#define _ODE_ERROR_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* all user defined error functions have this type. error and debug functions - * should not return. - */ -typedef void dMessageFunction (int errnum, const char *msg, va_list ap); - -/* set a new error, debug or warning handler. if fn is 0, the default handlers - * are used. - */ -void dSetErrorHandler (dMessageFunction *fn); -void dSetDebugHandler (dMessageFunction *fn); -void dSetMessageHandler (dMessageFunction *fn); - -/* return the current error, debug or warning handler. if the return value is - * 0, the default handlers are in place. - */ -dMessageFunction *dGetErrorHandler(void); -dMessageFunction *dGetDebugHandler(void); -dMessageFunction *dGetMessageHandler(void); - -/* generate a fatal error, debug trap or a message. */ -void dError (int num, const char *msg, ...); -void dDebug (int num, const char *msg, ...); -void dMessage (int num, const char *msg, ...); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/export-dif.h b/Extras/ode/include/ode/export-dif.h deleted file mode 100644 index d89317ff9..000000000 --- a/Extras/ode/include/ode/export-dif.h +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_EXPORT_DIF_ -#define _ODE_EXPORT_DIF_ - -#include - - -void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name); - - -#endif diff --git a/Extras/ode/include/ode/mass.h b/Extras/ode/include/ode/mass.h deleted file mode 100644 index f94fa5650..000000000 --- a/Extras/ode/include/ode/mass.h +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_MASS_H_ -#define _ODE_MASS_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct dMass; -typedef struct dMass dMass; - - -void dMassSetZero (dMass *); - -void dMassSetParameters (dMass *, dReal themass, - dReal cgx, dReal cgy, dReal cgz, - dReal I11, dReal I22, dReal I33, - dReal I12, dReal I13, dReal I23); - -void dMassSetSphere (dMass *, dReal density, dReal radius); -void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius); - -void dMassSetCappedCylinder (dMass *, dReal density, int direction, - dReal radius, dReal length); -void dMassSetCappedCylinderTotal (dMass *, dReal total_mass, int direction, - dReal radius, dReal length); - -void dMassSetCylinder (dMass *, dReal density, int direction, - dReal radius, dReal length); -void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction, - dReal radius, dReal length); - -void dMassSetBox (dMass *, dReal density, - dReal lx, dReal ly, dReal lz); -void dMassSetBoxTotal (dMass *, dReal total_mass, - dReal lx, dReal ly, dReal lz); - -void dMassAdjust (dMass *, dReal newmass); - -void dMassTranslate (dMass *, dReal x, dReal y, dReal z); - -void dMassRotate (dMass *, const dMatrix3 R); - -void dMassAdd (dMass *a, const dMass *b); - - - -struct dMass { - dReal mass; - dVector4 c; - dMatrix3 I; - -#ifdef __cplusplus - dMass() - { dMassSetZero (this); } - void setZero() - { dMassSetZero (this); } - void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz, - dReal I11, dReal I22, dReal I33, - dReal I12, dReal I13, dReal I23) - { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); } - void setSphere (dReal density, dReal radius) - { dMassSetSphere (this,density,radius); } - void setCappedCylinder (dReal density, int direction, dReal a, dReal b) - { dMassSetCappedCylinder (this,density,direction,a,b); } - void setBox (dReal density, dReal lx, dReal ly, dReal lz) - { dMassSetBox (this,density,lx,ly,lz); } - void adjust (dReal newmass) - { dMassAdjust (this,newmass); } - void translate (dReal x, dReal y, dReal z) - { dMassTranslate (this,x,y,z); } - void rotate (const dMatrix3 R) - { dMassRotate (this,R); } - void add (const dMass *b) - { dMassAdd (this,b); } -#endif -}; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/matrix.h b/Extras/ode/include/ode/matrix.h deleted file mode 100644 index 75218fd3e..000000000 --- a/Extras/ode/include/ode/matrix.h +++ /dev/null @@ -1,194 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* optimized and unoptimized vector and matrix functions */ - -#ifndef _ODE_MATRIX_H_ -#define _ODE_MATRIX_H_ - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* set a vector/matrix of size n to all zeros, or to a specific value. */ - -void dSetZero (dReal *a, int n); -void dSetValue (dReal *a, int n, dReal value); - - -/* get the dot product of two n*1 vectors. if n <= 0 then - * zero will be returned (in which case a and b need not be valid). - */ - -dReal dDot (const dReal *a, const dReal *b, int n); - - -/* get the dot products of (a0,b), (a1,b), etc and return them in outsum. - * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case - * the input vectors need not be valid). this function is somewhat faster - * than calling dDot() for all of the combinations separately. - */ - -/* NOT INCLUDED in the library for now. -void dMultidot2 (const dReal *a0, const dReal *a1, - const dReal *b, dReal *outsum, int n); -*/ - - -/* matrix multiplication. all matrices are stored in standard row format. - * the digit refers to the argument that is transposed: - * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) - * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) - * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) - * case 1,2 are equivalent to saying that the operation is A=B*C but - * B or C are stored in standard column format. - */ - -void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); -void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); -void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); - - -/* do an in-place cholesky decomposition on the lower triangle of the n*n - * symmetric matrix A (which is stored by rows). the resulting lower triangle - * will be such that L*L'=A. return 1 on success and 0 on failure (on failure - * the matrix is not positive definite). - */ - -int dFactorCholesky (dReal *A, int n); - - -/* solve for x: L*L'*x = b, and put the result back into x. - * L is size n*n, b is size n*1. only the lower triangle of L is considered. - */ - -void dSolveCholesky (const dReal *L, dReal *b, int n); - - -/* compute the inverse of the n*n positive definite matrix A and put it in - * Ainv. this is not especially fast. this returns 1 on success (A was - * positive definite) or 0 on failure (not PD). - */ - -int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n); - - -/* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). - * positive definite means that x'*A*x > 0 for any x. this performs a - * cholesky decomposition of A. if the decomposition fails then the matrix - * is not positive definite. A is stored by rows. A is not altered. - */ - -int dIsPositiveDefinite (const dReal *A, int n); - - -/* factorize a matrix A into L*D*L', where L is lower triangular with ones on - * the diagonal, and D is diagonal. - * A is an n*n matrix stored by rows, with a leading dimension of n rounded - * up to 4. L is written into the strict lower triangle of A (the ones are not - * written) and the reciprocal of the diagonal elements of D are written into - * d. - */ -void dFactorLDLT (dReal *A, dReal *d, int n, int nskip); - - -/* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, - * and x,b are n*1. b is overwritten with x. - * the leading dimension of L is `nskip'. - */ -void dSolveL1 (const dReal *L, dReal *b, int n, int nskip); - - -/* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, - * and x,b are n*1. b is overwritten with x. - * the leading dimension of L is `nskip'. - */ -void dSolveL1T (const dReal *L, dReal *b, int n, int nskip); - - -/* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */ - -void dVectorScale (dReal *a, const dReal *d, int n); - - -/* given `L', a n*n lower triangular matrix with ones on the diagonal, - * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix - * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. - * the leading dimension of L is `nskip'. - */ - -void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip); - - -/* given an L*D*L' factorization of an n*n matrix A, return the updated - * factorization L2*D2*L2' of A plus the following "top left" matrix: - * - * [ b a' ] <-- b is a[0] - * [ a 0 ] <-- a is a[1..n-1] - * - * - L has size n*n, its leading dimension is nskip. L is lower triangular - * with ones on the diagonal. only the lower triangle of L is referenced. - * - d has size n. d contains the reciprocal diagonal elements of D. - * - a has size n. - * the result is written into L, except that the left column of L and d[0] - * are not actually modified. see ldltaddTL.m for further comments. - */ -void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip); - - -/* given an L*D*L' factorization of a permuted matrix A, produce a new - * factorization for row and column `r' removed. - * - A has size n1*n1, its leading dimension in nskip. A is symmetric and - * positive definite. only the lower triangle of A is referenced. - * A itself may actually be an array of row pointers. - * - L has size n2*n2, its leading dimension in nskip. L is lower triangular - * with ones on the diagonal. only the lower triangle of L is referenced. - * - d has size n2. d contains the reciprocal diagonal elements of D. - * - p is a permutation vector. it contains n2 indexes into A. each index - * must be in the range 0..n1-1. - * - r is the row/column of L to remove. - * the new L will be written within the old L, i.e. will have the same leading - * dimension. the last row and column of L, and the last element of d, are - * undefined on exit. - * - * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. - */ -void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, - int n1, int n2, int r, int nskip); - - -/* given an n*n matrix A (with leading dimension nskip), remove the r'th row - * and column by moving elements. the new matrix will have the same leading - * dimension. the last row and column of A are untouched on exit. - */ -void dRemoveRowCol (dReal *A, int n, int nskip, int r); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/memory.h b/Extras/ode/include/ode/memory.h deleted file mode 100644 index 4c26549a7..000000000 --- a/Extras/ode/include/ode/memory.h +++ /dev/null @@ -1,59 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* this comes from the `reuse' library. copy any changes back to the source */ - -#ifndef _ODE_MEMORY_H_ -#define _ODE_MEMORY_H_ - -#include "ode/config.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* function types to allocate and free memory */ -typedef void * dAllocFunction (size_t size); -typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize); -typedef void dFreeFunction (void *ptr, size_t size); - -/* set new memory management functions. if fn is 0, the default handlers are - * used. */ -void dSetAllocHandler (dAllocFunction *fn); -void dSetReallocHandler (dReallocFunction *fn); -void dSetFreeHandler (dFreeFunction *fn); - -/* get current memory management functions */ -dAllocFunction *dGetAllocHandler (void); -dReallocFunction *dGetReallocHandler (void); -dFreeFunction *dGetFreeHandler (void); - -/* allocate and free memory. */ -void * dAlloc (size_t size); -void * dRealloc (void *ptr, size_t oldsize, size_t newsize); -void dFree (void *ptr, size_t size); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/misc.h b/Extras/ode/include/ode/misc.h deleted file mode 100644 index f566be802..000000000 --- a/Extras/ode/include/ode/misc.h +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* miscellaneous math functions. these are mostly useful for testing */ - -#ifndef _ODE_MISC_H_ -#define _ODE_MISC_H_ - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* return 1 if the random number generator is working. */ -int dTestRand(void); - -/* return next 32 bit random number. this uses a not-very-random linear - * congruential method. - */ -unsigned long dRand(void); - -/* get and set the current random number seed. */ -unsigned long dRandGetSeed(void); -void dRandSetSeed (unsigned long s); - -/* return a random integer between 0..n-1. the distribution will get worse - * as n approaches 2^32. - */ -int dRandInt (int n); - -/* return a random real number between 0..1 */ -dReal dRandReal(void); - -/* print out a matrix */ -#ifdef __cplusplus -void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ", - FILE *f=stdout); -#else -void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f); -#endif - -/* make a random vector with entries between +/- range. A has n elements. */ -void dMakeRandomVector (dReal *A, int n, dReal range); - -/* make a random matrix with entries between +/- range. A has size n*m. */ -void dMakeRandomMatrix (dReal *A, int n, int m, dReal range); - -/* clear the upper triangle of a square matrix */ -void dClearUpperTriangle (dReal *A, int n); - -/* return the maximum element difference between the two n*m matrices */ -dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m); - -/* return the maximum element difference between the lower triangle of two - * n*n matrices */ -dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/objects.h b/Extras/ode/include/ode/objects.h deleted file mode 100644 index a5b514a93..000000000 --- a/Extras/ode/include/ode/objects.h +++ /dev/null @@ -1,269 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_OBJECTS_H_ -#define _ODE_OBJECTS_H_ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* world */ - -dWorldID dWorldCreate(void); -void dWorldDestroy (dWorldID); - -void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); -void dWorldGetGravity (dWorldID, dVector3 gravity); -void dWorldSetERP (dWorldID, dReal erp); -dReal dWorldGetERP (dWorldID); -void dWorldSetCFM (dWorldID, dReal cfm); -dReal dWorldGetCFM (dWorldID); -void dWorldStep (dWorldID, dReal stepsize); -void dWorldImpulseToForce (dWorldID, dReal stepsize, - dReal ix, dReal iy, dReal iz, dVector3 force); - -/* World QuickStep functions */ - -void dWorldQuickStep (dWorldID w, dReal stepsize); -void dWorldSetQuickStepNumIterations (dWorldID, int num); -int dWorldGetQuickStepNumIterations (dWorldID); -void dWorldSetQuickStepW (dWorldID, dReal param); -dReal dWorldGetQuickStepW (dWorldID); - -/* World contact parameter functions */ - -void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel); -dReal dWorldGetContactMaxCorrectingVel (dWorldID); -void dWorldSetContactSurfaceLayer (dWorldID, dReal depth); -dReal dWorldGetContactSurfaceLayer (dWorldID); - -/* StepFast1 functions */ - -void dWorldStepFast1(dWorldID, dReal stepsize, int maxiterations); -void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth); -int dWorldGetAutoEnableDepthSF1(dWorldID); - -/* Auto-disable functions */ - -dReal dWorldGetAutoDisableLinearThreshold (dWorldID); -void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold); -dReal dWorldGetAutoDisableAngularThreshold (dWorldID); -void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); -int dWorldGetAutoDisableSteps (dWorldID); -void dWorldSetAutoDisableSteps (dWorldID, int steps); -dReal dWorldGetAutoDisableTime (dWorldID); -void dWorldSetAutoDisableTime (dWorldID, dReal time); -int dWorldGetAutoDisableFlag (dWorldID); -void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable); - -dReal dBodyGetAutoDisableLinearThreshold (dBodyID); -void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_threshold); -dReal dBodyGetAutoDisableAngularThreshold (dBodyID); -void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_threshold); -int dBodyGetAutoDisableSteps (dBodyID); -void dBodySetAutoDisableSteps (dBodyID, int steps); -dReal dBodyGetAutoDisableTime (dBodyID); -void dBodySetAutoDisableTime (dBodyID, dReal time); -int dBodyGetAutoDisableFlag (dBodyID); -void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable); -void dBodySetAutoDisableDefaults (dBodyID); - -/* bodies */ - -dBodyID dBodyCreate (dWorldID); -void dBodyDestroy (dBodyID); - -void dBodySetData (dBodyID, void *data); -void *dBodyGetData (dBodyID); - -void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); -void dBodySetRotation (dBodyID, const dMatrix3 R); -void dBodySetQuaternion (dBodyID, const dQuaternion q); -void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); -void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); -const dReal * dBodyGetPosition (dBodyID); -const dReal * dBodyGetRotation (dBodyID); /* ptr to 4x3 rot matrix */ -const dReal * dBodyGetQuaternion (dBodyID); -const dReal * dBodyGetLinearVel (dBodyID); -const dReal * dBodyGetAngularVel (dBodyID); - -void dBodySetMass (dBodyID, const dMass *mass); -void dBodyGetMass (dBodyID, dMass *mass); - -void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); -void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); -void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz); - -const dReal * dBodyGetForce (dBodyID); -const dReal * dBodyGetTorque (dBodyID); -void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); -void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); - -void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); -void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz, - dVector3 result); - -void dBodySetFiniteRotationMode (dBodyID, int mode); -void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); - -int dBodyGetFiniteRotationMode (dBodyID); -void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); - -int dBodyGetNumJoints (dBodyID b); -dJointID dBodyGetJoint (dBodyID, int index); - -void dBodyEnable (dBodyID); -void dBodyDisable (dBodyID); -int dBodyIsEnabled (dBodyID); - -void dBodySetGravityMode (dBodyID b, int mode); -int dBodyGetGravityMode (dBodyID b); - - -/* joints */ - -dJointID dJointCreateBall (dWorldID, dJointGroupID); -dJointID dJointCreateHinge (dWorldID, dJointGroupID); -dJointID dJointCreateSlider (dWorldID, dJointGroupID); -dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *); -dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); -dJointID dJointCreateUniversal (dWorldID, dJointGroupID); -dJointID dJointCreateFixed (dWorldID, dJointGroupID); -dJointID dJointCreateNull (dWorldID, dJointGroupID); -dJointID dJointCreateAMotor (dWorldID, dJointGroupID); - -void dJointDestroy (dJointID); - -dJointGroupID dJointGroupCreate (int max_size); -void dJointGroupDestroy (dJointGroupID); -void dJointGroupEmpty (dJointGroupID); - -void dJointAttach (dJointID, dBodyID body1, dBodyID body2); -void dJointSetData (dJointID, void *data); -void *dJointGetData (dJointID); -int dJointGetType (dJointID); -dBodyID dJointGetBody (dJointID, int index); - -void dJointSetFeedback (dJointID, dJointFeedback *); -dJointFeedback *dJointGetFeedback (dJointID); - -void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); -void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z); -void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); -void dJointSetHingeAnchorDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); -void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); -void dJointSetHingeParam (dJointID, int parameter, dReal value); -void dJointAddHingeTorque(dJointID joint, dReal torque); -void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); -void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); -void dJointSetSliderParam (dJointID, int parameter, dReal value); -void dJointAddSliderForce(dJointID joint, dReal force); -void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); -void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); -void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z); -void dJointSetHinge2Param (dJointID, int parameter, dReal value); -void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2); -void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z); -void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); -void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); -void dJointSetUniversalParam (dJointID, int parameter, dReal value); -void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2); -void dJointSetFixed (dJointID); -void dJointSetAMotorNumAxes (dJointID, int num); -void dJointSetAMotorAxis (dJointID, int anum, int rel, - dReal x, dReal y, dReal z); -void dJointSetAMotorAngle (dJointID, int anum, dReal angle); -void dJointSetAMotorParam (dJointID, int parameter, dReal value); -void dJointSetAMotorMode (dJointID, int mode); -void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3); - -void dJointGetBallAnchor (dJointID, dVector3 result); -void dJointGetBallAnchor2 (dJointID, dVector3 result); -void dJointGetHingeAnchor (dJointID, dVector3 result); -void dJointGetHingeAnchor2 (dJointID, dVector3 result); -void dJointGetHingeAxis (dJointID, dVector3 result); -dReal dJointGetHingeParam (dJointID, int parameter); -dReal dJointGetHingeAngle (dJointID); -dReal dJointGetHingeAngleRate (dJointID); -dReal dJointGetSliderPosition (dJointID); -dReal dJointGetSliderPositionRate (dJointID); -void dJointGetSliderAxis (dJointID, dVector3 result); -dReal dJointGetSliderParam (dJointID, int parameter); -void dJointGetHinge2Anchor (dJointID, dVector3 result); -void dJointGetHinge2Anchor2 (dJointID, dVector3 result); -void dJointGetHinge2Axis1 (dJointID, dVector3 result); -void dJointGetHinge2Axis2 (dJointID, dVector3 result); -dReal dJointGetHinge2Param (dJointID, int parameter); -dReal dJointGetHinge2Angle1 (dJointID); -dReal dJointGetHinge2Angle1Rate (dJointID); -dReal dJointGetHinge2Angle2Rate (dJointID); -void dJointGetUniversalAnchor (dJointID, dVector3 result); -void dJointGetUniversalAnchor2 (dJointID, dVector3 result); -void dJointGetUniversalAxis1 (dJointID, dVector3 result); -void dJointGetUniversalAxis2 (dJointID, dVector3 result); -dReal dJointGetUniversalParam (dJointID, int parameter); -dReal dJointGetUniversalAngle1 (dJointID); -dReal dJointGetUniversalAngle2 (dJointID); -dReal dJointGetUniversalAngle1Rate (dJointID); -dReal dJointGetUniversalAngle2Rate (dJointID); -int dJointGetAMotorNumAxes (dJointID); -void dJointGetAMotorAxis (dJointID, int anum, dVector3 result); -int dJointGetAMotorAxisRel (dJointID, int anum); -dReal dJointGetAMotorAngle (dJointID, int anum); -dReal dJointGetAMotorAngleRate (dJointID, int anum); -dReal dJointGetAMotorParam (dJointID, int parameter); -int dJointGetAMotorMode (dJointID); - -dJointID dConnectingJoint (dBodyID, dBodyID); -int dConnectingJointList (dBodyID, dBodyID, dJointID*); -int dAreConnected (dBodyID, dBodyID); -int dAreConnectedExcluding (dBodyID, dBodyID, int joint_type); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/ode.h b/Extras/ode/include/ode/ode.h deleted file mode 100644 index 00cd500b3..000000000 --- a/Extras/ode/include/ode/ode.h +++ /dev/null @@ -1,47 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_ODE_H_ -#define _ODE_ODE_H_ - -/* include *everything* here */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif diff --git a/Extras/ode/include/ode/odecpp.h b/Extras/ode/include/ode/odecpp.h deleted file mode 100644 index 01a06e429..000000000 --- a/Extras/ode/include/ode/odecpp.h +++ /dev/null @@ -1,621 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* C++ interface for non-collision stuff */ - - -#ifndef _ODE_ODECPP_H_ -#define _ODE_ODECPP_H_ -#ifdef __cplusplus - -#include - - -class dWorld { - dWorldID _id; - - // intentionally undefined, don't use these - dWorld (const dWorld &); - void operator= (const dWorld &); - -public: - dWorld() - { _id = dWorldCreate(); } - ~dWorld() - { dWorldDestroy (_id); } - - dWorldID id() const - { return _id; } - operator dWorldID() const - { return _id; } - - void setGravity (dReal x, dReal y, dReal z) - { dWorldSetGravity (_id,x,y,z); } - void getGravity (dVector3 g) const - { dWorldGetGravity (_id,g); } - - void setERP (dReal erp) - { dWorldSetERP(_id, erp); } - dReal getERP() const - { return dWorldGetERP(_id); } - - void setCFM (dReal cfm) - { dWorldSetCFM(_id, cfm); } - dReal getCFM() const - { return dWorldGetCFM(_id); } - - void step (dReal stepsize) - { dWorldStep (_id,stepsize); } - - void stepFast1 (dReal stepsize, int maxiterations) - { dWorldStepFast1 (_id,stepsize,maxiterations); } - void setAutoEnableDepthSF1(dWorldID, int depth) - { dWorldSetAutoEnableDepthSF1 (_id, depth); } - int getAutoEnableDepthSF1(dWorldID) - { return dWorldGetAutoEnableDepthSF1 (_id); } - - void setAutoDisableLinearThreshold (dReal threshold) - { dWorldSetAutoDisableLinearThreshold (_id,threshold); } - dReal getAutoDisableLinearThreshold() - { return dWorldGetAutoDisableLinearThreshold (_id); } - void setAutoDisableAngularThreshold (dReal threshold) - { dWorldSetAutoDisableAngularThreshold (_id,threshold); } - dReal getAutoDisableAngularThreshold() - { return dWorldGetAutoDisableAngularThreshold (_id); } - void setAutoDisableSteps (int steps) - { dWorldSetAutoDisableSteps (_id,steps); } - int getAutoDisableSteps() - { return dWorldGetAutoDisableSteps (_id); } - void setAutoDisableTime (dReal time) - { dWorldSetAutoDisableTime (_id,time); } - dReal getAutoDisableTime() - { return dWorldGetAutoDisableTime (_id); } - void setAutoDisableFlag (int do_auto_disable) - { dWorldSetAutoDisableFlag (_id,do_auto_disable); } - int getAutoDisableFlag() - { return dWorldGetAutoDisableFlag (_id); } - - void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz, - dVector3 force) - { dWorldImpulseToForce (_id,stepsize,ix,iy,iz,force); } -}; - - -class dBody { - dBodyID _id; - - // intentionally undefined, don't use these - dBody (const dBody &); - void operator= (const dBody &); - -public: - dBody() - { _id = 0; } - dBody (dWorldID world) - { _id = dBodyCreate (world); } - ~dBody() - { if (_id) dBodyDestroy (_id); } - - void create (dWorldID world) { - if (_id) dBodyDestroy (_id); - _id = dBodyCreate (world); - } - - dBodyID id() const - { return _id; } - operator dBodyID() const - { return _id; } - - void setData (void *data) - { dBodySetData (_id,data); } - void *getData() const - { return dBodyGetData (_id); } - - void setPosition (dReal x, dReal y, dReal z) - { dBodySetPosition (_id,x,y,z); } - void setRotation (const dMatrix3 R) - { dBodySetRotation (_id,R); } - void setQuaternion (const dQuaternion q) - { dBodySetQuaternion (_id,q); } - void setLinearVel (dReal x, dReal y, dReal z) - { dBodySetLinearVel (_id,x,y,z); } - void setAngularVel (dReal x, dReal y, dReal z) - { dBodySetAngularVel (_id,x,y,z); } - - const dReal * getPosition() const - { return dBodyGetPosition (_id); } - const dReal * getRotation() const - { return dBodyGetRotation (_id); } - const dReal * getQuaternion() const - { return dBodyGetQuaternion (_id); } - const dReal * getLinearVel() const - { return dBodyGetLinearVel (_id); } - const dReal * getAngularVel() const - { return dBodyGetAngularVel (_id); } - - void setMass (const dMass *mass) - { dBodySetMass (_id,mass); } - void getMass (dMass *mass) const - { dBodyGetMass (_id,mass); } - - void addForce (dReal fx, dReal fy, dReal fz) - { dBodyAddForce (_id, fx, fy, fz); } - void addTorque (dReal fx, dReal fy, dReal fz) - { dBodyAddTorque (_id, fx, fy, fz); } - void addRelForce (dReal fx, dReal fy, dReal fz) - { dBodyAddRelForce (_id, fx, fy, fz); } - void addRelTorque (dReal fx, dReal fy, dReal fz) - { dBodyAddRelTorque (_id, fx, fy, fz); } - void addForceAtPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); } - void addForceAtRelPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddForceAtRelPos (_id, fx, fy, fz, px, py, pz); } - void addRelForceAtPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); } - void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); } - - const dReal * getForce() const - { return dBodyGetForce(_id); } - const dReal * getTorque() const - { return dBodyGetTorque(_id); } - void setForce (dReal x, dReal y, dReal z) - { dBodySetForce (_id,x,y,z); } - void setTorque (dReal x, dReal y, dReal z) - { dBodySetTorque (_id,x,y,z); } - - void enable() - { dBodyEnable (_id); } - void disable() - { dBodyDisable (_id); } - int isEnabled() const - { return dBodyIsEnabled (_id); } - - void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const - { dBodyGetRelPointPos (_id, px, py, pz, result); } - void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const - { dBodyGetRelPointVel (_id, px, py, pz, result); } - void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const - { dBodyGetPointVel (_id,px,py,pz,result); } - void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const - { dBodyGetPosRelPoint (_id,px,py,pz,result); } - void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const - { dBodyVectorToWorld (_id,px,py,pz,result); } - void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const - { dBodyVectorFromWorld (_id,px,py,pz,result); } - - void setFiniteRotationMode (int mode) - { dBodySetFiniteRotationMode (_id, mode); } - void setFiniteRotationAxis (dReal x, dReal y, dReal z) - { dBodySetFiniteRotationAxis (_id, x, y, z); } - - int getFiniteRotationMode() const - { return dBodyGetFiniteRotationMode (_id); } - void getFiniteRotationAxis (dVector3 result) const - { dBodyGetFiniteRotationAxis (_id, result); } - - int getNumJoints() const - { return dBodyGetNumJoints (_id); } - dJointID getJoint (int index) const - { return dBodyGetJoint (_id, index); } - - void setGravityMode (int mode) - { dBodySetGravityMode (_id,mode); } - int getGravityMode() const - { return dBodyGetGravityMode (_id); } - - int isConnectedTo (dBodyID body) const - { return dAreConnected (_id, body); } - - void setAutoDisableLinearThreshold (dReal threshold) - { dBodySetAutoDisableLinearThreshold (_id,threshold); } - dReal getAutoDisableLinearThreshold() - { return dBodyGetAutoDisableLinearThreshold (_id); } - void setAutoDisableAngularThreshold (dReal threshold) - { dBodySetAutoDisableAngularThreshold (_id,threshold); } - dReal getAutoDisableAngularThreshold() - { return dBodyGetAutoDisableAngularThreshold (_id); } - void setAutoDisableSteps (int steps) - { dBodySetAutoDisableSteps (_id,steps); } - int getAutoDisableSteps() - { return dBodyGetAutoDisableSteps (_id); } - void setAutoDisableTime (dReal time) - { dBodySetAutoDisableTime (_id,time); } - dReal getAutoDisableTime() - { return dBodyGetAutoDisableTime (_id); } - void setAutoDisableFlag (int do_auto_disable) - { dBodySetAutoDisableFlag (_id,do_auto_disable); } - int getAutoDisableFlag() - { return dBodyGetAutoDisableFlag (_id); } -}; - - -class dJointGroup { - dJointGroupID _id; - - // intentionally undefined, don't use these - dJointGroup (const dJointGroup &); - void operator= (const dJointGroup &); - -public: - dJointGroup (int dummy_arg=0) - { _id = dJointGroupCreate (0); } - ~dJointGroup() - { dJointGroupDestroy (_id); } - void create (int dummy_arg=0) { - if (_id) dJointGroupDestroy (_id); - _id = dJointGroupCreate (0); - } - - dJointGroupID id() const - { return _id; } - operator dJointGroupID() const - { return _id; } - - void empty() - { dJointGroupEmpty (_id); } -}; - - -class dJoint { -private: - // intentionally undefined, don't use these - dJoint (const dJoint &) ; - void operator= (const dJoint &); - -protected: - dJointID _id; - -public: - dJoint() - { _id = 0; } - ~dJoint() - { if (_id) dJointDestroy (_id); } - - dJointID id() const - { return _id; } - operator dJointID() const - { return _id; } - - void attach (dBodyID body1, dBodyID body2) - { dJointAttach (_id, body1, body2); } - - void setData (void *data) - { dJointSetData (_id, data); } - void *getData() const - { return dJointGetData (_id); } - - int getType() const - { return dJointGetType (_id); } - - dBodyID getBody (int index) const - { return dJointGetBody (_id, index); } -}; - - -class dBallJoint : public dJoint { -private: - // intentionally undefined, don't use these - dBallJoint (const dBallJoint &); - void operator= (const dBallJoint &); - -public: - dBallJoint() { } - dBallJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateBall (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateBall (world, group); - } - - void setAnchor (dReal x, dReal y, dReal z) - { dJointSetBallAnchor (_id, x, y, z); } - void getAnchor (dVector3 result) const - { dJointGetBallAnchor (_id, result); } - void getAnchor2 (dVector3 result) const - { dJointGetBallAnchor2 (_id, result); } -} ; - - -class dHingeJoint : public dJoint { - // intentionally undefined, don't use these - dHingeJoint (const dHingeJoint &); - void operator = (const dHingeJoint &); - -public: - dHingeJoint() { } - dHingeJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateHinge (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateHinge (world, group); - } - - void setAnchor (dReal x, dReal y, dReal z) - { dJointSetHingeAnchor (_id, x, y, z); } - void getAnchor (dVector3 result) const - { dJointGetHingeAnchor (_id, result); } - void getAnchor2 (dVector3 result) const - { dJointGetHingeAnchor2 (_id, result); } - - void setAxis (dReal x, dReal y, dReal z) - { dJointSetHingeAxis (_id, x, y, z); } - void getAxis (dVector3 result) const - { dJointGetHingeAxis (_id, result); } - - dReal getAngle() const - { return dJointGetHingeAngle (_id); } - dReal getAngleRate() const - { return dJointGetHingeAngleRate (_id); } - - void setParam (int parameter, dReal value) - { dJointSetHingeParam (_id, parameter, value); } - dReal getParam (int parameter) const - { return dJointGetHingeParam (_id, parameter); } - - void addTorque (dReal torque) - { dJointAddHingeTorque(_id, torque); } -}; - - -class dSliderJoint : public dJoint { - // intentionally undefined, don't use these - dSliderJoint (const dSliderJoint &); - void operator = (const dSliderJoint &); - -public: - dSliderJoint() { } - dSliderJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateSlider (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateSlider (world, group); - } - - void setAxis (dReal x, dReal y, dReal z) - { dJointSetSliderAxis (_id, x, y, z); } - void getAxis (dVector3 result) const - { dJointGetSliderAxis (_id, result); } - - dReal getPosition() const - { return dJointGetSliderPosition (_id); } - dReal getPositionRate() const - { return dJointGetSliderPositionRate (_id); } - - void setParam (int parameter, dReal value) - { dJointSetSliderParam (_id, parameter, value); } - dReal getParam (int parameter) const - { return dJointGetSliderParam (_id, parameter); } - - void addForce (dReal force) - { dJointAddSliderForce(_id, force); } -}; - - -class dUniversalJoint : public dJoint { - // intentionally undefined, don't use these - dUniversalJoint (const dUniversalJoint &); - void operator = (const dUniversalJoint &); - -public: - dUniversalJoint() { } - dUniversalJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateUniversal (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateUniversal (world, group); - } - - void setAnchor (dReal x, dReal y, dReal z) - { dJointSetUniversalAnchor (_id, x, y, z); } - void setAxis1 (dReal x, dReal y, dReal z) - { dJointSetUniversalAxis1 (_id, x, y, z); } - void setAxis2 (dReal x, dReal y, dReal z) - { dJointSetUniversalAxis2 (_id, x, y, z); } - void setParam (int parameter, dReal value) - { dJointSetUniversalParam (_id, parameter, value); } - - void getAnchor (dVector3 result) const - { dJointGetUniversalAnchor (_id, result); } - void getAnchor2 (dVector3 result) const - { dJointGetUniversalAnchor2 (_id, result); } - void getAxis1 (dVector3 result) const - { dJointGetUniversalAxis1 (_id, result); } - void getAxis2 (dVector3 result) const - { dJointGetUniversalAxis2 (_id, result); } - dReal getParam (int parameter) const - { return dJointGetUniversalParam (_id, parameter); } - dReal getAngle1() const - { return dJointGetUniversalAngle1 (_id); } - dReal getAngle1Rate() const - { return dJointGetUniversalAngle1Rate (_id); } - dReal getAngle2() const - { return dJointGetUniversalAngle2 (_id); } - dReal getAngle2Rate() const - { return dJointGetUniversalAngle2Rate (_id); } - - void addTorques (dReal torque1, dReal torque2) - { dJointAddUniversalTorques(_id, torque1, torque2); } -}; - - -class dHinge2Joint : public dJoint { - // intentionally undefined, don't use these - dHinge2Joint (const dHinge2Joint &); - void operator = (const dHinge2Joint &); - -public: - dHinge2Joint() { } - dHinge2Joint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateHinge2 (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateHinge2 (world, group); - } - - void setAnchor (dReal x, dReal y, dReal z) - { dJointSetHinge2Anchor (_id, x, y, z); } - void setAxis1 (dReal x, dReal y, dReal z) - { dJointSetHinge2Axis1 (_id, x, y, z); } - void setAxis2 (dReal x, dReal y, dReal z) - { dJointSetHinge2Axis2 (_id, x, y, z); } - - void getAnchor (dVector3 result) const - { dJointGetHinge2Anchor (_id, result); } - void getAnchor2 (dVector3 result) const - { dJointGetHinge2Anchor2 (_id, result); } - void getAxis1 (dVector3 result) const - { dJointGetHinge2Axis1 (_id, result); } - void getAxis2 (dVector3 result) const - { dJointGetHinge2Axis2 (_id, result); } - - dReal getAngle1() const - { return dJointGetHinge2Angle1 (_id); } - dReal getAngle1Rate() const - { return dJointGetHinge2Angle1Rate (_id); } - dReal getAngle2Rate() const - { return dJointGetHinge2Angle2Rate (_id); } - - void setParam (int parameter, dReal value) - { dJointSetHinge2Param (_id, parameter, value); } - dReal getParam (int parameter) const - { return dJointGetHinge2Param (_id, parameter); } - - void addTorques(dReal torque1, dReal torque2) - { dJointAddHinge2Torques(_id, torque1, torque2); } -}; - - -class dFixedJoint : public dJoint { - // intentionally undefined, don't use these - dFixedJoint (const dFixedJoint &); - void operator = (const dFixedJoint &); - -public: - dFixedJoint() { } - dFixedJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateFixed (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateFixed (world, group); - } - - void set() - { dJointSetFixed (_id); } -}; - - -class dContactJoint : public dJoint { - // intentionally undefined, don't use these - dContactJoint (const dContactJoint &); - void operator = (const dContactJoint &); - -public: - dContactJoint() { } - dContactJoint (dWorldID world, dJointGroupID group, dContact *contact) - { _id = dJointCreateContact (world, group, contact); } - - void create (dWorldID world, dJointGroupID group, dContact *contact) { - if (_id) dJointDestroy (_id); - _id = dJointCreateContact (world, group, contact); - } -}; - - -class dNullJoint : public dJoint { - // intentionally undefined, don't use these - dNullJoint (const dNullJoint &); - void operator = (const dNullJoint &); - -public: - dNullJoint() { } - dNullJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateNull (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateNull (world, group); - } -}; - - -class dAMotorJoint : public dJoint { - // intentionally undefined, don't use these - dAMotorJoint (const dAMotorJoint &); - void operator = (const dAMotorJoint &); - -public: - dAMotorJoint() { } - dAMotorJoint (dWorldID world, dJointGroupID group=0) - { _id = dJointCreateAMotor (world, group); } - - void create (dWorldID world, dJointGroupID group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateAMotor (world, group); - } - - void setMode (int mode) - { dJointSetAMotorMode (_id, mode); } - int getMode() const - { return dJointGetAMotorMode (_id); } - - void setNumAxes (int num) - { dJointSetAMotorNumAxes (_id, num); } - int getNumAxes() const - { return dJointGetAMotorNumAxes (_id); } - - void setAxis (int anum, int rel, dReal x, dReal y, dReal z) - { dJointSetAMotorAxis (_id, anum, rel, x, y, z); } - void getAxis (int anum, dVector3 result) const - { dJointGetAMotorAxis (_id, anum, result); } - int getAxisRel (int anum) const - { return dJointGetAMotorAxisRel (_id, anum); } - - void setAngle (int anum, dReal angle) - { dJointSetAMotorAngle (_id, anum, angle); } - dReal getAngle (int anum) const - { return dJointGetAMotorAngle (_id, anum); } - dReal getAngleRate (int anum) - { return dJointGetAMotorAngleRate (_id,anum); } - - void setParam (int parameter, dReal value) - { dJointSetAMotorParam (_id, parameter, value); } - dReal getParam (int parameter) const - { return dJointGetAMotorParam (_id, parameter); } - - void addTorques(dReal torque1, dReal torque2, dReal torque3) - { dJointAddAMotorTorques(_id, torque1, torque2, torque3); } -}; - - -#endif -#endif diff --git a/Extras/ode/include/ode/odecpp_collision.h b/Extras/ode/include/ode/odecpp_collision.h deleted file mode 100644 index 6d69d2129..000000000 --- a/Extras/ode/include/ode/odecpp_collision.h +++ /dev/null @@ -1,346 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* C++ interface for new collision API */ - - -#ifndef _ODE_ODECPP_COLLISION_H_ -#define _ODE_ODECPP_COLLISION_H_ -#ifdef __cplusplus - -#include - - -class dGeom { - // intentionally undefined, don't use these - dGeom (dGeom &); - void operator= (dGeom &); - -protected: - dGeomID _id; - -public: - dGeom() - { _id = 0; } - ~dGeom() - { if (_id) dGeomDestroy (_id); } - - dGeomID id() const - { return _id; } - operator dGeomID() const - { return _id; } - - void destroy() { - if (_id) dGeomDestroy (_id); - _id = 0; - } - - int getClass() const - { return dGeomGetClass (_id); } - - dSpaceID getSpace() const - { return dGeomGetSpace (_id); } - - void setData (void *data) - { dGeomSetData (_id,data); } - void *getData() const - { return dGeomGetData (_id); } - - void setBody (dBodyID b) - { dGeomSetBody (_id,b); } - dBodyID getBody() const - { return dGeomGetBody (_id); } - - void setPosition (dReal x, dReal y, dReal z) - { dGeomSetPosition (_id,x,y,z); } - const dReal * getPosition() const - { return dGeomGetPosition (_id); } - - void setRotation (const dMatrix3 R) - { dGeomSetRotation (_id,R); } - const dReal * getRotation() const - { return dGeomGetRotation (_id); } - - void setQuaternion (const dQuaternion quat) - { dGeomSetQuaternion (_id,quat); } - void getQuaternion (dQuaternion quat) const - { dGeomGetQuaternion (_id,quat); } - - void getAABB (dReal aabb[6]) const - { dGeomGetAABB (_id, aabb); } - - int isSpace() - { return dGeomIsSpace (_id); } - - void setCategoryBits (unsigned long bits) - { dGeomSetCategoryBits (_id, bits); } - void setCollideBits (unsigned long bits) - { dGeomSetCollideBits (_id, bits); } - unsigned long getCategoryBits() - { return dGeomGetCategoryBits (_id); } - unsigned long getCollideBits() - { return dGeomGetCollideBits (_id); } - - void enable() - { dGeomEnable (_id); } - void disable() - { dGeomDisable (_id); } - int isEnabled() - { return dGeomIsEnabled (_id); } - - void collide2 (dGeomID g, void *data, dNearCallback *callback) - { dSpaceCollide2 (_id,g,data,callback); } -}; - - -class dSpace : public dGeom { - // intentionally undefined, don't use these - dSpace (dSpace &); - void operator= (dSpace &); - -protected: - // the default constructor is protected so that you - // can't instance this class. you must instance one - // of its subclasses instead. - dSpace () { _id = 0; } - -public: - dSpaceID id() const - { return (dSpaceID) _id; } - operator dSpaceID() const - { return (dSpaceID) _id; } - - void setCleanup (int mode) - { dSpaceSetCleanup (id(), mode); } - int getCleanup() - { return dSpaceGetCleanup (id()); } - - void add (dGeomID x) - { dSpaceAdd (id(), x); } - void remove (dGeomID x) - { dSpaceRemove (id(), x); } - int query (dGeomID x) - { return dSpaceQuery (id(),x); } - - int getNumGeoms() - { return dSpaceGetNumGeoms (id()); } - dGeomID getGeom (int i) - { return dSpaceGetGeom (id(),i); } - - void collide (void *data, dNearCallback *callback) - { dSpaceCollide (id(),data,callback); } -}; - - -class dSimpleSpace : public dSpace { - // intentionally undefined, don't use these - dSimpleSpace (dSimpleSpace &); - void operator= (dSimpleSpace &); - -public: - dSimpleSpace (dSpaceID space) - { _id = (dGeomID) dSimpleSpaceCreate (space); } -}; - - -class dHashSpace : public dSpace { - // intentionally undefined, don't use these - dHashSpace (dHashSpace &); - void operator= (dHashSpace &); - -public: - dHashSpace (dSpaceID space) - { _id = (dGeomID) dHashSpaceCreate (space); } - void setLevels (int minlevel, int maxlevel) - { dHashSpaceSetLevels (id(),minlevel,maxlevel); } -}; - - -class dQuadTreeSpace : public dSpace { - // intentionally undefined, don't use these - dQuadTreeSpace (dQuadTreeSpace &); - void operator= (dQuadTreeSpace &); - -public: - dQuadTreeSpace (dSpaceID space, dVector3 center, dVector3 extents, int depth) - { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); } -}; - - -class dSphere : public dGeom { - // intentionally undefined, don't use these - dSphere (dSphere &); - void operator= (dSphere &); - -public: - dSphere () { } - dSphere (dSpaceID space, dReal radius) - { _id = dCreateSphere (space, radius); } - - void create (dSpaceID space, dReal radius) { - if (_id) dGeomDestroy (_id); - _id = dCreateSphere (space, radius); - } - - void setRadius (dReal radius) - { dGeomSphereSetRadius (_id, radius); } - dReal getRadius() const - { return dGeomSphereGetRadius (_id); } -}; - - -class dBox : public dGeom { - // intentionally undefined, don't use these - dBox (dBox &); - void operator= (dBox &); - -public: - dBox () { } - dBox (dSpaceID space, dReal lx, dReal ly, dReal lz) - { _id = dCreateBox (space,lx,ly,lz); } - - void create (dSpaceID space, dReal lx, dReal ly, dReal lz) { - if (_id) dGeomDestroy (_id); - _id = dCreateBox (space,lx,ly,lz); - } - - void setLengths (dReal lx, dReal ly, dReal lz) - { dGeomBoxSetLengths (_id, lx, ly, lz); } - void getLengths (dVector3 result) const - { dGeomBoxGetLengths (_id,result); } -}; - - -class dPlane : public dGeom { - // intentionally undefined, don't use these - dPlane (dPlane &); - void operator= (dPlane &); - -public: - dPlane() { } - dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) - { _id = dCreatePlane (space,a,b,c,d); } - - void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) { - if (_id) dGeomDestroy (_id); - _id = dCreatePlane (space,a,b,c,d); - } - - void setParams (dReal a, dReal b, dReal c, dReal d) - { dGeomPlaneSetParams (_id, a, b, c, d); } - void getParams (dVector4 result) const - { dGeomPlaneGetParams (_id,result); } -}; - - -class dCCylinder : public dGeom { - // intentionally undefined, don't use these - dCCylinder (dCCylinder &); - void operator= (dCCylinder &); - -public: - dCCylinder() { } - dCCylinder (dSpaceID space, dReal radius, dReal length) - { _id = dCreateCCylinder (space,radius,length); } - - void create (dSpaceID space, dReal radius, dReal length) { - if (_id) dGeomDestroy (_id); - _id = dCreateCCylinder (space,radius,length); - } - - void setParams (dReal radius, dReal length) - { dGeomCCylinderSetParams (_id, radius, length); } - void getParams (dReal *radius, dReal *length) const - { dGeomCCylinderGetParams (_id,radius,length); } -}; - - -class dRay : public dGeom { - // intentionally undefined, don't use these - dRay (dRay &); - void operator= (dRay &); - -public: - dRay() { } - dRay (dSpaceID space, dReal length) - { _id = dCreateRay (space,length); } - - void create (dSpaceID space, dReal length) { - if (_id) dGeomDestroy (_id); - _id = dCreateRay (space,length); - } - - void setLength (dReal length) - { dGeomRaySetLength (_id, length); } - dReal getLength() - { return dGeomRayGetLength (_id); } - - void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz) - { dGeomRaySet (_id, px, py, pz, dx, dy, dz); } - void get (dVector3 start, dVector3 dir) - { dGeomRayGet (_id, start, dir); } - - void setParams (int firstContact, int backfaceCull) - { dGeomRaySetParams (_id, firstContact, backfaceCull); } - void getParams (int *firstContact, int *backfaceCull) - { dGeomRayGetParams (_id, firstContact, backfaceCull); } - void setClosestHit (int closestHit) - { dGeomRaySetClosestHit (_id, closestHit); } - int getClosestHit() - { return dGeomRayGetClosestHit (_id); } -}; - - -class dGeomTransform : public dGeom { - // intentionally undefined, don't use these - dGeomTransform (dGeomTransform &); - void operator= (dGeomTransform &); - -public: - dGeomTransform() { } - dGeomTransform (dSpaceID space) - { _id = dCreateGeomTransform (space); } - - void create (dSpaceID space=0) { - if (_id) dGeomDestroy (_id); - _id = dCreateGeomTransform (space); - } - - void setGeom (dGeomID geom) - { dGeomTransformSetGeom (_id, geom); } - dGeomID getGeom() const - { return dGeomTransformGetGeom (_id); } - - void setCleanup (int mode) - { dGeomTransformSetCleanup (_id,mode); } - int getCleanup () - { return dGeomTransformGetCleanup (_id); } - - void setInfo (int mode) - { dGeomTransformSetInfo (_id,mode); } - int getInfo() - { return dGeomTransformGetInfo (_id); } -}; - - -#endif -#endif diff --git a/Extras/ode/include/ode/odecpp_old.h b/Extras/ode/include/ode/odecpp_old.h deleted file mode 100644 index 49e7d7f3c..000000000 --- a/Extras/ode/include/ode/odecpp_old.h +++ /dev/null @@ -1,316 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* this is the old C++ interface, the new C++ interface is not quite - * compatible with this. but this file is kept around in case you were - * using the old interface. - */ - -#ifndef _ODE_ODECPP_H_ -#define _ODE_ODECPP_H_ -#ifdef __cplusplus - -#include - - -class dWorld { - dWorldID _id; - - dWorld (dWorld &) { dDebug (0,"bad"); } - void operator= (dWorld &) { dDebug (0,"bad"); } - -public: - dWorld() - { _id = dWorldCreate(); } - ~dWorld() - { dWorldDestroy (_id); } - dWorldID id() - { return _id; } - - void setGravity (dReal x, dReal y, dReal z) - { dWorldSetGravity (_id,x,y,z); } - void getGravity (dVector3 g) - { dWorldGetGravity (_id,g); } - void step (dReal stepsize) - { dWorldStep (_id,stepsize); } -}; - - -class dBody { - dBodyID _id; - - dBody (dBody &) { dDebug (0,"bad"); } - void operator= (dBody &) { dDebug (0,"bad"); } - -public: - dBody() - { _id = 0; } - dBody (dWorld &world) - { _id = dBodyCreate (world.id()); } - ~dBody() - { dBodyDestroy (_id); } - void create (dWorld &world) - { if (_id) dBodyDestroy (_id); _id = dBodyCreate (world.id()); } - dBodyID id() - { return _id; } - - void setData (void *data) - { dBodySetData (_id,data); } - void *getData() - { return dBodyGetData (_id); } - - void setPosition (dReal x, dReal y, dReal z) - { dBodySetPosition (_id,x,y,z); } - void setRotation (const dMatrix3 R) - { dBodySetRotation (_id,R); } - void setQuaternion (const dQuaternion q) - { dBodySetQuaternion (_id,q); } - void setLinearVel (dReal x, dReal y, dReal z) - { dBodySetLinearVel (_id,x,y,z); } - void setAngularVel (dReal x, dReal y, dReal z) - { dBodySetAngularVel (_id,x,y,z); } - - const dReal * getPosition() - { return dBodyGetPosition (_id); } - const dReal * getRotation() - { return dBodyGetRotation (_id); } - const dReal * getQuaternion() - { return dBodyGetQuaternion (_id); } - const dReal * getLinearVel() - { return dBodyGetLinearVel (_id); } - const dReal * getAngularVel() - { return dBodyGetAngularVel (_id); } - - void setMass (const dMass *mass) - { dBodySetMass (_id,mass); } - void getMass (dMass *mass) - { dBodyGetMass (_id,mass); } - - void addForce (dReal fx, dReal fy, dReal fz) - { dBodyAddForce (_id, fx, fy, fz); } - void addTorque (dReal fx, dReal fy, dReal fz) - { dBodyAddTorque (_id, fx, fy, fz); } - void addRelForce (dReal fx, dReal fy, dReal fz) - { dBodyAddRelForce (_id, fx, fy, fz); } - void addRelTorque (dReal fx, dReal fy, dReal fz) - { dBodyAddRelTorque (_id, fx, fy, fz); } - void addForceAtPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); } - void addRelForceAtPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); } - void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) - { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); } - - void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) - { dBodyGetRelPointPos (_id, px, py, pz, result); } - void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) - { dBodyGetRelPointVel (_id, px, py, pz, result); } - - int isConnectedTo (const dBody &b) - { return dAreConnected (_id,b._id); } -}; - - -class dJointGroup { - dJointGroupID _id; - - dJointGroup (dJointGroup &) { dDebug (0,"bad"); } - void operator= (dJointGroup &) { dDebug (0,"bad"); } - -public: - dJointGroup() - { _id = 0; } - dJointGroup (int max_size) - { _id = dJointGroupCreate (max_size); } - ~dJointGroup() - { dJointGroupDestroy (_id); } - void create (int max_size) - { if (_id) dJointGroupDestroy (_id); _id = dJointGroupCreate (max_size); } - dJointGroupID id() - { return _id; } - - void empty() - { dJointGroupEmpty (_id); } -}; - - -class dJoint { - dJointID _id; - - dJoint (dJoint &) { dDebug (0,"bad"); } - void operator= (dJoint &) { dDebug (0,"bad"); } - -public: - dJoint() - { _id = 0; } - ~dJoint() - { dJointDestroy (_id); } - dJointID id() - { return _id; } - - void createBall (dWorld &world, dJointGroup *group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateBall (world.id(), group ? group->id() : 0); - } - void createHinge (dWorld &world, dJointGroup *group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateHinge (world.id(), group ? group->id() : 0); - } - void createSlider (dWorld &world, dJointGroup *group=0) { - if (_id) dJointDestroy (_id); - _id = dJointCreateSlider (world.id(), group ? group->id() : 0); - } - void createContact (dWorld &world, dJointGroup *group, dContact *contact) { - if (_id) dJointDestroy (_id); - _id = dJointCreateContact (world.id(), group ? group->id() : 0, contact); - } - - void attach (dBody &body1, dBody &body2) - { dJointAttach (_id, body1.id(), body2.id()); } - - void setBallAnchor (dReal x, dReal y, dReal z) - { dJointSetBallAnchor (_id, x, y, z); } - void setHingeAnchor (dReal x, dReal y, dReal z) - { dJointSetHingeAnchor (_id, x, y, z); } - - void setHingeAxis (dReal x, dReal y, dReal z) - { dJointSetHingeAxis (_id, x, y, z); } - void setSliderAxis (dReal x, dReal y, dReal z) - { dJointSetSliderAxis (_id, x, y, z); } - - void getBallAnchor (dVector3 result) - { dJointGetBallAnchor (_id, result); } - void getHingeAnchor (dVector3 result) - { dJointGetHingeAnchor (_id, result); } - - void getHingeAxis (dVector3 result) - { dJointGetHingeAxis (_id, result); } - void getSliderAxis (dVector3 result) - { dJointGetSliderAxis (_id, result); } -}; - - -class dSpace { - dSpaceID _id; - - dSpace (dSpace &) { dDebug (0,"bad"); } - void operator= (dSpace &) { dDebug (0,"bad"); } - -public: - dSpace () - { _id = dHashSpaceCreate(); } - ~dSpace() - { dSpaceDestroy (_id); } - dSpaceID id() - { return _id; } - void collide (void *data, dNearCallback *callback) - { dSpaceCollide (_id,data,callback); } -}; - - -class dGeom { - dGeomID _id; - - dGeom (dGeom &) { dDebug (0,"bad"); } - void operator= (dGeom &) { dDebug (0,"bad"); } - -public: - dGeom() - { _id = 0; } - ~dGeom() - { dGeomDestroy (_id); } - dGeomID id() - { return _id; } - - void createSphere (dSpace &space, dReal radius) { - if (_id) dGeomDestroy (_id); - _id = dCreateSphere (space.id(),radius); - } - - void createBox (dSpace &space, dReal lx, dReal ly, dReal lz) { - if (_id) dGeomDestroy (_id); - _id = dCreateBox (space.id(),lx,ly,lz); - } - - void createPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d) { - if (_id) dGeomDestroy (_id); - _id = dCreatePlane (space.id(),a,b,c,d); - } - - void createCCylinder (dSpace &space, dReal radius, dReal length) { - if (_id) dGeomDestroy (_id); - _id = dCreateCCylinder (space.id(),radius,length); - } - - void destroy() { - if (_id) dGeomDestroy (_id); - _id = 0; - } - - int getClass() - { return dGeomGetClass (_id); } - - dReal sphereGetRadius() - { return dGeomSphereGetRadius (_id); } - - void boxGetLengths (dVector3 result) - { dGeomBoxGetLengths (_id,result); } - - void planeGetParams (dVector4 result) - { dGeomPlaneGetParams (_id,result); } - - void CCylinderGetParams (dReal *radius, dReal *length) - { dGeomCCylinderGetParams (_id,radius,length); } - - void setData (void *data) - { dGeomSetData (_id,data); } - - void *getData() - { return dGeomGetData (_id); } - - void setBody (dBody &b) - { dGeomSetBody (_id,b.id()); } - void setBody (dBodyID b) - { dGeomSetBody (_id,b); } - - dBodyID getBody() - { return dGeomGetBody (_id); } - - void setPosition (dReal x, dReal y, dReal z) - { dGeomSetPosition (_id,x,y,z); } - - void setRotation (const dMatrix3 R) - { dGeomSetRotation (_id,R); } - - const dReal * getPosition() - { return dGeomGetPosition (_id); } - - const dReal * getRotation() - { return dGeomGetRotation (_id); } -}; - - -#endif -#endif diff --git a/Extras/ode/include/ode/odemath.h b/Extras/ode/include/ode/odemath.h deleted file mode 100644 index 5ae3690f5..000000000 --- a/Extras/ode/include/ode/odemath.h +++ /dev/null @@ -1,258 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_ODEMATH_H_ -#define _ODE_ODEMATH_H_ - -#include - -#ifdef __GNUC__ -#define PURE_INLINE extern inline -#else -#define PURE_INLINE inline -#endif - -/* - * macro to access elements i,j in an NxM matrix A, independent of the - * matrix storage convention. - */ -#define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) - - -/* - * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced - * p and q indexes apart respectively. dDOT() means dDOT11. - * in C++ we could use function templates to get all the versions of these - * functions - but on some compilers this will result in sub-optimal code. - */ - -#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) - -#ifdef __cplusplus - -PURE_INLINE dReal dDOT (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); } -PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); } -PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); } -PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); } -PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); } -PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); } -PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); } - -#else - -#define dDOT(a,b) dDOTpq(a,b,1,1) -#define dDOT13(a,b) dDOTpq(a,b,1,3) -#define dDOT31(a,b) dDOTpq(a,b,3,1) -#define dDOT33(a,b) dDOTpq(a,b,3,3) -#define dDOT14(a,b) dDOTpq(a,b,1,4) -#define dDOT41(a,b) dDOTpq(a,b,4,1) -#define dDOT44(a,b) dDOTpq(a,b,4,4) - -#endif /* __cplusplus */ - - -/* - * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' - * and `c' are spaced p, q and r indexes apart respectively. - * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to - * +=, -= etc to get other effects. - */ - -#define dCROSS(a,op,b,c) \ -do { \ - (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ - (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ - (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \ -} while(0) -#define dCROSSpqr(a,op,b,c,p,q,r) \ -do { \ - (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ - (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ - (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \ -} while(0) -#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) -#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) -#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) -#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) -#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) -#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) -#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) - - -/* - * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. - * A is stored by rows, and has `skip' elements per row. the matrix is - * assumed to be already zero, so this does not write zero elements! - * if (plus,minus) is (+,-) then a positive version will be written. - * if (plus,minus) is (-,+) then a negative version will be written. - */ - -#define dCROSSMAT(A,a,skip,plus,minus) \ -do { \ - (A)[1] = minus (a)[2]; \ - (A)[2] = plus (a)[1]; \ - (A)[(skip)+0] = plus (a)[2]; \ - (A)[(skip)+2] = minus (a)[0]; \ - (A)[2*(skip)+0] = minus (a)[1]; \ - (A)[2*(skip)+1] = plus (a)[0]; \ -} while(0) - - -/* - * compute the distance between two 3-vectors - */ - -#ifdef __cplusplus -PURE_INLINE float dDISTANCE (const float a[3], const float b[3]) - { return (float) dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } -PURE_INLINE double dDISTANCE (const double a[3], const double b[3]) - { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } -#else -#define dDISTANCE(a,b) \ - (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b)[1]) + ((a)[2]-(b)[2])*((a)[2]-(b)[2]) )) -#endif - - -/* - * special case matrix multipication, with operator selection - */ - -#define dMULTIPLYOP0_331(A,op,B,C) \ -do { \ - (A)[0] op dDOT((B),(C)); \ - (A)[1] op dDOT((B+4),(C)); \ - (A)[2] op dDOT((B+8),(C)); \ -} while(0) -#define dMULTIPLYOP1_331(A,op,B,C) \ -do { \ - (A)[0] op dDOT41((B),(C)); \ - (A)[1] op dDOT41((B+1),(C)); \ - (A)[2] op dDOT41((B+2),(C)); \ -} while(0) -#define dMULTIPLYOP0_133(A,op,B,C) \ -do { \ - (A)[0] op dDOT14((B),(C)); \ - (A)[1] op dDOT14((B),(C+1)); \ - (A)[2] op dDOT14((B),(C+2)); \ -} while(0) -#define dMULTIPLYOP0_333(A,op,B,C) \ -do { \ - (A)[0] op dDOT14((B),(C)); \ - (A)[1] op dDOT14((B),(C+1)); \ - (A)[2] op dDOT14((B),(C+2)); \ - (A)[4] op dDOT14((B+4),(C)); \ - (A)[5] op dDOT14((B+4),(C+1)); \ - (A)[6] op dDOT14((B+4),(C+2)); \ - (A)[8] op dDOT14((B+8),(C)); \ - (A)[9] op dDOT14((B+8),(C+1)); \ - (A)[10] op dDOT14((B+8),(C+2)); \ -} while(0) -#define dMULTIPLYOP1_333(A,op,B,C) \ -do { \ - (A)[0] op dDOT44((B),(C)); \ - (A)[1] op dDOT44((B),(C+1)); \ - (A)[2] op dDOT44((B),(C+2)); \ - (A)[4] op dDOT44((B+1),(C)); \ - (A)[5] op dDOT44((B+1),(C+1)); \ - (A)[6] op dDOT44((B+1),(C+2)); \ - (A)[8] op dDOT44((B+2),(C)); \ - (A)[9] op dDOT44((B+2),(C+1)); \ - (A)[10] op dDOT44((B+2),(C+2)); \ -} while(0) -#define dMULTIPLYOP2_333(A,op,B,C) \ -do { \ - (A)[0] op dDOT((B),(C)); \ - (A)[1] op dDOT((B),(C+4)); \ - (A)[2] op dDOT((B),(C+8)); \ - (A)[4] op dDOT((B+4),(C)); \ - (A)[5] op dDOT((B+4),(C+4)); \ - (A)[6] op dDOT((B+4),(C+8)); \ - (A)[8] op dDOT((B+8),(C)); \ - (A)[9] op dDOT((B+8),(C+4)); \ - (A)[10] op dDOT((B+8),(C+8)); \ -} while(0) - -#ifdef __cplusplus - -#define DECL template PURE_INLINE void - -DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C); } -DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C); } -DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C); } -DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C); } -DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C); } -DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C); } - -DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C); } -DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C); } -DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C); } -DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C); } -DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C); } -DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C); } - -#undef DECL - -#else - -#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) -#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) -#define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C) -#define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) -#define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C) -#define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C) - -#define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C) -#define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C) -#define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C) -#define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C) -#define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C) -#define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C) - -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) - */ -void dNormalize3 (dVector3 a); -void dNormalize4 (dVector4 a); - - -/* - * given a unit length "normal" vector n, generate vectors p and q vectors - * that are an orthonormal basis for the plane space perpendicular to n. - * i.e. this makes p,q such that n,p,q are all perpendicular to each other. - * q will equal n x p. if n is not unit length then p will be unit length but - * q wont be. - */ - -void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/rotation.h b/Extras/ode/include/ode/rotation.h deleted file mode 100644 index 951547d98..000000000 --- a/Extras/ode/include/ode/rotation.h +++ /dev/null @@ -1,70 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_ROTATION_H_ -#define _ODE_ROTATION_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -void dRSetIdentity (dMatrix3 R); - -void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, - dReal angle); - -void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi); - -void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, - dReal bx, dReal by, dReal bz); - -void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az); - -void dQSetIdentity (dQuaternion q); - -void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, - dReal angle); - -/* Quaternion multiplication, analogous to the matrix multiplication routines. */ -/* qa = rotate by qc, then qb */ -void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); -/* qa = rotate by qc, then by inverse of qb */ -void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); -/* qa = rotate by inverse of qc, then by qb */ -void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); -/* qa = rotate by inverse of qc, then by inverse of qb */ -void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); - -void dRfromQ (dMatrix3 R, const dQuaternion q); -void dQfromR (dQuaternion q, const dMatrix3 R); -void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/include/ode/timer.h b/Extras/ode/include/ode/timer.h deleted file mode 100644 index 7ca462a88..000000000 --- a/Extras/ode/include/ode/timer.h +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_TIMER_H_ -#define _ODE_TIMER_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* stop watch objects */ - -typedef struct dStopwatch { - double time; /* total clock count */ - unsigned long cc[2]; /* clock count since last `start' */ -} dStopwatch; - -void dStopwatchReset (dStopwatch *); -void dStopwatchStart (dStopwatch *); -void dStopwatchStop (dStopwatch *); -double dStopwatchTime (dStopwatch *); /* returns total time in secs */ - - -/* code timers */ - -void dTimerStart (const char *description); /* pass a static string here */ -void dTimerNow (const char *description); /* pass a static string here */ -void dTimerEnd(void); - -/* print out a timer report. if `average' is nonzero, print out the average - * time for each slot (this is only meaningful if the same start-now-end - * calls are being made repeatedly. - */ -void dTimerReport (FILE *fout, int average); - - -/* resolution */ - -/* returns the timer ticks per second implied by the timing hardware or API. - * the actual timer resolution may not be this great. - */ -double dTimerTicksPerSecond(void); - -/* returns an estimate of the actual timer resolution, in seconds. this may - * be greater than 1/ticks_per_second. - */ -double dTimerResolution(void); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Extras/ode/ode/src/array.cpp b/Extras/ode/ode/src/array.cpp deleted file mode 100644 index cbb1a6ed5..000000000 --- a/Extras/ode/ode/src/array.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include -#include "array.h" - - -static inline int roundUpToPowerOfTwo (int x) -{ - int i = 1; - while (i < x) i <<= 1; - return i; -} - - -void dArrayBase::_freeAll (int sizeofT) -{ - if (_data) { - if (_data == this+1) return; // if constructLocalArray() was called - dFree (_data,_anum * sizeofT); - } -} - - -void dArrayBase::_setSize (int newsize, int sizeofT) -{ - if (newsize < 0) return; - if (newsize > _anum) { - if (_data == this+1) { - // this is a no-no, because constructLocalArray() was called - dDebug (0,"setSize() out of space in LOCAL array"); - } - int newanum = roundUpToPowerOfTwo (newsize); - if (_data) _data = dRealloc (_data, _anum*sizeofT, newanum*sizeofT); - else _data = dAlloc (newanum*sizeofT); - _anum = newanum; - } - _size = newsize; -} - - -void * dArrayBase::operator new (size_t size) -{ - return dAlloc (size); -} - - -void dArrayBase::operator delete (void *ptr, size_t size) -{ - dFree (ptr,size); -} - - -void dArrayBase::constructLocalArray (int __anum) -{ - _size = 0; - _anum = __anum; - _data = this+1; -} diff --git a/Extras/ode/ode/src/array.h b/Extras/ode/ode/src/array.h deleted file mode 100644 index 307206c37..000000000 --- a/Extras/ode/ode/src/array.h +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* this comes from the `reuse' library. copy any changes back to the source. - * - * Variable sized array template. The array is always stored in a contiguous - * chunk. The array can be resized. A size increase will cause more memory - * to be allocated, and may result in relocation of the array memory. - * A size decrease has no effect on the memory allocation. - * - * Array elements with constructors or destructors are not supported! - * But if you must have such elements, here's what to know/do: - * - Bitwise copy is used when copying whole arrays. - * - When copying individual items (via push(), insert() etc) the `=' - * (equals) operator is used. Thus you should define this operator to do - * a bitwise copy. You should probably also define the copy constructor. - */ - - -#ifndef _ODE_ARRAY_H_ -#define _ODE_ARRAY_H_ - -#include - - -// this base class has no constructors or destructor, for your convenience. - -class dArrayBase { -protected: - int _size; // number of elements in `data' - int _anum; // allocated number of elements in `data' - void *_data; // array data - - void _freeAll (int sizeofT); - void _setSize (int newsize, int sizeofT); - // set the array size to `newsize', allocating more memory if necessary. - // if newsize>_anum and is a power of two then this is guaranteed to - // set _size and _anum to newsize. - -public: - // not: dArrayBase () { _size=0; _anum=0; _data=0; } - - int size() const { return _size; } - int allocatedSize() const { return _anum; } - void * operator new (size_t size); - void operator delete (void *ptr, size_t size); - - void constructor() { _size=0; _anum=0; _data=0; } - // if this structure is allocated with malloc() instead of new, you can - // call this to set it up. - - void constructLocalArray (int __anum); - // this helper function allows non-reallocating arrays to be constructed - // on the stack (or in the heap if necessary). this is something of a - // kludge and should be used with extreme care. this function acts like - // a constructor - it is called on uninitialized memory that will hold the - // Array structure and the data. __anum is the number of elements that - // are allocated. the memory MUST be allocated with size: - // sizeof(ArrayBase) + __anum*sizeof(T) - // arrays allocated this way will never try to reallocate or free the - // memory - that's your job. -}; - - -template class dArray : public dArrayBase { -public: - void equals (const dArray &x) { - setSize (x.size()); - memcpy (_data,x._data,x._size * sizeof(T)); - } - - dArray () { constructor(); } - dArray (const dArray &x) { constructor(); equals (x); } - ~dArray () { _freeAll(sizeof(T)); } - void setSize (int newsize) { _setSize (newsize,sizeof(T)); } - T *data() const { return (T*) _data; } - T & operator[] (int i) const { return ((T*)_data)[i]; } - void operator = (const dArray &x) { equals (x); } - - void push (const T item) { - if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T)); - memcpy (&(((T*)_data)[_size-1]), &item, sizeof(T)); - } - - void swap (dArray &x) { - int tmp1; - void *tmp2; - tmp1=_size; _size=x._size; x._size=tmp1; - tmp1=_anum; _anum=x._anum; x._anum=tmp1; - tmp2=_data; _data=x._data; x._data=tmp2; - } - - // insert the item at the position `i'. if i<0 then add the item to the - // start, if i >= size then add the item to the end of the array. - void insert (int i, const T item) { - if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T)); - if (i >= (_size-1)) i = _size-1; // add to end - else { - if (i < 0) i=0; // add to start - int n = _size-1-i; - if (n>0) memmove (((T*)_data) + i+1, ((T*)_data) + i, n*sizeof(T)); - } - ((T*)_data)[i] = item; - } - - void remove (int i) { - if (i >= 0 && i < _size) { // passing this test guarantees size>0 - int n = _size-1-i; - if (n>0) memmove (((T*)_data) + i, ((T*)_data) + i+1, n*sizeof(T)); - _size--; - } - } -}; - - -#endif diff --git a/Extras/ode/ode/src/collision_convex.cpp b/Extras/ode/ode/src/collision_convex.cpp deleted file mode 100644 index 05e91255f..000000000 --- a/Extras/ode/ode/src/collision_convex.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// Convex collision detection (Bullet GJK) by Erwin Coumans, http://www.continuousphysics.com/Bullet/ -// -// Convex Integration is work in progress, so most users can ignore this file! -// Report suggestions/bugs in Bullet forum: -// http://www.continuousphysics.com/Bullet/phpBB2/ -// - -#ifdef BULLET_CONVEX_SUPPORT - -#include "collision_convex_internal.h" -#include -#include "BulletOdeTransformConvert.h" -#include "BulletOdeCollide.h" - -//**************************************************************************** -// convex object public API - -int dCollideConvexConvex(dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - - contact->g1 = o1; - contact->g2 = o2; - - return BulletOdeCollide(o1,o2,contact,flags & NUMC_MASK,skip); -} - -dxConvex::dxConvex (dSpaceID space, class CollisionShape* shape) : dxGeom (space,1) -{ - type = dConvexClass; - m_bulletCollisionShape = shape; -} - - -void GetAabbFromConvex(dGeomID geom,dVector3 halfExtents,dVector3 aabbCenter) -{ - - CollisionShape* shape = GetCollisionShapeFromConvex(geom); - SimdVector3 aabbMin,aabbMax; - - SimdTransform tr; - tr.setIdentity(); - - shape->GetAabb(tr,aabbMin,aabbMax); - SimdVector3 aabbHalfExtents = (aabbMax-aabbMin)*0.5f; - SimdVector3 center = (aabbMax+aabbMin)*0.5f; - - halfExtents[0] = aabbHalfExtents[0]; - halfExtents[1] = aabbHalfExtents[1]; - halfExtents[2] = aabbHalfExtents[2]; - - aabbCenter[0] = center [0]; - aabbCenter[1] = center [1]; - aabbCenter[2] = center [2]; - -} - - -void dxConvex::computeAABB() -{ - dReal xrange = 1e30; - dReal yrange = 1e30f; - dReal zrange = 1e30f; - CollisionShape* shape = GetCollisionShapeFromConvex(this); - - SimdVector3 aabbMin,aabbMax; - SimdTransform tr = GetTransformFromGeom(this); - shape->GetAabb(tr,aabbMin,aabbMax); - - aabb[0] = aabbMin[0]; - aabb[1] = aabbMax[0]; - aabb[2] = aabbMin[1]; - aabb[3] = aabbMax[1]; - aabb[4] = aabbMin[2]; - aabb[5] = aabbMax[2]; -} - -void dGeomConvexGetLengths(dGeomID convex, dVector3 result) -{ - dUASSERT (convex && convex->type == dConvexClass,"argument not a convex"); - dxConvex* cnvx = (dxConvex*) convex; - - dVector3 center; - GetAabbFromConvex(convex,result,center); - result[0]*=2.f; - result[1]*=2.f; - result[2]*=2.f; - -} - - - -dGeomID dCreateConvex(dSpaceID space, class CollisionShape* shape) -{ - return new dxConvex(space,shape); -} - - -#endif //BULLET_CONVEX_SUPPORT diff --git a/Extras/ode/ode/src/collision_convex_internal.h b/Extras/ode/ode/src/collision_convex_internal.h deleted file mode 100644 index 1a72ca55e..000000000 --- a/Extras/ode/ode/src/collision_convex_internal.h +++ /dev/null @@ -1,48 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// Convex (Bullet) GJK code by Erwin Coumans, http://www.continuousphysics.com/Bullet/ - -#ifndef COLLISION_CONVEX_INTERNAL_H -#define COLLISION_CONVEX_INTERNAL_H - - -#include -#include -#include -#include -#include "collision_util.h" -#include "collision_kernel.h" - -//Bullet class -class CollisionShape; - -/// General Convex shape support using Bullet GJK -struct dxConvex : public dxGeom { - class CollisionShape* m_bulletCollisionShape; - dxConvex (dSpaceID space, class CollisionShape* shape); - void computeAABB(); -}; - -void GetAabbFromConvex(dGeomID geom,dVector3 halfExtents,dVector3 aabbCenter); - -#endif //COLLISION_CONVEX_INTERNAL_H diff --git a/Extras/ode/ode/src/collision_kernel.cpp b/Extras/ode/ode/src/collision_kernel.cpp deleted file mode 100644 index b746dfe85..000000000 --- a/Extras/ode/ode/src/collision_kernel.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -core collision functions and data structures, plus part of the public API -for geometry objects - -*/ - -#include -#include -#include -#include -#include "collision_kernel.h" -#include "collision_util.h" -#include "collision_std.h" -#include "collision_transform.h" -#include "collision_trimesh_internal.h" - -#ifdef _MSC_VER -#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" -#endif - -//**************************************************************************** -// helper functions for dCollide()ing a space with another geom - -// this struct records the parameters passed to dCollideSpaceGeom() - -struct SpaceGeomColliderData { - int flags; // space left in contacts array - dContactGeom *contact; - int skip; -}; - - -static void space_geom_collider (void *data, dxGeom *o1, dxGeom *o2) -{ - SpaceGeomColliderData *d = (SpaceGeomColliderData*) data; - if (d->flags & NUMC_MASK) { - int n = dCollide (o1,o2,d->flags,d->contact,d->skip); - d->contact = CONTACT (d->contact,d->skip*n); - d->flags -= n; - } -} - - -static int dCollideSpaceGeom (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - SpaceGeomColliderData data; - data.flags = flags; - data.contact = contact; - data.skip = skip; - dSpaceCollide2 (o1,o2,&data,&space_geom_collider); - return (flags & NUMC_MASK) - (data.flags & NUMC_MASK); -} - -//**************************************************************************** -// dispatcher for the N^2 collider functions - -// function pointers and modes for n^2 class collider functions - -struct dColliderEntry { - dColliderFn *fn; // collider function, 0 = no function available - int reverse; // 1 = reverse o1 and o2 -}; -static dColliderEntry colliders[dGeomNumClasses][dGeomNumClasses]; -static int colliders_initialized = 0; - - -// setCollider() will refuse to write over a collider entry once it has -// been written. - -void setCollider (int i, int j, dColliderFn *fn) -{ - if (colliders[i][j].fn == 0) { - colliders[i][j].fn = fn; - colliders[i][j].reverse = 0; - } - if (colliders[j][i].fn == 0) { - colliders[j][i].fn = fn; - colliders[j][i].reverse = 1; - } -} - - -static void setAllColliders (int i, dColliderFn *fn) -{ - for (int j=0; jtype >= 0 && o1->type < dGeomNumClasses,"bad o1 class number"); - dUASSERT(o2->type >= 0 && o2->type < dGeomNumClasses,"bad o2 class number"); - - // no contacts if both geoms are the same - if (o1 == o2) return 0; - - // no contacts if both geoms on the same body, and the body is not 0 - if (o1->body == o2->body && o1->body) return 0; - - dColliderEntry *ce = &colliders[o1->type][o2->type]; - int count = 0; - if (ce->fn) { - if (ce->reverse) { - count = (*ce->fn) (o2,o1,flags,contact,skip); - for (int i=0; inormal[0] = -c->normal[0]; - c->normal[1] = -c->normal[1]; - c->normal[2] = -c->normal[2]; - dxGeom *tmp = c->g1; - c->g1 = c->g2; - c->g2 = tmp; - } - } - else { - count = (*ce->fn) (o1,o2,flags,contact,skip); - } - } - return count; -} - -//**************************************************************************** -// dxGeom - -dxGeom::dxGeom (dSpaceID _space, int is_placeable) -{ - initColliders(); - - // setup body vars. invalid type of -1 must be changed by the constructor. - type = -1; - gflags = GEOM_DIRTY | GEOM_AABB_BAD | GEOM_ENABLED; - if (is_placeable) gflags |= GEOM_PLACEABLE; - data = 0; - body = 0; - body_next = 0; - if (is_placeable) { - dxPosR *pr = (dxPosR*) dAlloc (sizeof(dxPosR)); - pos = pr->pos; - R = pr->R; - dSetZero (pos,4); - dRSetIdentity (R); - } - else { - pos = 0; - R = 0; - } - - // setup space vars - next = 0; - tome = 0; - parent_space = 0; - dSetZero (aabb,6); - category_bits = ~0; - collide_bits = ~0; - - // put this geom in a space if required - if (_space) dSpaceAdd (_space,this); -} - - -dxGeom::~dxGeom() -{ - if (parent_space) dSpaceRemove (parent_space,this); - if ((gflags & GEOM_PLACEABLE) && !body) dFree (pos,sizeof(dxPosR)); - bodyRemove(); -} - - -int dxGeom::AABBTest (dxGeom *o, dReal aabb[6]) -{ - return 1; -} - - -void dxGeom::bodyRemove() -{ - if (body) { - // delete this geom from body list - dxGeom **last = &body->geom, *g = body->geom; - while (g) { - if (g == this) { - *last = g->body_next; - break; - } - last = &g->body_next; - g = g->body_next; - } - body = 0; - body_next = 0; - } -} - -//**************************************************************************** -// misc - -dxGeom *dGeomGetBodyNext (dxGeom *geom) -{ - return geom->body_next; -} - -//**************************************************************************** -// public API for geometry objects - -#define CHECK_NOT_LOCKED(space) \ - dUASSERT (!(space && space->lock_count), \ - "invalid operation for geom in locked space"); - - -void dGeomDestroy (dxGeom *g) -{ - dAASSERT (g); - delete g; -} - - -void dGeomSetData (dxGeom *g, void *data) -{ - dAASSERT (g); - g->data = data; -} - - -void *dGeomGetData (dxGeom *g) -{ - dAASSERT (g); - return g->data; -} - - -void dGeomSetBody (dxGeom *g, dxBody *b) -{ - dAASSERT (g); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - CHECK_NOT_LOCKED (g->parent_space); - - if (b) { - if (!g->body) dFree (g->pos,sizeof(dxPosR)); - g->pos = b->pos; - g->R = b->R; - dGeomMoved (g); - if (g->body != b) { - g->bodyRemove(); - g->bodyAdd (b); - } - } - else { - if (g->body) { - dxPosR *pr = (dxPosR*) dAlloc (sizeof(dxPosR)); - g->pos = pr->pos; - g->R = pr->R; - memcpy (g->pos,g->body->pos,sizeof(dVector3)); - memcpy (g->R,g->body->R,sizeof(dMatrix3)); - g->bodyRemove(); - } - // dGeomMoved() should not be called if the body is being set to 0, as the - // new position of the geom is set to the old position of the body, so the - // effective position of the geom remains unchanged. - } -} - - -dBodyID dGeomGetBody (dxGeom *g) -{ - dAASSERT (g); - return g->body; -} - - -void dGeomSetPosition (dxGeom *g, dReal x, dReal y, dReal z) -{ - dAASSERT (g); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - CHECK_NOT_LOCKED (g->parent_space); - if (g->body) { - // this will call dGeomMoved (g), so we don't have to - dBodySetPosition (g->body,x,y,z); - } - else { - g->pos[0] = x; - g->pos[1] = y; - g->pos[2] = z; - dGeomMoved (g); - } -} - - -void dGeomSetRotation (dxGeom *g, const dMatrix3 R) -{ - dAASSERT (g && R); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - CHECK_NOT_LOCKED (g->parent_space); - if (g->body) { - // this will call dGeomMoved (g), so we don't have to - dBodySetRotation (g->body,R); - } - else { - memcpy (g->R,R,sizeof(dMatrix3)); - dGeomMoved (g); - } -} - - -void dGeomSetQuaternion (dxGeom *g, const dQuaternion quat) -{ - dAASSERT (g && quat); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - CHECK_NOT_LOCKED (g->parent_space); - if (g->body) { - // this will call dGeomMoved (g), so we don't have to - dBodySetQuaternion (g->body,quat); - } - else { - dQtoR (quat, g->R); - dGeomMoved (g); - } -} - - -const dReal * dGeomGetPosition (dxGeom *g) -{ - dAASSERT (g); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - return g->pos; -} - - -const dReal * dGeomGetRotation (dxGeom *g) -{ - dAASSERT (g); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - return g->R; -} - - -void dGeomGetQuaternion (dxGeom *g, dQuaternion quat) -{ - dAASSERT (g); - dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); - if (g->body) { - const dReal * body_quat = dBodyGetQuaternion (g->body); - quat[0] = body_quat[0]; - quat[1] = body_quat[1]; - quat[2] = body_quat[2]; - quat[3] = body_quat[3]; - } - else { - dRtoQ (g->R, quat); - } -} - - -void dGeomGetAABB (dxGeom *g, dReal aabb[6]) -{ - dAASSERT (g); - dAASSERT (aabb); - g->recomputeAABB(); - memcpy (aabb,g->aabb,6 * sizeof(dReal)); -} - - -int dGeomIsSpace (dxGeom *g) -{ - dAASSERT (g); - return IS_SPACE(g); -} - - -dSpaceID dGeomGetSpace (dxGeom *g) -{ - dAASSERT (g); - return g->parent_space; -} - - -int dGeomGetClass (dxGeom *g) -{ - dAASSERT (g); - return g->type; -} - - -void dGeomSetCategoryBits (dxGeom *g, unsigned long bits) -{ - dAASSERT (g); - CHECK_NOT_LOCKED (g->parent_space); - g->category_bits = bits; -} - - -void dGeomSetCollideBits (dxGeom *g, unsigned long bits) -{ - dAASSERT (g); - CHECK_NOT_LOCKED (g->parent_space); - g->collide_bits = bits; -} - - -unsigned long dGeomGetCategoryBits (dxGeom *g) -{ - dAASSERT (g); - return g->category_bits; -} - - -unsigned long dGeomGetCollideBits (dxGeom *g) -{ - dAASSERT (g); - return g->collide_bits; -} - - -void dGeomEnable (dxGeom *g) -{ - dAASSERT (g); - g->gflags |= GEOM_ENABLED; -} - -void dGeomDisable (dxGeom *g) -{ - dAASSERT (g); - g->gflags &= ~GEOM_ENABLED; -} - -int dGeomIsEnabled (dxGeom *g) -{ - dAASSERT (g); - return (g->gflags & GEOM_ENABLED) != 0; -} - - -//**************************************************************************** -// C interface that lets the user make new classes. this interface is a lot -// more cumbersome than C++ subclassing, which is what is used internally -// in ODE. this API is mainly to support legacy code. - -static int num_user_classes = 0; -static dGeomClass user_classes [dMaxUserClasses]; - - -struct dxUserGeom : public dxGeom { - void *user_data; - - dxUserGeom (int class_num); - ~dxUserGeom(); - void computeAABB(); - int AABBTest (dxGeom *o, dReal aabb[6]); -}; - - -dxUserGeom::dxUserGeom (int class_num) : dxGeom (0,1) -{ - type = class_num; - int size = user_classes[type-dFirstUserClass].bytes; - user_data = dAlloc (size); - memset (user_data,0,size); -} - - -dxUserGeom::~dxUserGeom() -{ - dGeomClass *c = &user_classes[type-dFirstUserClass]; - if (c->dtor) c->dtor (this); - dFree (user_data,c->bytes); -} - - -void dxUserGeom::computeAABB() -{ - user_classes[type-dFirstUserClass].aabb (this,aabb); -} - - -int dxUserGeom::AABBTest (dxGeom *o, dReal aabb[6]) -{ - dGeomClass *c = &user_classes[type-dFirstUserClass]; - if (c->aabb_test) return c->aabb_test (this,o,aabb); - else return 1; -} - - -static int dCollideUserGeomWithGeom (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - // this generic collider function is called the first time that a user class - // tries to collide against something. it will find out the correct collider - // function and then set the colliders array so that the correct function is - // called directly the next time around. - - int t1 = o1->type; // note that o1 is a user geom - int t2 = o2->type; // o2 *may* be a user geom - - // find the collider function to use. if o1 does not know how to collide with - // o2, then o2 might know how to collide with o1 (provided that it is a user - // geom). - dColliderFn *fn = user_classes[t1-dFirstUserClass].collider (t2); - int reverse = 0; - if (!fn && t2 >= dFirstUserClass && t2 <= dLastUserClass) { - fn = user_classes[t2-dFirstUserClass].collider (t1); - reverse = 1; - } - - // set the colliders array so that the correct function is called directly - // the next time around. note that fn can be 0 here if no collider was found, - // which means that dCollide() will always return 0 for this case. - colliders[t1][t2].fn = fn; - colliders[t1][t2].reverse = reverse; - colliders[t2][t1].fn = fn; - colliders[t2][t1].reverse = !reverse; - - // now call the collider function indirectly through dCollide(), so that - // contact reversing is properly handled. - return dCollide (o1,o2,flags,contact,skip); -} - - -int dCreateGeomClass (const dGeomClass *c) -{ - dUASSERT(c && c->bytes >= 0 && c->collider && c->aabb,"bad geom class"); - - if (num_user_classes >= dMaxUserClasses) { - dDebug (0,"too many user classes, you must increase the limit and " - "recompile ODE"); - } - user_classes[num_user_classes] = *c; - int class_number = num_user_classes + dFirstUserClass; - initColliders(); - setAllColliders (class_number,&dCollideUserGeomWithGeom); - - num_user_classes++; - return class_number; -} - - -void * dGeomGetClassData (dxGeom *g) -{ - dUASSERT (g && g->type >= dFirstUserClass && - g->type <= dLastUserClass,"not a custom class"); - dxUserGeom *user = (dxUserGeom*) g; - return user->user_data; -} - - -dGeomID dCreateGeom (int classnum) -{ - dUASSERT (classnum >= dFirstUserClass && - classnum <= dLastUserClass,"not a custom class"); - return new dxUserGeom (classnum); -} - -//**************************************************************************** -// here is where we deallocate any memory that has been globally -// allocated, or free other global resources. - -void dCloseODE() -{ - colliders_initialized = 0; - num_user_classes = 0; -} diff --git a/Extras/ode/ode/src/collision_kernel.h b/Extras/ode/ode/src/collision_kernel.h deleted file mode 100644 index 59c1ee615..000000000 --- a/Extras/ode/ode/src/collision_kernel.h +++ /dev/null @@ -1,203 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -internal data structures and functions for collision detection. - -*/ - -#ifndef _ODE_COLLISION_KERNEL_H_ -#define _ODE_COLLISION_KERNEL_H_ - -#include -#include -#include -#include "objects.h" - -//**************************************************************************** -// constants and macros - -// mask for the number-of-contacts field in the dCollide() flags parameter -#define NUMC_MASK (0xffff) - -#define IS_SPACE(geom) \ - ((geom)->type >= dFirstSpaceClass && (geom)->type <= dLastSpaceClass) - -//**************************************************************************** -// geometry object base class - -// position vector and rotation matrix for geometry objects that are not -// connected to bodies. - -struct dxPosR { - dVector3 pos; - dMatrix3 R; -}; - -void setCollider (int i, int j, dColliderFn *fn); - -// geom flags. -// -// GEOM_DIRTY means that the space data structures for this geom are -// potentially not up to date. NOTE THAT all space parents of a dirty geom -// are themselves dirty. this is an invariant that must be enforced. -// -// GEOM_AABB_BAD means that the cached AABB for this geom is not up to date. -// note that GEOM_DIRTY does not imply GEOM_AABB_BAD, as the geom might -// recalculate its own AABB but does not know how to update the space data -// structures for the space it is in. but GEOM_AABB_BAD implies GEOM_DIRTY. -// the valid combinations are: 0, GEOM_DIRTY, GEOM_DIRTY|GEOM_AABB_BAD. - -enum { - GEOM_DIRTY = 1, // geom is 'dirty', i.e. position unknown - GEOM_AABB_BAD = 2, // geom's AABB is not valid - GEOM_PLACEABLE = 4, // geom is placeable - GEOM_ENABLED = 8, // geom is enabled - - // Ray specific - RAY_FIRSTCONTACT = 0x10000, - RAY_BACKFACECULL = 0x20000, - RAY_CLOSEST_HIT = 0x40000 -}; - - -// geometry object base class. pos and R will either point to a separately -// allocated buffer (if body is 0 - pos points to the dxPosR object) or to -// the pos and R of the body (if body nonzero). -// a dGeomID is a pointer to this object. - -struct dxGeom : public dBase { - int type; // geom type number, set by subclass constructor - int gflags; // flags used by geom and space - void *data; // user-defined data pointer - dBodyID body; // dynamics body associated with this object (if any) - dxGeom *body_next; // next geom in body's linked list of associated geoms - dReal *pos; // pointer to object's position vector - dReal *R; // pointer to object's rotation matrix - - // information used by spaces - dxGeom *next; // next geom in linked list of geoms - dxGeom **tome; // linked list backpointer - dxSpace *parent_space;// the space this geom is contained in, 0 if none - dReal aabb[6]; // cached AABB for this space - unsigned long category_bits,collide_bits; - - dxGeom (dSpaceID _space, int is_placeable); - virtual ~dxGeom(); - - virtual void computeAABB()=0; - // compute the AABB for this object and put it in aabb. this function - // always performs a fresh computation, it does not inspect the - // GEOM_AABB_BAD flag. - - virtual int AABBTest (dxGeom *o, dReal aabb[6]); - // test whether the given AABB object intersects with this object, return - // 1=yes, 0=no. this is used as an early-exit test in the space collision - // functions. the default implementation returns 1, which is the correct - // behavior if no more detailed implementation can be provided. - - // utility functions - - // compute the AABB only if it is not current. this function manipulates - // the GEOM_AABB_BAD flag. - - void recomputeAABB() { - if (gflags & GEOM_AABB_BAD) { - computeAABB(); - gflags &= ~GEOM_AABB_BAD; - } - } - - // add and remove this geom from a linked list maintained by a space. - - void spaceAdd (dxGeom **first_ptr) { - next = *first_ptr; - tome = first_ptr; - if (*first_ptr) (*first_ptr)->tome = &next; - *first_ptr = this; - } - void spaceRemove() { - if (next) next->tome = tome; - *tome = next; - } - - // add and remove this geom from a linked list maintained by a body. - - void bodyAdd (dxBody *b) { - body = b; - body_next = b->geom; - b->geom = this; - } - void bodyRemove(); -}; - -//**************************************************************************** -// the base space class -// -// the contained geoms are divided into two kinds: clean and dirty. -// the clean geoms have not moved since they were put in the list, -// and their AABBs are valid. the dirty geoms have changed position, and -// their AABBs are may not be valid. the two types are distinguished by the -// GEOM_DIRTY flag. all dirty geoms come *before* all clean geoms in the list. - -struct dxSpace : public dxGeom { - int count; // number of geoms in this space - dxGeom *first; // first geom in list - int cleanup; // cleanup mode, 1=destroy geoms on exit - - // cached state for getGeom() - int current_index; // only valid if current_geom != 0 - dxGeom *current_geom; // if 0 then there is no information - - // locking stuff. the space is locked when it is currently traversing its - // internal data structures, e.g. in collide() and collide2(). operations - // that modify the contents of the space are not permitted when the space - // is locked. - int lock_count; - - dxSpace (dSpaceID _space); - ~dxSpace(); - - void computeAABB(); - - void setCleanup (int mode); - int getCleanup(); - int query (dxGeom *geom); - int getNumGeoms(); - virtual dxGeom *getGeom (int i); - - virtual void add (dxGeom *); - virtual void remove (dxGeom *); - virtual void dirty (dxGeom *); - - virtual void cleanGeoms()=0; - // turn all dirty geoms into clean geoms by computing their AABBs and any - // other space data structures that are required. this should clear the - // GEOM_DIRTY and GEOM_AABB_BAD flags of all geoms. - - virtual void collide (void *data, dNearCallback *callback)=0; - virtual void collide2 (void *data, dxGeom *geom, dNearCallback *callback)=0; -}; - - -#endif diff --git a/Extras/ode/ode/src/collision_quadtreespace.cpp b/Extras/ode/ode/src/collision_quadtreespace.cpp deleted file mode 100644 index 6f4a86ee2..000000000 --- a/Extras/ode/ode/src/collision_quadtreespace.cpp +++ /dev/null @@ -1,583 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// QuadTreeSpace by Erwin de Vries. - -#include -#include -#include -#include -#include "collision_kernel.h" - -#include "collision_space_internal.h" - - -#define AXIS0 0 -#define AXIS1 1 -#define UP 2 - -//#define DRAWBLOCKS - -const int SPLITAXIS = 2; -const int SPLITS = SPLITAXIS * SPLITAXIS; - -#define GEOM_ENABLED(g) (g)->gflags & GEOM_ENABLED - -class Block{ -public: - dReal MinX, MaxX; - dReal MinZ, MaxZ; - - dGeomID First; - int GeomCount; - - Block* Parent; - Block* Children; - - void Create(const dVector3 Center, const dVector3 Extents, Block* Parent, int Depth, Block*& Blocks); - - void Collide(void* UserData, dNearCallback* Callback); - void Collide(dGeomID Object, dGeomID g, void* UserData, dNearCallback* Callback); - - void CollideLocal(dGeomID Object, void* UserData, dNearCallback* Callback); - - void AddObject(dGeomID Object); - void DelObject(dGeomID Object); - void Traverse(dGeomID Object); - - bool Inside(const dReal* AABB); - - Block* GetBlock(const dReal* AABB); - Block* GetBlockChild(const dReal* AABB); -}; - - -#ifdef DRAWBLOCKS -#include "..\..\Include\drawstuff\\drawstuff.h" - -static void DrawBlock(Block* Block){ - dVector3 v[8]; - v[0][AXIS0] = Block->MinX; - v[0][UP] = REAL(-1.0); - v[0][AXIS1] = Block->MinZ; - - v[1][AXIS0] = Block->MinX; - v[1][UP] = REAL(-1.0); - v[1][AXIS1] = Block->MaxZ; - - v[2][AXIS0] = Block->MaxX; - v[2][UP] = REAL(-1.0); - v[2][AXIS1] = Block->MinZ; - - v[3][AXIS0] = Block->MaxX; - v[3][UP] = REAL(-1.0); - v[3][AXIS1] = Block->MaxZ; - - v[4][AXIS0] = Block->MinX; - v[4][UP] = REAL(1.0); - v[4][AXIS1] = Block->MinZ; - - v[5][AXIS0] = Block->MinX; - v[5][UP] = REAL(1.0); - v[5][AXIS1] = Block->MaxZ; - - v[6][AXIS0] = Block->MaxX; - v[6][UP] = REAL(1.0); - v[6][AXIS1] = Block->MinZ; - - v[7][AXIS0] = Block->MaxX; - v[7][UP] = REAL(1.0); - v[7][AXIS1] = Block->MaxZ; - - // Bottom - dsDrawLine(v[0], v[1]); - dsDrawLine(v[1], v[3]); - dsDrawLine(v[3], v[2]); - dsDrawLine(v[2], v[0]); - - // Top - dsDrawLine(v[4], v[5]); - dsDrawLine(v[5], v[7]); - dsDrawLine(v[7], v[6]); - dsDrawLine(v[6], v[4]); - - // Sides - dsDrawLine(v[0], v[4]); - dsDrawLine(v[1], v[5]); - dsDrawLine(v[2], v[6]); - dsDrawLine(v[3], v[7]); -} -#endif //DRAWBLOCKS - - -void Block::Create(const dVector3 Center, const dVector3 Extents, Block* Parent, int Depth, Block*& Blocks){ - GeomCount = 0; - First = 0; - - MinX = Center[AXIS0] - Extents[AXIS0]; - MaxX = Center[AXIS0] + Extents[AXIS0]; - - MinZ = Center[AXIS1] - Extents[AXIS1]; - MaxZ = Center[AXIS1] + Extents[AXIS1]; - - this->Parent = Parent; - if (Depth > 0){ - Children = Blocks; - Blocks += SPLITS; - - dVector3 ChildExtents; - ChildExtents[AXIS0] = Extents[AXIS0] / SPLITAXIS; - ChildExtents[AXIS1] = Extents[AXIS1] / SPLITAXIS; - ChildExtents[UP] = Extents[UP]; - - for (int i = 0; i < SPLITAXIS; i++){ - for (int j = 0; j < SPLITAXIS; j++){ - int Index = i * SPLITAXIS + j; - - dVector3 ChildCenter; - ChildCenter[AXIS0] = Center[AXIS0] - Extents[AXIS0] + ChildExtents[AXIS0] + i * (ChildExtents[AXIS0] * 2); - ChildCenter[AXIS1] = Center[AXIS1] - Extents[AXIS1] + ChildExtents[AXIS1] + j * (ChildExtents[AXIS1] * 2); - ChildCenter[UP] = Center[UP]; - - Children[Index].Create(ChildCenter, ChildExtents, this, Depth - 1, Blocks); - } - } - } - else Children = 0; -} - -void Block::Collide(void* UserData, dNearCallback* Callback){ -#ifdef DRAWBLOCKS - DrawBlock(this); -#endif - // Collide the local list - dxGeom* g = First; - while (g){ - if (GEOM_ENABLED(g)){ - Collide(g, g->next, UserData, Callback); - } - g = g->next; - } - - // Recurse for children - if (Children){ - for (int i = 0; i < SPLITS; i++){ - if (Children[i].GeomCount <= 1){ // Early out - continue; - } - Children[i].Collide(UserData, Callback); - } - } -} - -void Block::Collide(dxGeom* g1, dxGeom* g2, void* UserData, dNearCallback* Callback){ -#ifdef DRAWBLOCKS - DrawBlock(this); -#endif - // Collide against local list - while (g2){ - if (GEOM_ENABLED(g2)){ - collideAABBs (g1, g2, UserData, Callback); - } - g2 = g2->next; - } - - // Collide against children - if (Children){ - for (int i = 0; i < SPLITS; i++){ - // Early out for empty blocks - if (Children[i].GeomCount == 0){ - continue; - } - - // Does the geom's AABB collide with the block? - // Dont do AABB tests for single geom blocks. - if (Children[i].GeomCount == 1 && Children[i].First){ - // - } - else if (true){ - if (g1->aabb[AXIS0 * 2 + 0] > Children[i].MaxX || - g1->aabb[AXIS0 * 2 + 1] < Children[i].MinX || - g1->aabb[AXIS1 * 2 + 0] > Children[i].MaxZ || - g1->aabb[AXIS1 * 2 + 1] < Children[i].MinZ) continue; - } - Children[i].Collide(g1, Children[i].First, UserData, Callback); - } - } -} - -void Block::CollideLocal(dxGeom* g1, void* UserData, dNearCallback* Callback){ - // Collide against local list - dxGeom* g2 = First; - while (g2){ - if (GEOM_ENABLED(g2)){ - collideAABBs (g1, g2, UserData, Callback); - } - g2 = g2->next; - } -} - -void Block::AddObject(dGeomID Object){ - // Add the geom - Object->next = First; - First = Object; - Object->tome = (dxGeom**)this; - - // Now traverse upwards to tell that we have a geom - Block* Block = this; - do{ - Block->GeomCount++; - Block = Block->Parent; - } - while (Block); -} - -void Block::DelObject(dGeomID Object){ - // Del the geom - dxGeom* g = First; - dxGeom* Last = 0; - while (g){ - if (g == Object){ - if (Last){ - Last->next = g->next; - } - else First = g->next; - - break; - } - Last = g; - g = g->next; - } - - Object->tome = 0; - - // Now traverse upwards to tell that we have lost a geom - Block* Block = this; - do{ - Block->GeomCount--; - Block = Block->Parent; - } - while (Block); -} - -void Block::Traverse(dGeomID Object){ - Block* NewBlock = GetBlock(Object->aabb); - - if (NewBlock != this){ - // Remove the geom from the old block and add it to the new block. - // This could be more optimal, but the loss should be very small. - DelObject(Object); - NewBlock->AddObject(Object); - } -} - -bool Block::Inside(const dReal* AABB){ - return AABB[AXIS0 * 2 + 0] >= MinX && AABB[AXIS0 * 2 + 1] <= MaxX && AABB[AXIS1 * 2 + 0] >= MinZ && AABB[AXIS1 * 2 + 1] <= MaxZ; -} - -Block* Block::GetBlock(const dReal* AABB){ - if (Inside(AABB)){ - return GetBlockChild(AABB); // Child or this will have a good block - } - else if (Parent){ - return Parent->GetBlock(AABB); // Parent has a good block - } - else return this; // We are at the root, so we have little choice -} - -Block* Block::GetBlockChild(const dReal* AABB){ - if (Children){ - for (int i = 0; i < SPLITS; i++){ - if (Children[i].Inside(AABB)){ - return Children[i].GetBlockChild(AABB); // Child will have good block - } - } - } - return this; // This is the best block -} - -//**************************************************************************** -// quadtree space - -struct dxQuadTreeSpace : public dxSpace{ - Block* Blocks; // Blocks[0] is the root - - dArray DirtyList; - - dxQuadTreeSpace(dSpaceID _space, dVector3 Center, dVector3 Extents, int Depth); - ~dxQuadTreeSpace(); - - dxGeom* getGeom(int i); - - void add(dxGeom* g); - void remove(dxGeom* g); - void dirty(dxGeom* g); - - void computeAABB(); - - void cleanGeoms(); - void collide(void* UserData, dNearCallback* Callback); - void collide2(void* UserData, dxGeom* g1, dNearCallback* Callback); - - // Temp data - Block* CurrentBlock; // Only used while enumerating - int* CurrentChild; // Only used while enumerating - int CurrentLevel; // Only used while enumerating - dxGeom* CurrentObject; // Only used while enumerating - int CurrentIndex; -}; - -dxQuadTreeSpace::dxQuadTreeSpace(dSpaceID _space, dVector3 Center, dVector3 Extents, int Depth) : dxSpace(_space){ - type = dQuadTreeSpaceClass; - - int BlockCount = 0; - for (int i = 0; i <= Depth; i++){ - BlockCount += (int)powf(SPLITS, i); - } - - Blocks = (Block*)dAlloc(BlockCount * sizeof(Block)); - Block* Blocks = this->Blocks + 1; // This pointer gets modified! - - this->Blocks[0].Create(Center, Extents, 0, Depth, Blocks); - - CurrentBlock = 0; - CurrentChild = (int*)dAlloc((Depth + 1) * sizeof(int)); - CurrentLevel = 0; - CurrentObject = 0; - CurrentIndex = -1; - - // Init AABB. We initialize to infinity because it is not illegal for an object to be outside of the tree. Its simply inserted in the root block - aabb[0] = -dInfinity; - aabb[1] = dInfinity; - aabb[2] = -dInfinity; - aabb[3] = dInfinity; - aabb[4] = -dInfinity; - aabb[5] = dInfinity; -} - -dxQuadTreeSpace::~dxQuadTreeSpace(){ - int Depth = 0; - Block* Current = &Blocks[0]; - while (Current){ - Depth++; - Current = Current->Children; - } - - int BlockCount = 0; - for (int i = 0; i < Depth; i++){ - BlockCount += (int)powf(SPLITS, i); - } - - dFree(Blocks, BlockCount * sizeof(Block)); - dFree(CurrentChild, (Depth + 1) * sizeof(int)); -} - -dxGeom* dxQuadTreeSpace::getGeom(int Index){ - dUASSERT(Index >= 0 && Index < count, "index out of range"); - - //@@@ - dDebug (0,"dxQuadTreeSpace::getGeom() not yet implemented"); - - return 0; - - // This doesnt work - - /*if (CurrentIndex == Index){ - // Loop through all objects in the local list -CHILDRECURSE: - if (CurrentObject){ - dGeomID g = CurrentObject; - CurrentObject = CurrentObject->next; - CurrentIndex++; - -#ifdef DRAWBLOCKS - DrawBlock(CurrentBlock); -#endif //DRAWBLOCKS - return g; - } - else{ - // Now lets loop through our children. Starting at index 0. - if (CurrentBlock->Children){ - CurrentChild[CurrentLevel] = 0; -PARENTRECURSE: - for (int& i = CurrentChild[CurrentLevel]; i < SPLITS; i++){ - if (CurrentBlock->Children[i].GeomCount == 0){ - continue; - } - CurrentBlock = &CurrentBlock->Children[i]; - CurrentObject = CurrentBlock->First; - - i++; - - CurrentLevel++; - goto CHILDRECURSE; - } - } - } - - // Now lets go back to the parent so it can continue processing its other children. - if (CurrentBlock->Parent){ - CurrentBlock = CurrentBlock->Parent; - CurrentLevel--; - goto PARENTRECURSE; - } - } - else{ - CurrentBlock = &Blocks[0]; - CurrentLevel = 0; - CurrentObject = CurrentObject; - CurrentIndex = 0; - - // Other states are already set - CurrentObject = CurrentBlock->First; - } - - - if (current_geom && current_index == Index - 1){ - //current_geom = current_geom->next; // next - current_index = Index; - return current_geom; - } - else for (int i = 0; i < Index; i++){ // this will be verrrrrrry slow - getGeom(i); - }*/ - - return 0; -} - -void dxQuadTreeSpace::add(dxGeom* g){ - CHECK_NOT_LOCKED (this); - dAASSERT(g); - dUASSERT(g->parent_space == 0 && g->next == 0, "geom is already in a space"); - - g->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; - DirtyList.push(g); - - // add - g->parent_space = this; - Blocks[0].GetBlock(g->aabb)->AddObject(g); // Add to best block - count++; - - // enumerator has been invalidated - current_geom = 0; - - dGeomMoved(this); -} - -void dxQuadTreeSpace::remove(dxGeom* g){ - CHECK_NOT_LOCKED(this); - dAASSERT(g); - dUASSERT(g->parent_space == this,"object is not in this space"); - - // remove - ((Block*)g->tome)->DelObject(g); - count--; - - for (int i = 0; i < DirtyList.size(); i++){ - if (DirtyList[i] == g){ - DirtyList.remove(i); - break; - } - } - - // safeguard - g->next = 0; - g->tome = 0; - g->parent_space = 0; - - // enumerator has been invalidated - current_geom = 0; - - // the bounding box of this space (and that of all the parents) may have - // changed as a consequence of the removal. - dGeomMoved(this); -} - -void dxQuadTreeSpace::dirty(dxGeom* g){ - DirtyList.push(g); -} - -void dxQuadTreeSpace::computeAABB(){ - // -} - -void dxQuadTreeSpace::cleanGeoms(){ - // compute the AABBs of all dirty geoms, and clear the dirty flags - lock_count++; - - for (int i = 0; i < DirtyList.size(); i++){ - dxGeom* g = DirtyList[i]; - if (IS_SPACE(g)){ - ((dxSpace*)g)->cleanGeoms(); - } - g->recomputeAABB(); - g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); - - ((Block*)g->tome)->Traverse(g); - } - DirtyList.setSize(0); - - lock_count--; -} - -void dxQuadTreeSpace::collide(void* UserData, dNearCallback* Callback){ - dAASSERT(Callback); - - lock_count++; - cleanGeoms(); - - Blocks[0].Collide(UserData, Callback); - - lock_count--; -} - -void dxQuadTreeSpace::collide2(void* UserData, dxGeom* g1, dNearCallback* Callback){ - dAASSERT(g1 && Callback); - - lock_count++; - cleanGeoms(); - g1->recomputeAABB(); - - if (g1->parent_space == this){ - // The block the geom is in - Block* CurrentBlock = (Block*)g1->tome; - - // Collide against block and its children - CurrentBlock->Collide(g1, CurrentBlock->First, UserData, Callback); - - // Collide against parents - while (true){ - CurrentBlock = CurrentBlock->Parent; - if (!CurrentBlock){ - break; - } - CurrentBlock->CollideLocal(g1, UserData, Callback); - } - } - else Blocks[0].Collide(g1, Blocks[0].First, UserData, Callback); - - lock_count--; -} - -dSpaceID dQuadTreeSpaceCreate(dxSpace* space, dVector3 Center, dVector3 Extents, int Depth){ - return new dxQuadTreeSpace(space, Center, Extents, Depth); -} diff --git a/Extras/ode/ode/src/collision_space.cpp b/Extras/ode/ode/src/collision_space.cpp deleted file mode 100644 index 29edfaf09..000000000 --- a/Extras/ode/ode/src/collision_space.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -spaces - -*/ - -#include -#include -#include -#include -#include "collision_kernel.h" - -#include "collision_space_internal.h" - -#ifdef _MSC_VER -#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" -#endif - -//**************************************************************************** -// make the geom dirty by setting the GEOM_DIRTY and GEOM_BAD_AABB flags -// and moving it to the front of the space's list. all the parents of a -// dirty geom also become dirty. - -void dGeomMoved (dxGeom *geom) -{ - dAASSERT (geom); - - // from the bottom of the space heirarchy up, process all clean geoms - // turning them into dirty geoms. - dxSpace *parent = geom->parent_space; - - while (parent && (geom->gflags & GEOM_DIRTY)==0) { - CHECK_NOT_LOCKED (parent); - geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; - parent->dirty (geom); - geom = parent; - parent = parent->parent_space; - } - - // all the remaining dirty geoms must have their AABB_BAD flags set, to - // ensure that their AABBs get recomputed - while (geom) { - geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; - CHECK_NOT_LOCKED (geom->parent_space); - geom = geom->parent_space; - } -} - -#define GEOM_ENABLED(g) ((g)->gflags & GEOM_ENABLED) - -//**************************************************************************** -// dxSpace - -dxSpace::dxSpace (dSpaceID _space) : dxGeom (_space,0) -{ - count = 0; - first = 0; - cleanup = 1; - current_index = 0; - current_geom = 0; - lock_count = 0; -} - - -dxSpace::~dxSpace() -{ - CHECK_NOT_LOCKED (this); - if (cleanup) { - // note that destroying each geom will call remove() - dxGeom *g,*n; - for (g = first; g; g=n) { - n = g->next; - dGeomDestroy (g); - } - } - else { - dxGeom *g,*n; - for (g = first; g; g=n) { - n = g->next; - remove (g); - } - } -} - - -void dxSpace::computeAABB() -{ - if (first) { - int i; - dReal a[6]; - a[0] = dInfinity; - a[1] = -dInfinity; - a[2] = dInfinity; - a[3] = -dInfinity; - a[4] = dInfinity; - a[5] = -dInfinity; - for (dxGeom *g=first; g; g=g->next) { - g->recomputeAABB(); - for (i=0; i<6; i += 2) if (g->aabb[i] < a[i]) a[i] = g->aabb[i]; - for (i=1; i<6; i += 2) if (g->aabb[i] > a[i]) a[i] = g->aabb[i]; - } - memcpy(aabb,a,6*sizeof(dReal)); - } - else { - dSetZero (aabb,6); - } -} - - -void dxSpace::setCleanup (int mode) -{ - cleanup = (mode != 0); -} - - -int dxSpace::getCleanup() -{ - return cleanup; -} - - -int dxSpace::query (dxGeom *geom) -{ - dAASSERT (geom); - return (geom->parent_space == this); -} - - -int dxSpace::getNumGeoms() -{ - return count; -} - - -// the dirty geoms are numbered 0..k, the clean geoms are numbered k+1..count-1 - -dxGeom *dxSpace::getGeom (int i) -{ - dUASSERT (i >= 0 && i < count,"index out of range"); - if (current_geom && current_index == i-1) { - current_geom = current_geom->next; - current_index = i; - return current_geom; - } - else { - dxGeom *g=first; - for (int j=0; jnext; else return 0; - } - current_geom = g; - current_index = i; - return g; - } -} - - -void dxSpace::add (dxGeom *geom) -{ - CHECK_NOT_LOCKED (this); - dAASSERT (geom); - dUASSERT (geom->parent_space == 0 && geom->next == 0, - "geom is already in a space"); - - // add - geom->parent_space = this; - geom->spaceAdd (&first); - count++; - - // enumerator has been invalidated - current_geom = 0; - - // new geoms are added to the front of the list and are always - // considered to be dirty. as a consequence, this space and all its - // parents are dirty too. - geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; - dGeomMoved (this); -} - - -void dxSpace::remove (dxGeom *geom) -{ - CHECK_NOT_LOCKED (this); - dAASSERT (geom); - dUASSERT (geom->parent_space == this,"object is not in this space"); - - // remove - geom->spaceRemove(); - count--; - - // safeguard - geom->next = 0; - geom->tome = 0; - geom->parent_space = 0; - - // enumerator has been invalidated - current_geom = 0; - - // the bounding box of this space (and that of all the parents) may have - // changed as a consequence of the removal. - dGeomMoved (this); -} - - -void dxSpace::dirty (dxGeom *geom) -{ - geom->spaceRemove(); - geom->spaceAdd (&first); -} - -//**************************************************************************** -// simple space - reports all n^2 object intersections - -struct dxSimpleSpace : public dxSpace { - dxSimpleSpace (dSpaceID _space); - void cleanGeoms(); - void collide (void *data, dNearCallback *callback); - void collide2 (void *data, dxGeom *geom, dNearCallback *callback); -}; - - -dxSimpleSpace::dxSimpleSpace (dSpaceID _space) : dxSpace (_space) -{ - type = dSimpleSpaceClass; -} - - -void dxSimpleSpace::cleanGeoms() -{ - // compute the AABBs of all dirty geoms, and clear the dirty flags - lock_count++; - for (dxGeom *g=first; g && (g->gflags & GEOM_DIRTY); g=g->next) { - if (IS_SPACE(g)) { - ((dxSpace*)g)->cleanGeoms(); - } - g->recomputeAABB(); - g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); - } - lock_count--; -} - - -void dxSimpleSpace::collide (void *data, dNearCallback *callback) -{ - dAASSERT (callback); - - lock_count++; - cleanGeoms(); - - // intersect all bounding boxes - for (dxGeom *g1=first; g1; g1=g1->next) { - if (GEOM_ENABLED(g1)){ - for (dxGeom *g2=g1->next; g2; g2=g2->next) { - if (GEOM_ENABLED(g2)){ - collideAABBs (g1,g2,data,callback); - } - } - } - } - - lock_count--; -} - - -void dxSimpleSpace::collide2 (void *data, dxGeom *geom, - dNearCallback *callback) -{ - dAASSERT (geom && callback); - - lock_count++; - cleanGeoms(); - geom->recomputeAABB(); - - // intersect bounding boxes - for (dxGeom *g=first; g; g=g->next) { - if (GEOM_ENABLED(g)){ - collideAABBs (g,geom,data,callback); - } - } - - lock_count--; -} - -//**************************************************************************** -// utility stuff for hash table space - -// kind of silly, but oh well... -#ifndef MAXINT -#define MAXINT ((int)((((unsigned int)(-1)) << 1) >> 1)) -#endif - - -// prime[i] is the largest prime smaller than 2^i -#define NUM_PRIMES 31 -static long int prime[NUM_PRIMES] = {1L,2L,3L,7L,13L,31L,61L,127L,251L,509L, - 1021L,2039L,4093L,8191L,16381L,32749L,65521L,131071L,262139L, - 524287L,1048573L,2097143L,4194301L,8388593L,16777213L,33554393L, - 67108859L,134217689L,268435399L,536870909L,1073741789L}; - - -// an axis aligned bounding box in the hash table -struct dxAABB { - dxAABB *next; // next in the list of all AABBs - int level; // the level this is stored in (cell size = 2^level) - int dbounds[6]; // AABB bounds, discretized to cell size - dxGeom *geom; // corresponding geometry object (AABB stored here) - int index; // index of this AABB, starting from 0 -}; - - -// a hash table node that represents an AABB that intersects a particular cell -// at a particular level -struct Node { - Node *next; // next node in hash table collision list, 0 if none - int x,y,z; // cell position in space, discretized to cell size - dxAABB *aabb; // axis aligned bounding box that intersects this cell -}; - - -// return the `level' of an AABB. the AABB will be put into cells at this -// level - the cell size will be 2^level. the level is chosen to be the -// smallest value such that the AABB occupies no more than 8 cells, regardless -// of its placement. this means that: -// size/2 < q <= size -// where q is the maximum AABB dimension. - -static int findLevel (dReal bounds[6]) -{ - if (bounds[0] <= -dInfinity || bounds[1] >= dInfinity || - bounds[2] <= -dInfinity || bounds[3] >= dInfinity || - bounds[4] <= -dInfinity || bounds[5] >= dInfinity) { - return MAXINT; - } - - // compute q - dReal q,q2; - q = bounds[1] - bounds[0]; // x bounds - q2 = bounds[3] - bounds[2]; // y bounds - if (q2 > q) q = q2; - q2 = bounds[5] - bounds[4]; // z bounds - if (q2 > q) q = q2; - - // find level such that 0.5 * 2^level < q <= 2^level - int level; - frexp (q,&level); // q = (0.5 .. 1.0) * 2^level (definition of frexp) - return level; -} - - -// find a virtual memory address for a cell at the given level and x,y,z -// position. -// @@@ currently this is not very sophisticated, e.g. the scaling -// factors could be better designed to avoid collisions, and they should -// probably depend on the hash table physical size. - -static unsigned long getVirtualAddress (int level, int x, int y, int z) -{ - return level*1000 + x*100 + y*10 + z; -} - -//**************************************************************************** -// hash space - -struct dxHashSpace : public dxSpace { - int global_minlevel; // smallest hash table level to put AABBs in - int global_maxlevel; // objects that need a level larger than this will be - // put in a "big objects" list instead of a hash table - - dxHashSpace (dSpaceID _space); - void setLevels (int minlevel, int maxlevel); - void getLevels (int *minlevel, int *maxlevel); - void cleanGeoms(); - void collide (void *data, dNearCallback *callback); - void collide2 (void *data, dxGeom *geom, dNearCallback *callback); -}; - - -dxHashSpace::dxHashSpace (dSpaceID _space) : dxSpace (_space) -{ - type = dHashSpaceClass; - global_minlevel = -3; - global_maxlevel = 10; -} - - -void dxHashSpace::setLevels (int minlevel, int maxlevel) -{ - dAASSERT (minlevel <= maxlevel); - global_minlevel = minlevel; - global_maxlevel = maxlevel; -} - - -void dxHashSpace::getLevels (int *minlevel, int *maxlevel) -{ - if (minlevel) *minlevel = global_minlevel; - if (maxlevel) *maxlevel = global_maxlevel; -} - - -void dxHashSpace::cleanGeoms() -{ - // compute the AABBs of all dirty geoms, and clear the dirty flags - lock_count++; - for (dxGeom *g=first; g && (g->gflags & GEOM_DIRTY); g=g->next) { - if (IS_SPACE(g)) { - ((dxSpace*)g)->cleanGeoms(); - } - g->recomputeAABB(); - g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); - } - lock_count--; -} - - -void dxHashSpace::collide (void *data, dNearCallback *callback) -{ - dAASSERT(this && callback); - dxGeom *geom; - dxAABB *aabb; - int i,maxlevel; - - // 0 or 1 geoms can't collide with anything - if (count < 2) return; - - lock_count++; - cleanGeoms(); - - // create a list of auxiliary information for all geom axis aligned bounding - // boxes. set the level for all AABBs. put AABBs larger than the space's - // global_maxlevel in the big_boxes list, check everything else against - // that list at the end. for AABBs that are not too big, record the maximum - // level that we need. - - int n = 0; // number of AABBs in main list - dxAABB *first_aabb = 0; // list of AABBs in hash table - dxAABB *big_boxes = 0; // list of AABBs too big for hash table - maxlevel = global_minlevel - 1; - for (geom = first; geom; geom=geom->next) { - if (!GEOM_ENABLED(geom)){ - continue; - } - dxAABB *aabb = (dxAABB*) ALLOCA (sizeof(dxAABB)); - aabb->geom = geom; - // compute level, but prevent cells from getting too small - int level = findLevel (geom->aabb); - if (level < global_minlevel) level = global_minlevel; - if (level <= global_maxlevel) { - // aabb goes in main list - aabb->next = first_aabb; - first_aabb = aabb; - aabb->level = level; - if (level > maxlevel) maxlevel = level; - // cellsize = 2^level - dReal cellsize = (dReal) ldexp (1.0,level); - // discretize AABB position to cell size - for (i=0; i < 6; i++) aabb->dbounds[i] = (int) - floor (geom->aabb[i]/cellsize); - // set AABB index - aabb->index = n; - n++; - } - else { - // aabb is too big, put it in the big_boxes list. we don't care about - // setting level, dbounds, index, or the maxlevel - aabb->next = big_boxes; - big_boxes = aabb; - } - } - - // for `n' objects, an n*n array of bits is used to record if those objects - // have been intersection-tested against each other yet. this array can - // grow large with high n, but oh well... - int tested_rowsize = (n+7) >> 3; // number of bytes needed for n bits - unsigned char *tested = (unsigned char *) alloca (n * tested_rowsize); - memset (tested,0,n * tested_rowsize); - - // create a hash table to store all AABBs. each AABB may take up to 8 cells. - // we use chaining to resolve collisions, but we use a relatively large table - // to reduce the chance of collisions. - - // compute hash table size sz to be a prime > 8*n - for (i=0; i= (8*n)) break; - } - if (i >= NUM_PRIMES) i = NUM_PRIMES-1; // probably pointless - int sz = prime[i]; - - // allocate and initialize hash table node pointers - Node **table = (Node **) ALLOCA (sizeof(Node*) * sz); - for (i=0; inext) { - int *dbounds = aabb->dbounds; - for (int xi = dbounds[0]; xi <= dbounds[1]; xi++) { - for (int yi = dbounds[2]; yi <= dbounds[3]; yi++) { - for (int zi = dbounds[4]; zi <= dbounds[5]; zi++) { - // get the hash index - unsigned long hi = getVirtualAddress (aabb->level,xi,yi,zi) % sz; - // add a new node to the hash table - Node *node = (Node*) alloca (sizeof (Node)); - node->x = xi; - node->y = yi; - node->z = zi; - node->aabb = aabb; - node->next = table[hi]; - table[hi] = node; - } - } - } - } - - // now that all AABBs are loaded into the hash table, we do the actual - // collision detection. for all AABBs, check for other AABBs in the - // same cells for collisions, and then check for other AABBs in all - // intersecting higher level cells. - - int db[6]; // discrete bounds at current level - for (aabb=first_aabb; aabb; aabb=aabb->next) { - // we are searching for collisions with aabb - for (i=0; i<6; i++) db[i] = aabb->dbounds[i]; - for (int level = aabb->level; level <= maxlevel; level++) { - for (int xi = db[0]; xi <= db[1]; xi++) { - for (int yi = db[2]; yi <= db[3]; yi++) { - for (int zi = db[4]; zi <= db[5]; zi++) { - // get the hash index - unsigned long hi = getVirtualAddress (level,xi,yi,zi) % sz; - // search all nodes at this index - Node *node; - for (node = table[hi]; node; node=node->next) { - // node points to an AABB that may intersect aabb - if (node->aabb == aabb) continue; - if (node->aabb->level == level && - node->x == xi && node->y == yi && node->z == zi) { - // see if aabb and node->aabb have already been tested - // against each other - unsigned char mask; - if (aabb->index <= node->aabb->index) { - i = (aabb->index * tested_rowsize)+(node->aabb->index >> 3); - mask = 1 << (node->aabb->index & 7); - } - else { - i = (node->aabb->index * tested_rowsize)+(aabb->index >> 3); - mask = 1 << (aabb->index & 7); - } - dIASSERT (i >= 0 && i < (tested_rowsize*n)); - if ((tested[i] & mask)==0) { - collideAABBs (aabb->geom,node->aabb->geom,data,callback); - } - tested[i] |= mask; - } - } - } - } - } - // get the discrete bounds for the next level up - for (i=0; i<6; i++) db[i] >>= 1; - } - } - - // every AABB in the normal list must now be intersected against every - // AABB in the big_boxes list. so let's hope there are not too many objects - // in the big_boxes list. - for (aabb=first_aabb; aabb; aabb=aabb->next) { - for (dxAABB *aabb2=big_boxes; aabb2; aabb2=aabb2->next) { - collideAABBs (aabb->geom,aabb2->geom,data,callback); - } - } - - // intersected all AABBs in the big_boxes list together - for (aabb=big_boxes; aabb; aabb=aabb->next) { - for (dxAABB *aabb2=aabb->next; aabb2; aabb2=aabb2->next) { - collideAABBs (aabb->geom,aabb2->geom,data,callback); - } - } - - lock_count--; -} - - -void dxHashSpace::collide2 (void *data, dxGeom *geom, - dNearCallback *callback) -{ - dAASSERT (geom && callback); - - // this could take advantage of the hash structure to avoid - // O(n2) complexity, but it does not yet. - - lock_count++; - cleanGeoms(); - geom->recomputeAABB(); - - // intersect bounding boxes - for (dxGeom *g=first; g; g=g->next) { - collideAABBs (g,geom,data,callback); - } - - lock_count--; -} - -//**************************************************************************** -// space functions - -dxSpace *dSimpleSpaceCreate (dxSpace *space) -{ - return new dxSimpleSpace (space); -} - - -dxSpace *dHashSpaceCreate (dxSpace *space) -{ - return new dxHashSpace (space); -} - - -void dHashSpaceSetLevels (dxSpace *space, int minlevel, int maxlevel) -{ - dAASSERT (space); - dUASSERT (minlevel <= maxlevel,"must have minlevel <= maxlevel"); - dUASSERT (space->type == dHashSpaceClass,"argument must be a hash space"); - dxHashSpace *hspace = (dxHashSpace*) space; - hspace->setLevels (minlevel,maxlevel); -} - - -void dHashSpaceGetLevels (dxSpace *space, int *minlevel, int *maxlevel) -{ - dAASSERT (space); - dUASSERT (space->type == dHashSpaceClass,"argument must be a hash space"); - dxHashSpace *hspace = (dxHashSpace*) space; - hspace->getLevels (minlevel,maxlevel); -} - - -void dSpaceDestroy (dxSpace *space) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - dGeomDestroy (space); -} - - -void dSpaceSetCleanup (dxSpace *space, int mode) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - space->setCleanup (mode); -} - - -int dSpaceGetCleanup (dxSpace *space) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - return space->getCleanup(); -} - - -void dSpaceAdd (dxSpace *space, dxGeom *g) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - CHECK_NOT_LOCKED (space); - space->add (g); -} - - -void dSpaceRemove (dxSpace *space, dxGeom *g) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - CHECK_NOT_LOCKED (space); - space->remove (g); -} - - -int dSpaceQuery (dxSpace *space, dxGeom *g) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - return space->query (g); -} - -void dSpaceClean (dxSpace *space){ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - - space->cleanGeoms(); -} - -int dSpaceGetNumGeoms (dxSpace *space) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - return space->getNumGeoms(); -} - - -dGeomID dSpaceGetGeom (dxSpace *space, int i) -{ - dAASSERT (space); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - return space->getGeom (i); -} - - -void dSpaceCollide (dxSpace *space, void *data, dNearCallback *callback) -{ - dAASSERT (space && callback); - dUASSERT (dGeomIsSpace(space),"argument not a space"); - space->collide (data,callback); -} - - -void dSpaceCollide2 (dxGeom *g1, dxGeom *g2, void *data, - dNearCallback *callback) -{ - dAASSERT (g1 && g2 && callback); - dxSpace *s1,*s2; - - // see if either geom is a space - if (IS_SPACE(g1)) s1 = (dxSpace*) g1; else s1 = 0; - if (IS_SPACE(g2)) s2 = (dxSpace*) g2; else s2 = 0; - - // handle the four space/geom cases - if (s1) { - if (s2) { - // g1 and g2 are spaces. - if (s1==s2) { - // collide a space with itself --> interior collision - s1->collide (data,callback); - } - else { - // iterate through the space that has the fewest geoms, calling - // collide2 in the other space for each one. - if (s1->count < s2->count) { - for (dxGeom *g = s1->first; g; g=g->next) { - s2->collide2 (data,g,callback); - } - } - else { - for (dxGeom *g = s2->first; g; g=g->next) { - s1->collide2 (data,g,callback); - } - } - } - } - else { - // g1 is a space, g2 is a geom - s1->collide2 (data,g2,callback); - } - } - else { - if (s2) { - // g1 is a geom, g2 is a space - s2->collide2 (data,g1,callback); - } - else { - // g1 and g2 are geoms, call the callback directly - callback (data,g1,g2); - } - } -} diff --git a/Extras/ode/ode/src/collision_space_internal.h b/Extras/ode/ode/src/collision_space_internal.h deleted file mode 100644 index 004276ab0..000000000 --- a/Extras/ode/ode/src/collision_space_internal.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -stuff common to all spaces - -*/ - -#ifndef _ODE_COLLISION_SPACE_INTERNAL_H_ -#define _ODE_COLLISION_SPACE_INTERNAL_H_ - -#define ALLOCA(x) dALLOCA16(x) - -#define CHECK_NOT_LOCKED(space) \ - dUASSERT ((space)==0 || (space)->lock_count==0, \ - "invalid operation for locked space"); - - -// collide two geoms together. for the hash table space, this is -// called if the two AABBs inhabit the same hash table cells. -// this only calls the callback function if the AABBs actually -// intersect. if a geom has an AABB test function, that is called to -// provide a further refinement of the intersection. -// -// NOTE: this assumes that the geom AABBs are valid on entry -// and that both geoms are enabled. - -static void collideAABBs (dxGeom *g1, dxGeom *g2, - void *data, dNearCallback *callback) -{ - dIASSERT((g1->gflags & GEOM_AABB_BAD)==0); - dIASSERT((g2->gflags & GEOM_AABB_BAD)==0); - - // no contacts if both geoms on the same body, and the body is not 0 - if (g1->body == g2->body && g1->body) return; - - // test if the category and collide bitfields match - if ( ((g1->category_bits & g2->collide_bits) || - (g2->category_bits & g1->collide_bits)) == 0) { - return; - } - - // if the bounding boxes are disjoint then don't do anything - dReal *bounds1 = g1->aabb; - dReal *bounds2 = g2->aabb; - if (bounds1[0] > bounds2[1] || - bounds1[1] < bounds2[0] || - bounds1[2] > bounds2[3] || - bounds1[3] < bounds2[2] || - bounds1[4] > bounds2[5] || - bounds1[5] < bounds2[4]) { - return; - } - - // check if either object is able to prove that it doesn't intersect the - // AABB of the other - if (g1->AABBTest (g2,bounds2) == 0) return; - if (g2->AABBTest (g1,bounds1) == 0) return; - - // the objects might actually intersect - call the space callback function - callback (data,g1,g2); -} - -#endif diff --git a/Extras/ode/ode/src/collision_std.cpp b/Extras/ode/ode/src/collision_std.cpp deleted file mode 100644 index 9574efd54..000000000 --- a/Extras/ode/ode/src/collision_std.cpp +++ /dev/null @@ -1,1876 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -standard ODE geometry primitives: public API and pairwise collision functions. - -the rule is that only the low level primitive collision functions should set -dContactGeom::g1 and dContactGeom::g2. - -*/ - -#include -#include -#include -#include -#include -#include "collision_kernel.h" -#include "collision_std.h" -#include "collision_util.h" - -#ifdef _MSC_VER -#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" -#endif - -//**************************************************************************** -// the basic geometry objects - -struct dxSphere : public dxGeom { - dReal radius; // sphere radius - dxSphere (dSpaceID space, dReal _radius); - void computeAABB(); -}; - - -struct dxBox : public dxGeom { - dVector3 side; // side lengths (x,y,z) - dxBox (dSpaceID space, dReal lx, dReal ly, dReal lz); - void computeAABB(); -}; - - -struct dxCCylinder : public dxGeom { - dReal radius,lz; // radius, length along z axis - dxCCylinder (dSpaceID space, dReal _radius, dReal _length); - void computeAABB(); -}; - - -struct dxPlane : public dxGeom { - dReal p[4]; - dxPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d); - void computeAABB(); -}; - - -struct dxRay : public dxGeom { - dReal length; - dxRay (dSpaceID space, dReal _length); - void computeAABB(); -}; - -//**************************************************************************** -// sphere public API - -dxSphere::dxSphere (dSpaceID space, dReal _radius) : dxGeom (space,1) -{ - dAASSERT (_radius > 0); - type = dSphereClass; - radius = _radius; -} - - -void dxSphere::computeAABB() -{ - aabb[0] = pos[0] - radius; - aabb[1] = pos[0] + radius; - aabb[2] = pos[1] - radius; - aabb[3] = pos[1] + radius; - aabb[4] = pos[2] - radius; - aabb[5] = pos[2] + radius; -} - - -dGeomID dCreateSphere (dSpaceID space, dReal radius) -{ - return new dxSphere (space,radius); -} - - -void dGeomSphereSetRadius (dGeomID g, dReal radius) -{ - dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); - dAASSERT (radius > 0); - dxSphere *s = (dxSphere*) g; - s->radius = radius; - dGeomMoved (g); -} - - -dReal dGeomSphereGetRadius (dGeomID g) -{ - dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); - dxSphere *s = (dxSphere*) g; - return s->radius; -} - - -dReal dGeomSpherePointDepth (dGeomID g, dReal x, dReal y, dReal z) -{ - dUASSERT (g && g->type == dSphereClass,"argument not a sphere"); - dxSphere *s = (dxSphere*) g; - return s->radius - dSqrt ((x-s->pos[0])*(x-s->pos[0]) + - (y-s->pos[1])*(y-s->pos[1]) + - (z-s->pos[2])*(z-s->pos[2])); -} - -//**************************************************************************** -// box public API - -dxBox::dxBox (dSpaceID space, dReal lx, dReal ly, dReal lz) : dxGeom (space,1) -{ - dAASSERT (lx >= 0 && ly >= 0 && lz >= 0); - type = dBoxClass; - side[0] = lx; - side[1] = ly; - side[2] = lz; -} - - -void dxBox::computeAABB() -{ - dReal xrange = REAL(0.5) * (dFabs (R[0] * side[0]) + - dFabs (R[1] * side[1]) + dFabs (R[2] * side[2])); - dReal yrange = REAL(0.5) * (dFabs (R[4] * side[0]) + - dFabs (R[5] * side[1]) + dFabs (R[6] * side[2])); - dReal zrange = REAL(0.5) * (dFabs (R[8] * side[0]) + - dFabs (R[9] * side[1]) + dFabs (R[10] * side[2])); - aabb[0] = pos[0] - xrange; - aabb[1] = pos[0] + xrange; - aabb[2] = pos[1] - yrange; - aabb[3] = pos[1] + yrange; - aabb[4] = pos[2] - zrange; - aabb[5] = pos[2] + zrange; -} - - -dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz) -{ - return new dxBox (space,lx,ly,lz); -} - - -void dGeomBoxSetLengths (dGeomID g, dReal lx, dReal ly, dReal lz) -{ - dUASSERT (g && g->type == dBoxClass,"argument not a box"); - dAASSERT (lx > 0 && ly > 0 && lz > 0); - dxBox *b = (dxBox*) g; - b->side[0] = lx; - b->side[1] = ly; - b->side[2] = lz; - dGeomMoved (g); -} - - -void dGeomBoxGetLengths (dGeomID g, dVector3 result) -{ - dUASSERT (g && g->type == dBoxClass,"argument not a box"); - dxBox *b = (dxBox*) g; - result[0] = b->side[0]; - result[1] = b->side[1]; - result[2] = b->side[2]; -} - - -dReal dGeomBoxPointDepth (dGeomID g, dReal x, dReal y, dReal z) -{ - dUASSERT (g && g->type == dBoxClass,"argument not a box"); - dxBox *b = (dxBox*) g; - - // Set p = (x,y,z) relative to box center - // - // This will be (0,0,0) if the point is at (side[0]/2,side[1]/2,side[2]/2) - - dVector3 p,q; - - p[0] = x - b->pos[0]; - p[1] = y - b->pos[1]; - p[2] = z - b->pos[2]; - - // Rotate p into box's coordinate frame, so we can - // treat the OBB as an AABB - - dMULTIPLY1_331 (q,b->R,p); - - // Record distance from point to each successive box side, and see - // if the point is inside all six sides - - dReal dist[6]; - int i; - - bool inside = true; - - for (i=0; i < 3; i++) { - dReal side = b->side[i] * REAL(0.5); - - dist[i ] = side - q[i]; - dist[i+3] = side + q[i]; - - if ((dist[i] < 0) || (dist[i+3] < 0)) { - inside = false; - } - } - - // If point is inside the box, the depth is the smallest positive distance - // to any side - - if (inside) { - dReal smallest_dist = (dReal) (unsigned) -1; - - for (i=0; i < 6; i++) { - if (dist[i] < smallest_dist) smallest_dist = dist[i]; - } - - return smallest_dist; - } - - // Otherwise, if point is outside the box, the depth is the largest - // distance to any side. This is an approximation to the 'proper' - // solution (the proper solution may be larger in some cases). - - dReal largest_dist = 0; - - for (i=0; i < 6; i++) { - if (dist[i] > largest_dist) largest_dist = dist[i]; - } - - return -largest_dist; -} - -//**************************************************************************** -// capped cylinder public API - -dxCCylinder::dxCCylinder (dSpaceID space, dReal _radius, dReal _length) : - dxGeom (space,1) -{ - dAASSERT (_radius > 0 && _length > 0); - type = dCCylinderClass; - radius = _radius; - lz = _length; -} - - -void dxCCylinder::computeAABB() -{ - dReal xrange = dFabs(R[2] * lz) * REAL(0.5) + radius; - dReal yrange = dFabs(R[6] * lz) * REAL(0.5) + radius; - dReal zrange = dFabs(R[10] * lz) * REAL(0.5) + radius; - aabb[0] = pos[0] - xrange; - aabb[1] = pos[0] + xrange; - aabb[2] = pos[1] - yrange; - aabb[3] = pos[1] + yrange; - aabb[4] = pos[2] - zrange; - aabb[5] = pos[2] + zrange; -} - - -dGeomID dCreateCCylinder (dSpaceID space, dReal radius, dReal length) -{ - return new dxCCylinder (space,radius,length); -} - - -void dGeomCCylinderSetParams (dGeomID g, dReal radius, dReal length) -{ - dUASSERT (g && g->type == dCCylinderClass,"argument not a ccylinder"); - dAASSERT (radius > 0 && length > 0); - dxCCylinder *c = (dxCCylinder*) g; - c->radius = radius; - c->lz = length; - dGeomMoved (g); -} - - -void dGeomCCylinderGetParams (dGeomID g, dReal *radius, dReal *length) -{ - dUASSERT (g && g->type == dCCylinderClass,"argument not a ccylinder"); - dxCCylinder *c = (dxCCylinder*) g; - *radius = c->radius; - *length = c->lz; -} - - -dReal dGeomCCylinderPointDepth (dGeomID g, dReal x, dReal y, dReal z) -{ - dUASSERT (g && g->type == dCCylinderClass,"argument not a ccylinder"); - dxCCylinder *c = (dxCCylinder*) g; - dVector3 a; - a[0] = x - c->pos[0]; - a[1] = y - c->pos[1]; - a[2] = z - c->pos[2]; - dReal beta = dDOT14(a,c->R+2); - dReal lz2 = c->lz*REAL(0.5); - if (beta < -lz2) beta = -lz2; - else if (beta > lz2) beta = lz2; - a[0] = c->pos[0] + beta*c->R[0*4+2]; - a[1] = c->pos[1] + beta*c->R[1*4+2]; - a[2] = c->pos[2] + beta*c->R[2*4+2]; - return c->radius - - dSqrt ((x-a[0])*(x-a[0]) + (y-a[1])*(y-a[1]) + (z-a[2])*(z-a[2])); -} - -//**************************************************************************** -// plane public API - -static void make_sure_plane_normal_has_unit_length (dxPlane *g) -{ - dReal l = g->p[0]*g->p[0] + g->p[1]*g->p[1] + g->p[2]*g->p[2]; - if (l > 0) { - l = dRecipSqrt(l); - g->p[0] *= l; - g->p[1] *= l; - g->p[2] *= l; - g->p[3] *= l; - } - else { - g->p[0] = 1; - g->p[1] = 0; - g->p[2] = 0; - g->p[3] = 0; - } -} - - -dxPlane::dxPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) : - dxGeom (space,0) -{ - type = dPlaneClass; - p[0] = a; - p[1] = b; - p[2] = c; - p[3] = d; - make_sure_plane_normal_has_unit_length (this); -} - - -void dxPlane::computeAABB() -{ - // @@@ planes that have normal vectors aligned along an axis can use a - // @@@ less comprehensive (half space) bounding box. - aabb[0] = -dInfinity; - aabb[1] = dInfinity; - aabb[2] = -dInfinity; - aabb[3] = dInfinity; - aabb[4] = -dInfinity; - aabb[5] = dInfinity; -} - - -dGeomID dCreatePlane (dSpaceID space, - dReal a, dReal b, dReal c, dReal d) -{ - return new dxPlane (space,a,b,c,d); -} - - -void dGeomPlaneSetParams (dGeomID g, dReal a, dReal b, dReal c, dReal d) -{ - dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); - dxPlane *p = (dxPlane*) g; - p->p[0] = a; - p->p[1] = b; - p->p[2] = c; - p->p[3] = d; - make_sure_plane_normal_has_unit_length (p); - dGeomMoved (g); -} - - -void dGeomPlaneGetParams (dGeomID g, dVector4 result) -{ - dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); - dxPlane *p = (dxPlane*) g; - result[0] = p->p[0]; - result[1] = p->p[1]; - result[2] = p->p[2]; - result[3] = p->p[3]; -} - - -dReal dGeomPlanePointDepth (dGeomID g, dReal x, dReal y, dReal z) -{ - dUASSERT (g && g->type == dPlaneClass,"argument not a plane"); - dxPlane *p = (dxPlane*) g; - return p->p[3] - p->p[0]*x - p->p[1]*y - p->p[2]*z; -} - -//**************************************************************************** -// ray public API - -dxRay::dxRay (dSpaceID space, dReal _length) : dxGeom (space,1) -{ - type = dRayClass; - length = _length; -} - - -void dxRay::computeAABB() -{ - dVector3 e; - e[0] = pos[0] + R[0*4+2]*length; - e[1] = pos[1] + R[1*4+2]*length; - e[2] = pos[2] + R[2*4+2]*length; - - if (pos[0] < e[0]){ - aabb[0] = pos[0]; - aabb[1] = e[0]; - } - else{ - aabb[0] = e[0]; - aabb[1] = pos[0]; - } - - if (pos[1] < e[1]){ - aabb[2] = pos[1]; - aabb[3] = e[1]; - } - else{ - aabb[2] = e[1]; - aabb[3] = pos[1]; - } - - if (pos[2] < e[2]){ - aabb[4] = pos[2]; - aabb[5] = e[2]; - } - else{ - aabb[4] = e[2]; - aabb[5] = pos[2]; - } -} - - -dGeomID dCreateRay (dSpaceID space, dReal length) -{ - return new dxRay (space,length); -} - - -void dGeomRaySetLength (dGeomID g, dReal length) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - dxRay *r = (dxRay*) g; - r->length = length; - dGeomMoved (g); -} - - -dReal dGeomRayGetLength (dGeomID g) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - dxRay *r = (dxRay*) g; - return r->length; -} - - -void dGeomRaySet (dGeomID g, dReal px, dReal py, dReal pz, - dReal dx, dReal dy, dReal dz) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - dReal* rot = g->R; - dReal* pos = g->pos; - dVector3 n; - pos[0] = px; - pos[1] = py; - pos[2] = pz; - - n[0] = dx; - n[1] = dy; - n[2] = dz; - dNormalize3(n); - rot[0*4+2] = n[0]; - rot[1*4+2] = n[1]; - rot[2*4+2] = n[2]; - dGeomMoved (g); -} - - -void dGeomRayGet (dGeomID g, dVector3 start, dVector3 dir) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - start[0] = g->pos[0]; - start[1] = g->pos[1]; - start[2] = g->pos[2]; - dir[0] = g->R[0*4+2]; - dir[1] = g->R[1*4+2]; - dir[2] = g->R[2*4+2]; -} - - -void dGeomRaySetParams (dxGeom *g, int FirstContact, int BackfaceCull) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - - if (FirstContact){ - g->gflags |= RAY_FIRSTCONTACT; - } - else g->gflags &= ~RAY_FIRSTCONTACT; - - if (BackfaceCull){ - g->gflags |= RAY_BACKFACECULL; - } - else g->gflags &= ~RAY_BACKFACECULL; -} - - -void dGeomRayGetParams (dxGeom *g, int *FirstContact, int *BackfaceCull) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - - (*FirstContact) = ((g->gflags & RAY_FIRSTCONTACT) != 0); - (*BackfaceCull) = ((g->gflags & RAY_BACKFACECULL) != 0); -} - - -void dGeomRaySetClosestHit (dxGeom *g, int closestHit) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - if (closestHit){ - g->gflags |= RAY_CLOSEST_HIT; - } - else g->gflags &= ~RAY_CLOSEST_HIT; -} - - -int dGeomRayGetClosestHit (dxGeom *g) -{ - dUASSERT (g && g->type == dRayClass,"argument not a ray"); - return ((g->gflags & RAY_CLOSEST_HIT) != 0); -} - -//**************************************************************************** -// box-box collision utility - - -// find all the intersection points between the 2D rectangle with vertices -// at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]), -// (p[2],p[3]),(p[4],p[5]),(p[6],p[7]). -// -// the intersection points are returned as x,y pairs in the 'ret' array. -// the number of intersection points is returned by the function (this will -// be in the range 0 to 8). - -static int intersectRectQuad (dReal h[2], dReal p[8], dReal ret[16]) -{ - // q (and r) contain nq (and nr) coordinate points for the current (and - // chopped) polygons - int nq=4,nr; - dReal buffer[16]; - dReal *q = p; - dReal *r = ret; - for (int dir=0; dir <= 1; dir++) { - // direction notation: xy[0] = x axis, xy[1] = y axis - for (int sign=-1; sign <= 1; sign += 2) { - // chop q along the line xy[dir] = sign*h[dir] - dReal *pq = q; - dReal *pr = r; - nr = 0; - for (int i=nq; i > 0; i--) { - // go through all points in q and all lines between adjacent points - if (sign*pq[dir] < h[dir]) { - // this point is inside the chopping line - pr[0] = pq[0]; - pr[1] = pq[1]; - pr += 2; - nr++; - if (nr & 8) { - q = r; - goto done; - } - } - dReal *nextq = (i > 1) ? pq+2 : q; - if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) { - // this line crosses the chopping line - pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) / - (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]); - pr[dir] = sign*h[dir]; - pr += 2; - nr++; - if (nr & 8) { - q = r; - goto done; - } - } - pq += 2; - } - q = r; - r = (q==ret) ? buffer : ret; - nq = nr; - } - } - done: - if (q != ret) memcpy (ret,q,nr*2*sizeof(dReal)); - return nr; -} - - -// given n points in the plane (array p, of size 2*n), generate m points that -// best represent the whole set. the definition of 'best' here is not -// predetermined - the idea is to select points that give good box-box -// collision detection behavior. the chosen point indexes are returned in the -// array iret (of size m). 'i0' is always the first entry in the array. -// n must be in the range [1..8]. m must be in the range [1..n]. i0 must be -// in the range [0..n-1]. - -void cullPoints (int n, dReal p[], int m, int i0, int iret[]) -{ - // compute the centroid of the polygon in cx,cy - int i,j; - dReal a,cx,cy,q; - if (n==1) { - cx = p[0]; - cy = p[1]; - } - else if (n==2) { - cx = REAL(0.5)*(p[0] + p[2]); - cy = REAL(0.5)*(p[1] + p[3]); - } - else { - a = 0; - cx = 0; - cy = 0; - for (i=0; i<(n-1); i++) { - q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1]; - a += q; - cx += q*(p[i*2]+p[i*2+2]); - cy += q*(p[i*2+1]+p[i*2+3]); - } - q = p[n*2-2]*p[1] - p[0]*p[n*2-1]; - a = dRecip(REAL(3.0)*(a+q)); - cx = a*(cx + q*(p[n*2-2]+p[0])); - cy = a*(cy + q*(p[n*2-1]+p[1])); - } - - // compute the angle of each point w.r.t. the centroid - dReal A[8]; - for (i=0; i M_PI) a -= 2*M_PI; - dReal maxdiff=1e9,diff; -#ifndef dNODEBUG - *iret = i0; // iret is not allowed to keep this value -#endif - for (i=0; i M_PI) diff = 2*M_PI - diff; - if (diff < maxdiff) { - maxdiff = diff; - *iret = i; - } - } - } -#ifndef dNODEBUG - dIASSERT (*iret != i0); // ensure iret got set -#endif - avail[*iret] = 0; - iret++; - } -} - - -// given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and -// generate contact points. this returns 0 if there is no contact otherwise -// it returns the number of contacts generated. -// `normal' returns the contact normal. -// `depth' returns the maximum penetration depth along that normal. -// `return_code' returns a number indicating the type of contact that was -// detected: -// 1,2,3 = box 2 intersects with a face of box 1 -// 4,5,6 = box 1 intersects with a face of box 2 -// 7..15 = edge-edge contact -// `maxc' is the maximum number of contacts allowed to be generated, i.e. -// the size of the `contact' array. -// `contact' and `skip' are the contact array information provided to the -// collision functions. this function only fills in the position and depth -// fields. - -int dBoxBox (const dVector3 p1, const dMatrix3 R1, - const dVector3 side1, const dVector3 p2, - const dMatrix3 R2, const dVector3 side2, - dVector3 normal, dReal *depth, int *return_code, - int maxc, dContactGeom *contact, int skip) -{ - const dReal fudge_factor = REAL(1.05); - dVector3 p,pp,normalC; - const dReal *normalR = 0; - dReal A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33, - Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l; - int i,j,invert_normal,code; - - // get vector from centers of box 1 to box 2, relative to box 1 - p[0] = p2[0] - p1[0]; - p[1] = p2[1] - p1[1]; - p[2] = p2[2] - p1[2]; - dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1 - - // get side lengths / 2 - A[0] = side1[0]*REAL(0.5); - A[1] = side1[1]*REAL(0.5); - A[2] = side1[2]*REAL(0.5); - B[0] = side2[0]*REAL(0.5); - B[1] = side2[1]*REAL(0.5); - B[2] = side2[2]*REAL(0.5); - - // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 - R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); - R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); - R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); - - Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13); - Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23); - Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33); - - // for all 15 possible separating axes: - // * see if the axis separates the boxes. if so, return 0. - // * find the depth of the penetration along the separating axis (s2) - // * if this is the largest depth so far, record it. - // the normal vector will be set to the separating axis with the smallest - // depth. note: normalR is set to point to a column of R1 or R2 if that is - // the smallest depth normal so far. otherwise normalR is 0 and normalC is - // set to a vector relative to body 1. invert_normal is 1 if the sign of - // the normal should be flipped. - -#define TST(expr1,expr2,norm,cc) \ - s2 = dFabs(expr1) - (expr2); \ - if (s2 > 0) return 0; \ - if (s2 > s) { \ - s = s2; \ - normalR = norm; \ - invert_normal = ((expr1) < 0); \ - code = (cc); \ - } - - s = -dInfinity; - invert_normal = 0; - code = 0; - - // separating axis = u1,u2,u3 - TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1); - TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2); - TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3); - - // separating axis = v1,v2,v3 - TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); - TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); - TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6); - - // note: cross product axes need to be scaled when s is computed. - // normal (n1,n2,n3) is relative to box 1. -#undef TST -#define TST(expr1,expr2,n1,n2,n3,cc) \ - s2 = dFabs(expr1) - (expr2); \ - if (s2 > 0) return 0; \ - l = dSqrt ((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ - if (l > 0) { \ - s2 /= l; \ - if (s2*fudge_factor > s) { \ - s = s2; \ - normalR = 0; \ - normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \ - invert_normal = ((expr1) < 0); \ - code = (cc); \ - } \ - } - - // separating axis = u1 x (v1,v2,v3) - TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7); - TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8); - TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9); - - // separating axis = u2 x (v1,v2,v3) - TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10); - TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11); - TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12); - - // separating axis = u3 x (v1,v2,v3) - TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13); - TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14); - TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15); - -#undef TST - - if (!code) return 0; - - // if we get to this point, the boxes interpenetrate. compute the normal - // in global coordinates. - if (normalR) { - normal[0] = normalR[0]; - normal[1] = normalR[4]; - normal[2] = normalR[8]; - } - else { - dMULTIPLY0_331 (normal,R1,normalC); - } - if (invert_normal) { - normal[0] = -normal[0]; - normal[1] = -normal[1]; - normal[2] = -normal[2]; - } - *depth = -s; - - // compute contact point(s) - - if (code > 6) { - // an edge from box 1 touches an edge from box 2. - // find a point pa on the intersecting edge of box 1 - dVector3 pa; - dReal sign; - for (i=0; i<3; i++) pa[i] = p1[i]; - for (j=0; j<3; j++) { - sign = (dDOT14(normal,R1+j) > 0) ? REAL(1.0) : REAL(-1.0); - for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j]; - } - - // find a point pb on the intersecting edge of box 2 - dVector3 pb; - for (i=0; i<3; i++) pb[i] = p2[i]; - for (j=0; j<3; j++) { - sign = (dDOT14(normal,R2+j) > 0) ? REAL(-1.0) : REAL(1.0); - for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j]; - } - - dReal alpha,beta; - dVector3 ua,ub; - for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4]; - for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4]; - - dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta); - for (i=0; i<3; i++) pa[i] += ua[i]*alpha; - for (i=0; i<3; i++) pb[i] += ub[i]*beta; - - for (i=0; i<3; i++) contact[0].pos[i] = REAL(0.5)*(pa[i]+pb[i]); - contact[0].depth = *depth; - *return_code = code; - return 1; - } - - // okay, we have a face-something intersection (because the separating - // axis is perpendicular to a face). define face 'a' to be the reference - // face (i.e. the normal vector is perpendicular to this) and face 'b' to be - // the incident face (the closest face of the other box). - - const dReal *Ra,*Rb,*pa,*pb,*Sa,*Sb; - if (code <= 3) { - Ra = R1; - Rb = R2; - pa = p1; - pb = p2; - Sa = A; - Sb = B; - } - else { - Ra = R2; - Rb = R1; - pa = p2; - pb = p1; - Sa = B; - Sb = A; - } - - // nr = normal vector of reference face dotted with axes of incident box. - // anr = absolute values of nr. - dVector3 normal2,nr,anr; - if (code <= 3) { - normal2[0] = normal[0]; - normal2[1] = normal[1]; - normal2[2] = normal[2]; - } - else { - normal2[0] = -normal[0]; - normal2[1] = -normal[1]; - normal2[2] = -normal[2]; - } - dMULTIPLY1_331 (nr,Rb,normal2); - anr[0] = dFabs (nr[0]); - anr[1] = dFabs (nr[1]); - anr[2] = dFabs (nr[2]); - - // find the largest compontent of anr: this corresponds to the normal - // for the indident face. the other axis numbers of the indicent face - // are stored in a1,a2. - int lanr,a1,a2; - if (anr[1] > anr[0]) { - if (anr[1] > anr[2]) { - a1 = 0; - lanr = 1; - a2 = 2; - } - else { - a1 = 0; - a2 = 1; - lanr = 2; - } - } - else { - if (anr[0] > anr[2]) { - lanr = 0; - a1 = 1; - a2 = 2; - } - else { - a1 = 0; - a2 = 1; - lanr = 2; - } - } - - // compute center point of incident face, in reference-face coordinates - dVector3 center; - if (nr[lanr] < 0) { - for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr]; - } - else { - for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr]; - } - - // find the normal and non-normal axis numbers of the reference box - int codeN,code1,code2; - if (code <= 3) codeN = code-1; else codeN = code-4; - if (codeN==0) { - code1 = 1; - code2 = 2; - } - else if (codeN==1) { - code1 = 0; - code2 = 2; - } - else { - code1 = 0; - code2 = 1; - } - - // find the four corners of the incident face, in reference-face coordinates - dReal quad[8]; // 2D coordinate of incident face (x,y pairs) - dReal c1,c2,m11,m12,m21,m22; - c1 = dDOT14 (center,Ra+code1); - c2 = dDOT14 (center,Ra+code2); - // optimize this? - we have already computed this data above, but it is not - // stored in an easy-to-index format. for now it's quicker just to recompute - // the four dot products. - m11 = dDOT44 (Ra+code1,Rb+a1); - m12 = dDOT44 (Ra+code1,Rb+a2); - m21 = dDOT44 (Ra+code2,Rb+a1); - m22 = dDOT44 (Ra+code2,Rb+a2); - { - dReal k1 = m11*Sb[a1]; - dReal k2 = m21*Sb[a1]; - dReal k3 = m12*Sb[a2]; - dReal k4 = m22*Sb[a2]; - quad[0] = c1 - k1 - k3; - quad[1] = c2 - k2 - k4; - quad[2] = c1 - k1 + k3; - quad[3] = c2 - k2 + k4; - quad[4] = c1 + k1 + k3; - quad[5] = c2 + k2 + k4; - quad[6] = c1 + k1 - k3; - quad[7] = c2 + k2 - k4; - } - - // find the size of the reference face - dReal rect[2]; - rect[0] = Sa[code1]; - rect[1] = Sa[code2]; - - // intersect the incident and reference faces - dReal ret[16]; - int n = intersectRectQuad (rect,quad,ret); - if (n < 1) return 0; // this should never happen - - // convert the intersection points into reference-face coordinates, - // and compute the contact position and depth for each point. only keep - // those points that have a positive (penetrating) depth. delete points in - // the 'ret' array as necessary so that 'point' and 'ret' correspond. - dReal point[3*8]; // penetrating contact points - dReal dep[8]; // depths for those points - dReal det1 = dRecip(m11*m22 - m12*m21); - m11 *= det1; - m12 *= det1; - m21 *= det1; - m22 *= det1; - int cnum = 0; // number of penetrating contact points found - for (j=0; j < n; j++) { - dReal k1 = m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2); - dReal k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2); - for (i=0; i<3; i++) point[cnum*3+i] = - center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2]; - dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3); - if (dep[cnum] >= 0) { - ret[cnum*2] = ret[j*2]; - ret[cnum*2+1] = ret[j*2+1]; - cnum++; - } - } - if (cnum < 1) return 0; // this should never happen - - // we can't generate more contacts than we actually have - if (maxc > cnum) maxc = cnum; - if (maxc < 1) maxc = 1; - - if (cnum <= maxc) { - // we have less contacts than we need, so we use them all - for (j=0; j < cnum; j++) { - dContactGeom *con = CONTACT(contact,skip*j); - for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i]; - con->depth = dep[j]; - } - } - else { - // we have more contacts than are wanted, some of them must be culled. - // find the deepest point, it is always the first contact. - int i1 = 0; - dReal maxdepth = dep[0]; - for (i=1; i maxdepth) { - maxdepth = dep[i]; - i1 = i; - } - } - - int iret[8]; - cullPoints (cnum,ret,maxc,i1,iret); - - for (j=0; j < maxc; j++) { - dContactGeom *con = CONTACT(contact,skip*j); - for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i]; - con->depth = dep[iret[j]]; - } - cnum = maxc; - } - - *return_code = code; - return cnum; -} - -//**************************************************************************** -// pairwise collision functions for standard geom types - -int dCollideSphereSphere (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dSphereClass); - dIASSERT (o2->type == dSphereClass); - dxSphere *sphere1 = (dxSphere*) o1; - dxSphere *sphere2 = (dxSphere*) o2; - - contact->g1 = o1; - contact->g2 = o2; - - return dCollideSpheres (o1->pos,sphere1->radius, - o2->pos,sphere2->radius,contact); -} - - -int dCollideSphereBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - // this is easy. get the sphere center `p' relative to the box, and then clip - // that to the boundary of the box (call that point `q'). if q is on the - // boundary of the box and |p-q| is <= sphere radius, they touch. - // if q is inside the box, the sphere is inside the box, so set a contact - // normal to push the sphere to the closest box face. - - dVector3 l,t,p,q,r; - dReal depth; - int onborder = 0; - - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dSphereClass); - dIASSERT (o2->type == dBoxClass); - dxSphere *sphere = (dxSphere*) o1; - dxBox *box = (dxBox*) o2; - - contact->g1 = o1; - contact->g2 = o2; - - p[0] = o1->pos[0] - o2->pos[0]; - p[1] = o1->pos[1] - o2->pos[1]; - p[2] = o1->pos[2] - o2->pos[2]; - - l[0] = box->side[0]*REAL(0.5); - t[0] = dDOT14(p,o2->R); - if (t[0] < -l[0]) { t[0] = -l[0]; onborder = 1; } - if (t[0] > l[0]) { t[0] = l[0]; onborder = 1; } - - l[1] = box->side[1]*REAL(0.5); - t[1] = dDOT14(p,o2->R+1); - if (t[1] < -l[1]) { t[1] = -l[1]; onborder = 1; } - if (t[1] > l[1]) { t[1] = l[1]; onborder = 1; } - - t[2] = dDOT14(p,o2->R+2); - l[2] = box->side[2]*REAL(0.5); - if (t[2] < -l[2]) { t[2] = -l[2]; onborder = 1; } - if (t[2] > l[2]) { t[2] = l[2]; onborder = 1; } - - if (!onborder) { - // sphere center inside box. find closest face to `t' - dReal min_distance = l[0] - dFabs(t[0]); - int mini = 0; - for (int i=1; i<3; i++) { - dReal face_distance = l[i] - dFabs(t[i]); - if (face_distance < min_distance) { - min_distance = face_distance; - mini = i; - } - } - // contact position = sphere center - contact->pos[0] = o1->pos[0]; - contact->pos[1] = o1->pos[1]; - contact->pos[2] = o1->pos[2]; - // contact normal points to closest face - dVector3 tmp; - tmp[0] = 0; - tmp[1] = 0; - tmp[2] = 0; - tmp[mini] = (t[mini] > 0) ? REAL(1.0) : REAL(-1.0); - dMULTIPLY0_331 (contact->normal,o2->R,tmp); - // contact depth = distance to wall along normal plus radius - contact->depth = min_distance + sphere->radius; - return 1; - } - - t[3] = 0; //@@@ hmmm - dMULTIPLY0_331 (q,o2->R,t); - r[0] = p[0] - q[0]; - r[1] = p[1] - q[1]; - r[2] = p[2] - q[2]; - depth = sphere->radius - dSqrt(dDOT(r,r)); - if (depth < 0) return 0; - contact->pos[0] = q[0] + o2->pos[0]; - contact->pos[1] = q[1] + o2->pos[1]; - contact->pos[2] = q[2] + o2->pos[2]; - contact->normal[0] = r[0]; - contact->normal[1] = r[1]; - contact->normal[2] = r[2]; - dNormalize3 (contact->normal); - contact->depth = depth; - return 1; -} - - -int dCollideSpherePlane (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dSphereClass); - dIASSERT (o2->type == dPlaneClass); - dxSphere *sphere = (dxSphere*) o1; - dxPlane *plane = (dxPlane*) o2; - - contact->g1 = o1; - contact->g2 = o2; - dReal k = dDOT (o1->pos,plane->p); - dReal depth = plane->p[3] - k + sphere->radius; - if (depth >= 0) { - contact->normal[0] = plane->p[0]; - contact->normal[1] = plane->p[1]; - contact->normal[2] = plane->p[2]; - contact->pos[0] = o1->pos[0] - plane->p[0] * sphere->radius; - contact->pos[1] = o1->pos[1] - plane->p[1] * sphere->radius; - contact->pos[2] = o1->pos[2] - plane->p[2] * sphere->radius; - contact->depth = depth; - return 1; - } - else return 0; -} - - -int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dBoxClass); - dIASSERT (o2->type == dBoxClass); - dVector3 normal; - dReal depth; - int code; - dxBox *b1 = (dxBox*) o1; - dxBox *b2 = (dxBox*) o2; - int num = dBoxBox (o1->pos,o1->R,b1->side, o2->pos,o2->R,b2->side, - normal,&depth,&code,flags & NUMC_MASK,contact,skip); - for (int i=0; inormal[0] = -normal[0]; - CONTACT(contact,i*skip)->normal[1] = -normal[1]; - CONTACT(contact,i*skip)->normal[2] = -normal[2]; - CONTACT(contact,i*skip)->g1 = o1; - CONTACT(contact,i*skip)->g2 = o2; - } - return num; -} - - -int dCollideBoxPlane (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dBoxClass); - dIASSERT (o2->type == dPlaneClass); - dxBox *box = (dxBox*) o1; - dxPlane *plane = (dxPlane*) o2; - - contact->g1 = o1; - contact->g2 = o2; - int ret = 0; - - //@@@ problem: using 4-vector (plane->p) as 3-vector (normal). - const dReal *R = o1->R; // rotation of box - const dReal *n = plane->p; // normal vector - - // project sides lengths along normal vector, get absolute values - dReal Q1 = dDOT14(n,R+0); - dReal Q2 = dDOT14(n,R+1); - dReal Q3 = dDOT14(n,R+2); - dReal A1 = box->side[0] * Q1; - dReal A2 = box->side[1] * Q2; - dReal A3 = box->side[2] * Q3; - dReal B1 = dFabs(A1); - dReal B2 = dFabs(A2); - dReal B3 = dFabs(A3); - - // early exit test - dReal depth = plane->p[3] + REAL(0.5)*(B1+B2+B3) - dDOT(n,o1->pos); - if (depth < 0) return 0; - - // find number of contacts requested - int maxc = flags & NUMC_MASK; - if (maxc < 1) maxc = 1; - if (maxc > 3) maxc = 3; // no more than 3 contacts per box allowed - - // find deepest point - dVector3 p; - p[0] = o1->pos[0]; - p[1] = o1->pos[1]; - p[2] = o1->pos[2]; -#define FOO(i,op) \ - p[0] op REAL(0.5)*box->side[i] * R[0+i]; \ - p[1] op REAL(0.5)*box->side[i] * R[4+i]; \ - p[2] op REAL(0.5)*box->side[i] * R[8+i]; -#define BAR(i,iinc) if (A ## iinc > 0) { FOO(i,-=) } else { FOO(i,+=) } - BAR(0,1); - BAR(1,2); - BAR(2,3); -#undef FOO -#undef BAR - - // the deepest point is the first contact point - contact->pos[0] = p[0]; - contact->pos[1] = p[1]; - contact->pos[2] = p[2]; - contact->normal[0] = n[0]; - contact->normal[1] = n[1]; - contact->normal[2] = n[2]; - contact->depth = depth; - ret = 1; // ret is number of contact points found so far - if (maxc == 1) goto done; - - // get the second and third contact points by starting from `p' and going - // along the two sides with the smallest projected length. - -#define FOO(i,j,op) \ - CONTACT(contact,i*skip)->pos[0] = p[0] op box->side[j] * R[0+j]; \ - CONTACT(contact,i*skip)->pos[1] = p[1] op box->side[j] * R[4+j]; \ - CONTACT(contact,i*skip)->pos[2] = p[2] op box->side[j] * R[8+j]; -#define BAR(ctact,side,sideinc) \ - depth -= B ## sideinc; \ - if (depth < 0) goto done; \ - if (A ## sideinc > 0) { FOO(ctact,side,+) } else { FOO(ctact,side,-) } \ - CONTACT(contact,ctact*skip)->depth = depth; \ - ret++; - - CONTACT(contact,skip)->normal[0] = n[0]; - CONTACT(contact,skip)->normal[1] = n[1]; - CONTACT(contact,skip)->normal[2] = n[2]; - if (maxc == 3) { - CONTACT(contact,2*skip)->normal[0] = n[0]; - CONTACT(contact,2*skip)->normal[1] = n[1]; - CONTACT(contact,2*skip)->normal[2] = n[2]; - } - - if (B1 < B2) { - if (B3 < B1) goto use_side_3; else { - BAR(1,0,1); // use side 1 - if (maxc == 2) goto done; - if (B2 < B3) goto contact2_2; else goto contact2_3; - } - } - else { - if (B3 < B2) { - use_side_3: // use side 3 - BAR(1,2,3); - if (maxc == 2) goto done; - if (B1 < B2) goto contact2_1; else goto contact2_2; - } - else { - BAR(1,1,2); // use side 2 - if (maxc == 2) goto done; - if (B1 < B3) goto contact2_1; else goto contact2_3; - } - } - - contact2_1: BAR(2,0,1); goto done; - contact2_2: BAR(2,1,2); goto done; - contact2_3: BAR(2,2,3); goto done; -#undef FOO -#undef BAR - - done: - for (int i=0; ig1 = o1; - CONTACT(contact,i*skip)->g2 = o2; - } - return ret; -} - - -int dCollideCCylinderSphere (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dCCylinderClass); - dIASSERT (o2->type == dSphereClass); - dxCCylinder *ccyl = (dxCCylinder*) o1; - dxSphere *sphere = (dxSphere*) o2; - - contact->g1 = o1; - contact->g2 = o2; - - // find the point on the cylinder axis that is closest to the sphere - dReal alpha = - o1->R[2] * (o2->pos[0] - o1->pos[0]) + - o1->R[6] * (o2->pos[1] - o1->pos[1]) + - o1->R[10] * (o2->pos[2] - o1->pos[2]); - dReal lz2 = ccyl->lz * REAL(0.5); - if (alpha > lz2) alpha = lz2; - if (alpha < -lz2) alpha = -lz2; - - // collide the spheres - dVector3 p; - p[0] = o1->pos[0] + alpha * o1->R[2]; - p[1] = o1->pos[1] + alpha * o1->R[6]; - p[2] = o1->pos[2] + alpha * o1->R[10]; - return dCollideSpheres (p,ccyl->radius,o2->pos,sphere->radius,contact); -} - - -int dCollideCCylinderBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dCCylinderClass); - dIASSERT (o2->type == dBoxClass); - dxCCylinder *cyl = (dxCCylinder*) o1; - dxBox *box = (dxBox*) o2; - - contact->g1 = o1; - contact->g2 = o2; - - // get p1,p2 = cylinder axis endpoints, get radius - dVector3 p1,p2; - dReal clen = cyl->lz * REAL(0.5); - p1[0] = o1->pos[0] + clen * o1->R[2]; - p1[1] = o1->pos[1] + clen * o1->R[6]; - p1[2] = o1->pos[2] + clen * o1->R[10]; - p2[0] = o1->pos[0] - clen * o1->R[2]; - p2[1] = o1->pos[1] - clen * o1->R[6]; - p2[2] = o1->pos[2] - clen * o1->R[10]; - dReal radius = cyl->radius; - - // copy out box center, rotation matrix, and side array - dReal *c = o2->pos; - dReal *R = o2->R; - const dReal *side = box->side; - - // get the closest point between the cylinder axis and the box - dVector3 pl,pb; - dClosestLineBoxPoints (p1,p2,c,R,side,pl,pb); - - // generate contact point - return dCollideSpheres (pl,radius,pb,0,contact); -} - - -int dCollideCCylinderCCylinder (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip) -{ - int i; - const dReal tolerance = REAL(1e-5); - - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dCCylinderClass); - dIASSERT (o2->type == dCCylinderClass); - dxCCylinder *cyl1 = (dxCCylinder*) o1; - dxCCylinder *cyl2 = (dxCCylinder*) o2; - - contact->g1 = o1; - contact->g2 = o2; - - // copy out some variables, for convenience - dReal lz1 = cyl1->lz * REAL(0.5); - dReal lz2 = cyl2->lz * REAL(0.5); - dReal *pos1 = o1->pos; - dReal *pos2 = o2->pos; - dReal axis1[3],axis2[3]; - axis1[0] = o1->R[2]; - axis1[1] = o1->R[6]; - axis1[2] = o1->R[10]; - axis2[0] = o2->R[2]; - axis2[1] = o2->R[6]; - axis2[2] = o2->R[10]; - - // if the cylinder axes are close to parallel, we'll try to detect up to - // two contact points along the body of the cylinder. if we can't find any - // points then we'll fall back to the closest-points algorithm. note that - // we are not treating this special case for reasons of degeneracy, but - // because we want two contact points in some situations. the closet-points - // algorithm is robust in all casts, but it can return only one contact. - - dVector3 sphere1,sphere2; - dReal a1a2 = dDOT (axis1,axis2); - dReal det = REAL(1.0)-a1a2*a1a2; - if (det < tolerance) { - // the cylinder axes (almost) parallel, so we will generate up to two - // contacts. alpha1 and alpha2 (line position parameters) are related by: - // alpha2 = alpha1 + (pos1-pos2)'*axis1 (if axis1==axis2) - // or alpha2 = -(alpha1 + (pos1-pos2)'*axis1) (if axis1==-axis2) - // first compute where the two cylinders overlap in alpha1 space: - if (a1a2 < 0) { - axis2[0] = -axis2[0]; - axis2[1] = -axis2[1]; - axis2[2] = -axis2[2]; - } - dReal q[3]; - for (i=0; i<3; i++) q[i] = pos1[i]-pos2[i]; - dReal k = dDOT (axis1,q); - dReal a1lo = -lz1; - dReal a1hi = lz1; - dReal a2lo = -lz2 - k; - dReal a2hi = lz2 - k; - dReal lo = (a1lo > a2lo) ? a1lo : a2lo; - dReal hi = (a1hi < a2hi) ? a1hi : a2hi; - if (lo <= hi) { - int num_contacts = flags & NUMC_MASK; - if (num_contacts >= 2 && lo < hi) { - // generate up to two contacts. if one of those contacts is - // not made, fall back on the one-contact strategy. - for (i=0; i<3; i++) sphere1[i] = pos1[i] + lo*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + (lo+k)*axis2[i]; - int n1 = dCollideSpheres (sphere1,cyl1->radius, - sphere2,cyl2->radius,contact); - if (n1) { - for (i=0; i<3; i++) sphere1[i] = pos1[i] + hi*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + (hi+k)*axis2[i]; - dContactGeom *c2 = CONTACT(contact,skip); - int n2 = dCollideSpheres (sphere1,cyl1->radius, - sphere2,cyl2->radius, c2); - if (n2) { - c2->g1 = o1; - c2->g2 = o2; - return 2; - } - } - } - - // just one contact to generate, so put it in the middle of - // the range - dReal alpha1 = (lo + hi) * REAL(0.5); - dReal alpha2 = alpha1 + k; - for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; - return dCollideSpheres (sphere1,cyl1->radius, - sphere2,cyl2->radius,contact); - } - } - - // use the closest point algorithm - dVector3 a1,a2,b1,b2; - a1[0] = o1->pos[0] + axis1[0]*lz1; - a1[1] = o1->pos[1] + axis1[1]*lz1; - a1[2] = o1->pos[2] + axis1[2]*lz1; - a2[0] = o1->pos[0] - axis1[0]*lz1; - a2[1] = o1->pos[1] - axis1[1]*lz1; - a2[2] = o1->pos[2] - axis1[2]*lz1; - b1[0] = o2->pos[0] + axis2[0]*lz2; - b1[1] = o2->pos[1] + axis2[1]*lz2; - b1[2] = o2->pos[2] + axis2[2]*lz2; - b2[0] = o2->pos[0] - axis2[0]*lz2; - b2[1] = o2->pos[1] - axis2[1]*lz2; - b2[2] = o2->pos[2] - axis2[2]*lz2; - - dClosestLineSegmentPoints (a1,a2,b1,b2,sphere1,sphere2); - return dCollideSpheres (sphere1,cyl1->radius,sphere2,cyl2->radius,contact); -} - - -int dCollideCCylinderPlane (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dCCylinderClass); - dIASSERT (o2->type == dPlaneClass); - dxCCylinder *ccyl = (dxCCylinder*) o1; - dxPlane *plane = (dxPlane*) o2; - - // collide the deepest capping sphere with the plane - dReal sign = (dDOT14 (plane->p,o1->R+2) > 0) ? REAL(-1.0) : REAL(1.0); - dVector3 p; - p[0] = o1->pos[0] + o1->R[2] * ccyl->lz * REAL(0.5) * sign; - p[1] = o1->pos[1] + o1->R[6] * ccyl->lz * REAL(0.5) * sign; - p[2] = o1->pos[2] + o1->R[10] * ccyl->lz * REAL(0.5) * sign; - - dReal k = dDOT (p,plane->p); - dReal depth = plane->p[3] - k + ccyl->radius; - if (depth < 0) return 0; - contact->normal[0] = plane->p[0]; - contact->normal[1] = plane->p[1]; - contact->normal[2] = plane->p[2]; - contact->pos[0] = p[0] - plane->p[0] * ccyl->radius; - contact->pos[1] = p[1] - plane->p[1] * ccyl->radius; - contact->pos[2] = p[2] - plane->p[2] * ccyl->radius; - contact->depth = depth; - - int ncontacts = 1; - if ((flags & NUMC_MASK) >= 2) { - // collide the other capping sphere with the plane - p[0] = o1->pos[0] - o1->R[2] * ccyl->lz * REAL(0.5) * sign; - p[1] = o1->pos[1] - o1->R[6] * ccyl->lz * REAL(0.5) * sign; - p[2] = o1->pos[2] - o1->R[10] * ccyl->lz * REAL(0.5) * sign; - - k = dDOT (p,plane->p); - depth = plane->p[3] - k + ccyl->radius; - if (depth >= 0) { - dContactGeom *c2 = CONTACT(contact,skip); - c2->normal[0] = plane->p[0]; - c2->normal[1] = plane->p[1]; - c2->normal[2] = plane->p[2]; - c2->pos[0] = p[0] - plane->p[0] * ccyl->radius; - c2->pos[1] = p[1] - plane->p[1] * ccyl->radius; - c2->pos[2] = p[2] - plane->p[2] * ccyl->radius; - c2->depth = depth; - ncontacts = 2; - } - } - - for (int i=0; i < ncontacts; i++) { - CONTACT(contact,i*skip)->g1 = o1; - CONTACT(contact,i*skip)->g2 = o2; - } - return ncontacts; -} - - -// if mode==1 then use the sphere exit contact, not the entry contact - -static int ray_sphere_helper (dxRay *ray, dVector3 sphere_pos, dReal radius, - dContactGeom *contact, int mode) -{ - dVector3 q; - q[0] = ray->pos[0] - sphere_pos[0]; - q[1] = ray->pos[1] - sphere_pos[1]; - q[2] = ray->pos[2] - sphere_pos[2]; - dReal B = dDOT14(q,ray->R+2); - dReal C = dDOT(q,q) - radius*radius; - // note: if C <= 0 then the start of the ray is inside the sphere - dReal k = B*B - C; - if (k < 0) return 0; - k = dSqrt(k); - dReal alpha; - if (mode && C >= 0) { - alpha = -B + k; - if (alpha < 0) return 0; - } - else { - alpha = -B - k; - if (alpha < 0) { - alpha = -B + k; - if (alpha < 0) return 0; - } - } - if (alpha > ray->length) return 0; - contact->pos[0] = ray->pos[0] + alpha*ray->R[0*4+2]; - contact->pos[1] = ray->pos[1] + alpha*ray->R[1*4+2]; - contact->pos[2] = ray->pos[2] + alpha*ray->R[2*4+2]; - dReal nsign = (C < 0 || mode) ? REAL(-1.0) : REAL(1.0); - contact->normal[0] = nsign*(contact->pos[0] - sphere_pos[0]); - contact->normal[1] = nsign*(contact->pos[1] - sphere_pos[1]); - contact->normal[2] = nsign*(contact->pos[2] - sphere_pos[2]); - dNormalize3 (contact->normal); - contact->depth = alpha; - return 1; -} - - -int dCollideRaySphere (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dRayClass); - dIASSERT (o2->type == dSphereClass); - dxRay *ray = (dxRay*) o1; - dxSphere *sphere = (dxSphere*) o2; - contact->g1 = ray; - contact->g2 = sphere; - return ray_sphere_helper (ray,sphere->pos,sphere->radius,contact,0); -} - - -int dCollideRayBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dRayClass); - dIASSERT (o2->type == dBoxClass); - dxRay *ray = (dxRay*) o1; - dxBox *box = (dxBox*) o2; - - contact->g1 = ray; - contact->g2 = box; - - int i; - - // compute the start and delta of the ray relative to the box. - // we will do all subsequent computations in this box-relative coordinate - // system. we have to do a translation and rotation for each point. - dVector3 tmp,s,v; - tmp[0] = ray->pos[0] - box->pos[0]; - tmp[1] = ray->pos[1] - box->pos[1]; - tmp[2] = ray->pos[2] - box->pos[2]; - dMULTIPLY1_331 (s,box->R,tmp); - tmp[0] = ray->R[0*4+2]; - tmp[1] = ray->R[1*4+2]; - tmp[2] = ray->R[2*4+2]; - dMULTIPLY1_331 (v,box->R,tmp); - - // mirror the line so that v has all components >= 0 - dVector3 sign; - for (i=0; i<3; i++) { - if (v[i] < 0) { - s[i] = -s[i]; - v[i] = -v[i]; - sign[i] = 1; - } - else sign[i] = -1; - } - - // compute the half-sides of the box - dReal h[3]; - h[0] = REAL(0.5) * box->side[0]; - h[1] = REAL(0.5) * box->side[1]; - h[2] = REAL(0.5) * box->side[2]; - - // do a few early exit tests - if ((s[0] < -h[0] && v[0] <= 0) || s[0] > h[0] || - (s[1] < -h[1] && v[1] <= 0) || s[1] > h[1] || - (s[2] < -h[2] && v[2] <= 0) || s[2] > h[2] || - (v[0] == 0 && v[1] == 0 && v[2] == 0)) { - return 0; - } - - // compute the t=[lo..hi] range for where s+v*t intersects the box - dReal lo = -dInfinity; - dReal hi = dInfinity; - int nlo = 0, nhi = 0; - for (i=0; i<3; i++) { - if (v[i] != 0) { - dReal k = (-h[i] - s[i])/v[i]; - if (k > lo) { - lo = k; - nlo = i; - } - k = (h[i] - s[i])/v[i]; - if (k < hi) { - hi = k; - nhi = i; - } - } - } - - // check if the ray intersects - if (lo > hi) return 0; - dReal alpha; - int n; - if (lo >= 0) { - alpha = lo; - n = nlo; - } - else { - alpha = hi; - n = nhi; - } - if (alpha < 0 || alpha > ray->length) return 0; - contact->pos[0] = ray->pos[0] + alpha*ray->R[0*4+2]; - contact->pos[1] = ray->pos[1] + alpha*ray->R[1*4+2]; - contact->pos[2] = ray->pos[2] + alpha*ray->R[2*4+2]; - contact->normal[0] = box->R[0*4+n] * sign[n]; - contact->normal[1] = box->R[1*4+n] * sign[n]; - contact->normal[2] = box->R[2*4+n] * sign[n]; - contact->depth = alpha; - return 1; -} - - -int dCollideRayCCylinder (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dRayClass); - dIASSERT (o2->type == dCCylinderClass); - dxRay *ray = (dxRay*) o1; - dxCCylinder *ccyl = (dxCCylinder*) o2; - - contact->g1 = ray; - contact->g2 = ccyl; - dReal lz2 = ccyl->lz * REAL(0.5); - - // compute some useful info - dVector3 cs,q,r; - dReal C,k; - cs[0] = ray->pos[0] - ccyl->pos[0]; - cs[1] = ray->pos[1] - ccyl->pos[1]; - cs[2] = ray->pos[2] - ccyl->pos[2]; - k = dDOT41(ccyl->R+2,cs); // position of ray start along ccyl axis - q[0] = k*ccyl->R[0*4+2] - cs[0]; - q[1] = k*ccyl->R[1*4+2] - cs[1]; - q[2] = k*ccyl->R[2*4+2] - cs[2]; - C = dDOT(q,q) - ccyl->radius*ccyl->radius; - // if C < 0 then ray start position within infinite extension of cylinder - - // see if ray start position is inside the capped cylinder - int inside_ccyl = 0; - if (C < 0) { - if (k < -lz2) k = -lz2; - else if (k > lz2) k = lz2; - r[0] = ccyl->pos[0] + k*ccyl->R[0*4+2]; - r[1] = ccyl->pos[1] + k*ccyl->R[1*4+2]; - r[2] = ccyl->pos[2] + k*ccyl->R[2*4+2]; - if ((ray->pos[0]-r[0])*(ray->pos[0]-r[0]) + - (ray->pos[1]-r[1])*(ray->pos[1]-r[1]) + - (ray->pos[2]-r[2])*(ray->pos[2]-r[2]) < ccyl->radius*ccyl->radius) { - inside_ccyl = 1; - } - } - - // compute ray collision with infinite cylinder, except for the case where - // the ray is outside the capped cylinder but within the infinite cylinder - // (it that case the ray can only hit endcaps) - if (!inside_ccyl && C < 0) { - // set k to cap position to check - if (k < 0) k = -lz2; else k = lz2; - } - else { - dReal uv = dDOT44(ccyl->R+2,ray->R+2); - r[0] = uv*ccyl->R[0*4+2] - ray->R[0*4+2]; - r[1] = uv*ccyl->R[1*4+2] - ray->R[1*4+2]; - r[2] = uv*ccyl->R[2*4+2] - ray->R[2*4+2]; - dReal A = dDOT(r,r); - dReal B = 2*dDOT(q,r); - k = B*B-4*A*C; - if (k < 0) { - // the ray does not intersect the infinite cylinder, but if the ray is - // inside and parallel to the cylinder axis it may intersect the end - // caps. set k to cap position to check. - if (!inside_ccyl) return 0; - if (uv < 0) k = -lz2; else k = lz2; - } - else { - k = dSqrt(k); - A = dRecip (2*A); - dReal alpha = (-B-k)*A; - if (alpha < 0) { - alpha = (-B+k)*A; - if (alpha < 0) return 0; - } - if (alpha > ray->length) return 0; - - // the ray intersects the infinite cylinder. check to see if the - // intersection point is between the caps - contact->pos[0] = ray->pos[0] + alpha*ray->R[0*4+2]; - contact->pos[1] = ray->pos[1] + alpha*ray->R[1*4+2]; - contact->pos[2] = ray->pos[2] + alpha*ray->R[2*4+2]; - q[0] = contact->pos[0] - ccyl->pos[0]; - q[1] = contact->pos[1] - ccyl->pos[1]; - q[2] = contact->pos[2] - ccyl->pos[2]; - k = dDOT14(q,ccyl->R+2); - dReal nsign = inside_ccyl ? REAL(-1.0) : REAL(1.0); - if (k >= -lz2 && k <= lz2) { - contact->normal[0] = nsign * (contact->pos[0] - - (ccyl->pos[0] + k*ccyl->R[0*4+2])); - contact->normal[1] = nsign * (contact->pos[1] - - (ccyl->pos[1] + k*ccyl->R[1*4+2])); - contact->normal[2] = nsign * (contact->pos[2] - - (ccyl->pos[2] + k*ccyl->R[2*4+2])); - dNormalize3 (contact->normal); - contact->depth = alpha; - return 1; - } - - // the infinite cylinder intersection point is not between the caps. - // set k to cap position to check. - if (k < 0) k = -lz2; else k = lz2; - } - } - - // check for ray intersection with the caps. k must indicate the cap - // position to check - q[0] = ccyl->pos[0] + k*ccyl->R[0*4+2]; - q[1] = ccyl->pos[1] + k*ccyl->R[1*4+2]; - q[2] = ccyl->pos[2] + k*ccyl->R[2*4+2]; - return ray_sphere_helper (ray,q,ccyl->radius,contact, inside_ccyl); -} - - -int dCollideRayPlane (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dRayClass); - dIASSERT (o2->type == dPlaneClass); - dxRay *ray = (dxRay*) o1; - dxPlane *plane = (dxPlane*) o2; - - dReal alpha = plane->p[3] - dDOT (plane->p,ray->pos); - // note: if alpha > 0 the starting point is below the plane - dReal nsign = (alpha > 0) ? REAL(-1.0) : REAL(1.0); - dReal k = dDOT14(plane->p,ray->R+2); - if (k==0) return 0; // ray parallel to plane - alpha /= k; - if (alpha < 0 || alpha > ray->length) return 0; - contact->pos[0] = ray->pos[0] + alpha*ray->R[0*4+2]; - contact->pos[1] = ray->pos[1] + alpha*ray->R[1*4+2]; - contact->pos[2] = ray->pos[2] + alpha*ray->R[2*4+2]; - contact->normal[0] = nsign*plane->p[0]; - contact->normal[1] = nsign*plane->p[1]; - contact->normal[2] = nsign*plane->p[2]; - contact->depth = alpha; - contact->g1 = ray; - contact->g2 = plane; - return 1; -} diff --git a/Extras/ode/ode/src/collision_std.h b/Extras/ode/ode/src/collision_std.h deleted file mode 100644 index 968e4247e..000000000 --- a/Extras/ode/ode/src/collision_std.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -the standard ODE geometry primitives. - -*/ - -#ifndef _ODE_COLLISION_STD_H_ -#define _ODE_COLLISION_STD_H_ - -#include -#include "collision_kernel.h" - - -// primitive collision functions - these have the dColliderFn interface, i.e. -// the same interface as dCollide(). the first and second geom arguments must -// have the specified types. - - -int dCollideSphereSphere (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideSphereBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideSpherePlane (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideBoxPlane (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip); -int dCollideCCylinderSphere (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideCCylinderBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideCCylinderCCylinder (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip); -int dCollideCCylinderPlane (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideRaySphere (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideRayBox (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -int dCollideRayCCylinder (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip); -int dCollideRayPlane (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); -///dCollideConvexConvex: see collision_convex.cpp for details -int dCollideConvexConvex(dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); - - -#endif diff --git a/Extras/ode/ode/src/collision_transform.cpp b/Extras/ode/ode/src/collision_transform.cpp deleted file mode 100644 index cab7ea240..000000000 --- a/Extras/ode/ode/src/collision_transform.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -geom transform - -*/ - -#include -#include -#include -#include -#include "collision_transform.h" -#include "collision_util.h" - -#ifdef _MSC_VER -#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" -#endif - -//**************************************************************************** -// dxGeomTransform class - -struct dxGeomTransform : public dxGeom { - dxGeom *obj; // object that is being transformed - int cleanup; // 1 to destroy obj when destroyed - int infomode; // 1 to put Tx geom in dContactGeom g1 - - // cached final object transform (body tx + relative tx). this is set by - // computeAABB(), and it is valid while the AABB is valid. - dVector3 final_pos; - dMatrix3 final_R; - - dxGeomTransform (dSpaceID space); - ~dxGeomTransform(); - void computeAABB(); - void computeFinalTx(); -}; - - -dxGeomTransform::dxGeomTransform (dSpaceID space) : dxGeom (space,1) -{ - type = dGeomTransformClass; - obj = 0; - cleanup = 0; - infomode = 0; - dSetZero (final_pos,4); - dRSetIdentity (final_R); -} - - -dxGeomTransform::~dxGeomTransform() -{ - if (obj && cleanup) delete obj; -} - - -void dxGeomTransform::computeAABB() -{ - if (!obj) { - dSetZero (aabb,6); - return; - } - - // backup the relative pos and R pointers of the encapsulated geom object - dReal *posbak = obj->pos; - dReal *Rbak = obj->R; - - // compute temporary pos and R for the encapsulated geom object - computeFinalTx(); - obj->pos = final_pos; - obj->R = final_R; - - // compute the AABB - obj->computeAABB(); - memcpy (aabb,obj->aabb,6*sizeof(dReal)); - - // restore the pos and R - obj->pos = posbak; - obj->R = Rbak; -} - - -// utility function for dCollideTransform() : compute final pos and R -// for the encapsulated geom object - -void dxGeomTransform::computeFinalTx() -{ - dMULTIPLY0_331 (final_pos,R,obj->pos); - final_pos[0] += pos[0]; - final_pos[1] += pos[1]; - final_pos[2] += pos[2]; - dMULTIPLY0_333 (final_R,R,obj->R); -} - -//**************************************************************************** -// collider function: -// this collides a transformed geom with another geom. the other geom can -// also be a transformed geom, but this case is not handled specially. - -int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dGeomTransformClass); - - dxGeomTransform *tr = (dxGeomTransform*) o1; - if (!tr->obj) return 0; - dUASSERT (tr->obj->parent_space==0, - "GeomTransform encapsulated object must not be in a space"); - dUASSERT (tr->obj->body==0, - "GeomTransform encapsulated object must not be attached " - "to a body"); - - // backup the relative pos and R pointers of the encapsulated geom object, - // and the body pointer - dReal *posbak = tr->obj->pos; - dReal *Rbak = tr->obj->R; - dxBody *bodybak = tr->obj->body; - - // compute temporary pos and R for the encapsulated geom object. - // note that final_pos and final_R are valid if no GEOM_AABB_BAD flag, - // because computeFinalTx() will have already been called in - // dxGeomTransform::computeAABB() - - if (tr->gflags & GEOM_AABB_BAD) tr->computeFinalTx(); - tr->obj->pos = tr->final_pos; - tr->obj->R = tr->final_R; - tr->obj->body = o1->body; - - // do the collision - int n = dCollide (tr->obj,o2,flags,contact,skip); - - // if required, adjust the 'g1' values in the generated contacts so that - // thay indicated the GeomTransform object instead of the encapsulated - // object. - if (tr->infomode) { - for (int i=0; ig1 = o1; - } - } - - // restore the pos, R and body - tr->obj->pos = posbak; - tr->obj->R = Rbak; - tr->obj->body = bodybak; - return n; -} - -//**************************************************************************** -// public API - -dGeomID dCreateGeomTransform (dSpaceID space) -{ - return new dxGeomTransform (space); -} - - -void dGeomTransformSetGeom (dGeomID g, dGeomID obj) -{ - dUASSERT (g && g->type == dGeomTransformClass, - "argument not a geom transform"); - dxGeomTransform *tr = (dxGeomTransform*) g; - if (tr->obj && tr->cleanup) delete tr->obj; - tr->obj = obj; -} - - -dGeomID dGeomTransformGetGeom (dGeomID g) -{ - dUASSERT (g && g->type == dGeomTransformClass, - "argument not a geom transform"); - dxGeomTransform *tr = (dxGeomTransform*) g; - return tr->obj; -} - - -void dGeomTransformSetCleanup (dGeomID g, int mode) -{ - dUASSERT (g && g->type == dGeomTransformClass, - "argument not a geom transform"); - dxGeomTransform *tr = (dxGeomTransform*) g; - tr->cleanup = mode; -} - - -int dGeomTransformGetCleanup (dGeomID g) -{ - dUASSERT (g && g->type == dGeomTransformClass, - "argument not a geom transform"); - dxGeomTransform *tr = (dxGeomTransform*) g; - return tr->cleanup; -} - - -void dGeomTransformSetInfo (dGeomID g, int mode) -{ - dUASSERT (g && g->type == dGeomTransformClass, - "argument not a geom transform"); - dxGeomTransform *tr = (dxGeomTransform*) g; - tr->infomode = mode; -} - - -int dGeomTransformGetInfo (dGeomID g) -{ - dUASSERT (g && g->type == dGeomTransformClass, - "argument not a geom transform"); - dxGeomTransform *tr = (dxGeomTransform*) g; - return tr->infomode; -} diff --git a/Extras/ode/ode/src/collision_transform.h b/Extras/ode/ode/src/collision_transform.h deleted file mode 100644 index 406a68791..000000000 --- a/Extras/ode/ode/src/collision_transform.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -geom transform - -*/ - -#ifndef _ODE_COLLISION_TRANSFORM_H_ -#define _ODE_COLLISION_TRANSFORM_H_ - -#include -#include "collision_kernel.h" - - -int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); - - -#endif diff --git a/Extras/ode/ode/src/collision_trimesh.cpp b/Extras/ode/ode/src/collision_trimesh.cpp deleted file mode 100644 index 4f3a23476..000000000 --- a/Extras/ode/ode/src/collision_trimesh.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// TriMesh code by Erwin de Vries. - -#include -#include -#include -#include -#include "collision_util.h" -#define TRIMESH_INTERNAL -#include "collision_trimesh_internal.h" - -// Trimesh data -dxTriMeshData::dxTriMeshData(){ -#ifndef dTRIMESH_ENABLED - dUASSERT(g, "dTRIMESH_ENABLED is not defined. Trimesh geoms will not work"); -#endif -} - -dxTriMeshData::~dxTriMeshData(){ - // -} - -void -dxTriMeshData::Build(const void* Vertices, int VertexStide, int VertexCount, - const void* Indices, int IndexCount, int TriStride, - const void* in_Normals, - bool Single){ - Mesh.SetNbTriangles(IndexCount / 3); - Mesh.SetNbVertices(VertexCount); - Mesh.SetPointers((IndexedTriangle*)Indices, (Point*)Vertices); - Mesh.SetStrides(TriStride, VertexStide); - Mesh.Single = Single; - - // Build tree - BuildSettings Settings; - // recommended in Opcode User Manual - //Settings.mRules = SPLIT_COMPLETE | SPLIT_SPLATTERPOINTS | SPLIT_GEOMCENTER; - // used in ODE, why? - //Settings.mRules = SPLIT_BEST_AXIS; - - // best compromise? - Settings.mRules = SPLIT_BEST_AXIS | SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER; - - - OPCODECREATE TreeBuilder; - TreeBuilder.mIMesh = &Mesh; - - TreeBuilder.mSettings = Settings; - TreeBuilder.mNoLeaf = true; - TreeBuilder.mQuantized = false; - - TreeBuilder.mKeepOriginal = false; - TreeBuilder.mCanRemap = false; - - - - BVTree.Build(TreeBuilder); - - // compute model space AABB - dVector3 AABBMax, AABBMin; - AABBMax[0] = AABBMax[1] = AABBMax[2] = (dReal) -dInfinity; - AABBMin[0] = AABBMin[1] = AABBMin[2] = (dReal) dInfinity; - if( Single ) { - const char* verts = (const char*)Vertices; - for( int i = 0; i < VertexCount; ++i ) { - const float* v = (const float*)verts; - if( v[0] > AABBMax[0] ) AABBMax[0] = v[0]; - if( v[1] > AABBMax[1] ) AABBMax[1] = v[1]; - if( v[2] > AABBMax[2] ) AABBMax[2] = v[2]; - if( v[0] < AABBMin[0] ) AABBMin[0] = v[0]; - if( v[1] < AABBMin[1] ) AABBMin[1] = v[1]; - if( v[2] < AABBMin[2] ) AABBMin[2] = v[2]; - verts += VertexStide; - } - } else { - const char* verts = (const char*)Vertices; - for( int i = 0; i < VertexCount; ++i ) { - const double* v = (const double*)verts; - if( v[0] > AABBMax[0] ) AABBMax[0] = (dReal) v[0]; - if( v[1] > AABBMax[1] ) AABBMax[1] = (dReal) v[1]; - if( v[2] > AABBMax[2] ) AABBMax[2] = (dReal) v[2]; - if( v[0] < AABBMin[0] ) AABBMin[0] = (dReal) v[0]; - if( v[1] < AABBMin[1] ) AABBMin[1] = (dReal) v[1]; - if( v[2] < AABBMin[2] ) AABBMin[2] = (dReal) v[2]; - verts += VertexStide; - } - } - AABBCenter[0] = (AABBMin[0] + AABBMax[0]) * REAL(0.5); - AABBCenter[1] = (AABBMin[1] + AABBMax[1]) * REAL(0.5); - AABBCenter[2] = (AABBMin[2] + AABBMax[2]) * REAL(0.5); - AABBExtents[0] = AABBMax[0] - AABBCenter[0]; - AABBExtents[1] = AABBMax[1] - AABBCenter[1]; - AABBExtents[2] = AABBMax[2] - AABBCenter[2]; - - // user data (not used by OPCODE) - for (int i=0; i<16; i++) - last_trans[i] = 0.0; - - Normals = (dReal *) in_Normals; -} - -dTriMeshDataID dGeomTriMeshDataCreate(){ - return new dxTriMeshData(); -} - -void dGeomTriMeshDataDestroy(dTriMeshDataID g){ - delete g; -} - -void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) -{ - dUASSERT(g, "argument not trimesh data"); - - double *elem; - - switch (data_id) { - case TRIMESH_FACE_NORMALS: - g->Normals = (dReal *) in_data; - break; - - case TRIMESH_LAST_TRANSFORMATION: - elem = (double *) in_data; - for (int i=0; i<16; i++) - g->last_trans[i] = (dReal) elem[i]; - - break; - default: - dUASSERT(data_id, "invalid data type"); - break; - } - - return; -} - - - -void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) -{ - dUASSERT(g, "argument not trimesh data"); - - switch (data_id) { - case TRIMESH_FACE_NORMALS: - return (void *) g->Normals; - break; - - case TRIMESH_LAST_TRANSFORMATION: - return (void *) g->last_trans; - break; - default: - dUASSERT(data_id, "invalid data type"); - break; - } - - return NULL; -} - - -void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride, - const void* Normals) -{ - dUASSERT(g, "argument not trimesh data"); - - g->Build(Vertices, VertexStride, VertexCount, - Indices, IndexCount, TriStride, - Normals, - true); -} - - -void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride) -{ - dGeomTriMeshDataBuildSingle1(g, Vertices, VertexStride, VertexCount, - Indices, IndexCount, TriStride, (void*)NULL); -} - - -void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride, - const void* Normals) -{ - dUASSERT(g, "argument not trimesh data"); - - g->Build(Vertices, VertexStride, VertexCount, - Indices, IndexCount, TriStride, - Normals, - false); -} - - -void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, - const void* Vertices, int VertexStride, int VertexCount, - const void* Indices, int IndexCount, int TriStride) { - dGeomTriMeshDataBuildDouble1(g, Vertices, VertexStride, VertexCount, - Indices, IndexCount, TriStride, NULL); -} - - -void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, - const dReal* Vertices, int VertexCount, - const int* Indices, int IndexCount, - const int* Normals){ -#ifdef dSINGLE - dGeomTriMeshDataBuildSingle1(g, - Vertices, 4 * sizeof(dReal), VertexCount, - Indices, IndexCount, 3 * sizeof(unsigned int), - Normals); -#else - dGeomTriMeshDataBuildDouble1(g, Vertices, 4 * sizeof(dReal), VertexCount, - Indices, IndexCount, 3 * sizeof(unsigned int), - Normals); -#endif -} - - -void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, - const dReal* Vertices, int VertexCount, - const int* Indices, int IndexCount) { - dGeomTriMeshDataBuildSimple1(g, - Vertices, VertexCount, Indices, IndexCount, - (const int*)NULL); -} - - -// Trimesh -PlanesCollider dxTriMesh::_PlanesCollider; -SphereCollider dxTriMesh::_SphereCollider; -OBBCollider dxTriMesh::_OBBCollider; -RayCollider dxTriMesh::_RayCollider; -AABBTreeCollider dxTriMesh::_AABBTreeCollider; -LSSCollider dxTriMesh::_LSSCollider; - -SphereCache dxTriMesh::defaultSphereCache; -OBBCache dxTriMesh::defaultBoxCache; -LSSCache dxTriMesh::defaultCCylinderCache; - -CollisionFaces dxTriMesh::Faces; - -dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1){ - type = dTriMeshClass; - - this->Data = Data; - - _RayCollider.SetDestination(&Faces); - - _PlanesCollider.SetTemporalCoherence(true); - - _SphereCollider.SetTemporalCoherence(true); - _SphereCollider.SetPrimitiveTests(false); - - - _OBBCollider.SetTemporalCoherence(true); - - // no first-contact test (i.e. return full contact info) - _AABBTreeCollider.SetFirstContact( false ); - // temporal coherence only works with "first conact" tests - _AABBTreeCollider.SetTemporalCoherence(false); - // Perform full BV-BV tests (true) or SAT-lite tests (false) - _AABBTreeCollider.SetFullBoxBoxTest( true ); - // Perform full Primitive-BV tests (true) or SAT-lite tests (false) - _AABBTreeCollider.SetFullPrimBoxTest( true ); - _LSSCollider.SetTemporalCoherence(false); - - /* TC has speed/space 'issues' that don't make it a clear - win by default on spheres/boxes. */ - this->doSphereTC = false; - this->doBoxTC = false; - this->doCCylinderTC = false; - - const char* msg; - if ((msg =_AABBTreeCollider.ValidateSettings())) - dDebug (d_ERR_UASSERT, msg, " (%s:%d)", __FILE__,__LINE__); - _LSSCollider.SetPrimitiveTests(false); - _LSSCollider.SetFirstContact(false); -} - -dxTriMesh::~dxTriMesh(){ - // -} - - -void dxTriMesh::ClearTCCache(){ - /* dxTriMesh::ClearTCCache uses dArray's setSize(0) to clear the caches - - but the destructor isn't called when doing this, so we would leak. - So, call the previous caches' containers' destructors by hand first. */ - int i, n; - n = SphereTCCache.size(); - for( i = 0; i < n; ++i ) { - SphereTCCache[i].~SphereTC(); - } - SphereTCCache.setSize(0); - n = BoxTCCache.size(); - for( i = 0; i < n; ++i ) { - BoxTCCache[i].~BoxTC(); - } - BoxTCCache.setSize(0); - n = CCylinderTCCache.size(); - for( i = 0; i < n; ++i ) { - CCylinderTCCache[i].~CCylinderTC(); - } - CCylinderTCCache.setSize(0); -} - - -int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]){ - return 1; -} - - -void dxTriMesh::computeAABB() { - const dxTriMeshData* d = Data; - dVector3 c; - - dMULTIPLY0_331( c, R, d->AABBCenter ); - - dReal xrange = dFabs(R[0] * Data->AABBExtents[0]) + - dFabs(R[1] * Data->AABBExtents[1]) + - dFabs(R[2] * Data->AABBExtents[2]); - dReal yrange = dFabs(R[4] * Data->AABBExtents[0]) + - dFabs(R[5] * Data->AABBExtents[1]) + - dFabs(R[6] * Data->AABBExtents[2]); - dReal zrange = dFabs(R[8] * Data->AABBExtents[0]) + - dFabs(R[9] * Data->AABBExtents[1]) + - dFabs(R[10] * Data->AABBExtents[2]); - - aabb[0] = c[0] + pos[0] - xrange; - aabb[1] = c[0] + pos[0] + xrange; - aabb[2] = c[1] + pos[1] - yrange; - aabb[3] = c[1] + pos[1] + yrange; - aabb[4] = c[2] + pos[2] - zrange; - aabb[5] = c[2] + pos[2] + zrange; -} - -dGeomID dCreateTriMesh(dSpaceID space, - dTriMeshDataID Data, - dTriCallback* Callback, - dTriArrayCallback* ArrayCallback, - dTriRayCallback* RayCallback) -{ - dxTriMesh* Geom = new dxTriMesh(space, Data); - Geom->Callback = Callback; - Geom->ArrayCallback = ArrayCallback; - Geom->RayCallback = RayCallback; - - return Geom; -} - -void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - ((dxTriMesh*)g)->Callback = Callback; -} - -dTriCallback* dGeomTriMeshGetCallback(dGeomID g) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - return ((dxTriMesh*)g)->Callback; -} - -void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - ((dxTriMesh*)g)->ArrayCallback = ArrayCallback; -} - -dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - return ((dxTriMesh*)g)->ArrayCallback; -} - -void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - ((dxTriMesh*)g)->RayCallback = Callback; -} - -dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - return ((dxTriMesh*)g)->RayCallback; -} - -void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - ((dxTriMesh*)g)->Data = Data; -} - -dTriMeshDataID dGeomTriMeshGetData(dGeomID g) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - return ((dxTriMesh*)g)->Data; -} - - - -void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - - switch (geomClass) - { - case dSphereClass: - ((dxTriMesh*)g)->doSphereTC = (1 == enable); - break; - case dBoxClass: - ((dxTriMesh*)g)->doBoxTC = (1 == enable); - break; - case dCCylinderClass: - ((dxTriMesh*)g)->doCCylinderTC = (1 == enable); - break; - } -} - -int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) -{ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - - switch (geomClass) - { - case dSphereClass: - if (((dxTriMesh*)g)->doSphereTC) - return 1; - break; - case dBoxClass: - if (((dxTriMesh*)g)->doBoxTC) - return 1; - break; - case dCCylinderClass: - if (((dxTriMesh*)g)->doCCylinderTC) - return 1; - break; - } - return 0; -} - -void dGeomTriMeshClearTCCache(dGeomID g){ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - - dxTriMesh* Geom = (dxTriMesh*)g; - Geom->ClearTCCache(); -} - -/* - * returns the TriMeshDataID - */ -dTriMeshDataID -dGeomTriMeshGetTriMeshDataID(dGeomID g) -{ - dxTriMesh* Geom = (dxTriMesh*) g; - return Geom->Data; -} - -// Getting data -void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2){ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - - dxTriMesh* Geom = (dxTriMesh*)g; - - const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); - const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); - - dVector3 v[3]; - FetchTriangle(Geom, Index, Position, Rotation, v); - - if (v0){ - (*v0)[0] = v[0][0]; - (*v0)[1] = v[0][1]; - (*v0)[2] = v[0][2]; - (*v0)[3] = v[0][3]; - } - if (v1){ - (*v1)[0] = v[1][0]; - (*v1)[1] = v[1][1]; - (*v1)[2] = v[1][2]; - (*v1)[3] = v[1][3]; - } - if (v2){ - (*v2)[0] = v[2][0]; - (*v2)[1] = v[2][1]; - (*v2)[2] = v[2][2]; - (*v2)[3] = v[2][3]; - } -} - -void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ - dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); - - dxTriMesh* Geom = (dxTriMesh*)g; - - const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); - const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); - - dVector3 dv[3]; - FetchTriangle(Geom, Index, Position, Rotation, dv); - - GetPointFromBarycentric(dv, u, v, Out); -} - -int dGeomTriMeshGetTriangleCount (dGeomID g) -{ - dxTriMesh* Geom = (dxTriMesh*)g; - return Geom->Data->Mesh.GetNbTriangles(); -} diff --git a/Extras/ode/ode/src/collision_trimesh_box.cpp b/Extras/ode/ode/src/collision_trimesh_box.cpp deleted file mode 100644 index ff01f9f53..000000000 --- a/Extras/ode/ode/src/collision_trimesh_box.cpp +++ /dev/null @@ -1,1309 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - - -/************************************************************************* - * * - * Triangle-box collider by Alen Ladavac and Vedran Klanac. * - * Ported to ODE by Oskari Nyman. * - * * - *************************************************************************/ - - -#include -#include -#include -#include -#include "collision_util.h" - -#define TRIMESH_INTERNAL -#include "collision_trimesh_internal.h" - -static void -GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, - dxGeom* in_g1, dxGeom* in_g2, - const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, - int& OutTriCount); - - -// largest number, double or float -#if defined(dSINGLE) - #define MAXVALUE FLT_MAX -#else - #define MAXVALUE DBL_MAX -#endif - - -// dVector3 -// r=a-b -#define SUBTRACT(a,b,r) do{ \ - (r)[0]=(a)[0] - (b)[0]; \ - (r)[1]=(a)[1] - (b)[1]; \ - (r)[2]=(a)[2] - (b)[2]; }while(0) - - -// dVector3 -// a=b -#define SET(a,b) do{ \ - (a)[0]=(b)[0]; \ - (a)[1]=(b)[1]; \ - (a)[2]=(b)[2]; }while(0) - - -// dMatrix3 -// a=b -#define SETM(a,b) do{ \ - (a)[0]=(b)[0]; \ - (a)[1]=(b)[1]; \ - (a)[2]=(b)[2]; \ - (a)[3]=(b)[3]; \ - (a)[4]=(b)[4]; \ - (a)[5]=(b)[5]; \ - (a)[6]=(b)[6]; \ - (a)[7]=(b)[7]; \ - (a)[8]=(b)[8]; \ - (a)[9]=(b)[9]; \ - (a)[10]=(b)[10]; \ - (a)[11]=(b)[11]; }while(0) - - -// dVector3 -// r=a+b -#define ADD(a,b,r) do{ \ - (r)[0]=(a)[0] + (b)[0]; \ - (r)[1]=(a)[1] + (b)[1]; \ - (r)[2]=(a)[2] + (b)[2]; }while(0) - - -// dMatrix3, int, dVector3 -// v=column a from m -#define GETCOL(m,a,v) do{ \ - (v)[0]=(m)[(a)+0]; \ - (v)[1]=(m)[(a)+4]; \ - (v)[2]=(m)[(a)+8]; }while(0) - - -// dVector4, dVector3 -// distance between plane p and point v -#define POINTDISTANCE(p,v) \ - ( p[0]*v[0] + p[1]*v[1] + p[2]*v[2] + p[3] ) - - -// dVector4, dVector3, dReal -// construct plane from normal and d -#define CONSTRUCTPLANE(plane,normal,d) do{ \ - plane[0]=normal[0];\ - plane[1]=normal[1];\ - plane[2]=normal[2];\ - plane[3]=d; }while(0) - - -// dVector3 -// length of vector a -#define LENGTHOF(a) \ - dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]) - - -// box data -static dMatrix3 mHullBoxRot; -static dVector3 vHullBoxPos; -static dVector3 vBoxHalfSize; - -// mesh data -static dVector3 vHullDstPos; - -// global collider data -static dVector3 vBestNormal; -static dReal fBestDepth; -static int iBestAxis = 0; -static int iExitAxis = 0; -static dVector3 vE0, vE1, vE2, vN; - -// global info for contact creation -static int iFlags; -static dContactGeom *ContactGeoms; -static int iStride; -static dxGeom *Geom1; -static dxGeom *Geom2; -static int ctContacts = 0; - - - -// Test normal of mesh face as separating axis for intersection -static BOOL _cldTestNormal( dReal fp0, dReal fR, dVector3 vNormal, int iAxis ) -{ - // calculate overlapping interval of box and triangle - dReal fDepth = fR+fp0; - - // if we do not overlap - if ( fDepth<0 ) { - // do nothing - return FALSE; - } - - // calculate normal's length - dReal fLength = LENGTHOF(vNormal); - // if long enough - if ( fLength > 0.0f ) { - - dReal fOneOverLength = 1.0f/fLength; - // normalize depth - fDepth = fDepth*fOneOverLength; - - // get minimum depth - if (fDepth=0); - fBestDepth = fDepth; - } - - } - - return TRUE; -} - - - - -// Test box axis as separating axis -static BOOL _cldTestFace( dReal fp0, dReal fp1, dReal fp2, dReal fR, dReal fD, - dVector3 vNormal, int iAxis ) -{ - dReal fMin, fMax; - - // find min of triangle interval - if ( fp0 < fp1 ) { - if ( fp0 < fp2 ) { - fMin = fp0; - } else { - fMin = fp2; - } - } else { - if( fp1 < fp2 ) { - fMin = fp1; - } else { - fMin = fp2; - } - } - - // find max of triangle interval - if ( fp0 > fp1 ) { - if ( fp0 > fp2 ) { - fMax = fp0; - } else { - fMax = fp2; - } - } else { - if( fp1 > fp2 ) { - fMax = fp1; - } else { - fMax = fp2; - } - } - - // calculate minimum and maximum depth - dReal fDepthMin = fR - fMin; - dReal fDepthMax = fMax + fR; - - // if we dont't have overlapping interval - if ( fDepthMin < 0 || fDepthMax < 0 ) { - // do nothing - return FALSE; - } - - dReal fDepth = 0; - - // if greater depth is on negative side - if ( fDepthMin > fDepthMax ) { - // use smaller depth (one from positive side) - fDepth = fDepthMax; - // flip normal direction - vNormal[0] = -vNormal[0]; - vNormal[1] = -vNormal[1]; - vNormal[2] = -vNormal[2]; - fD = -fD; - // if greater depth is on positive side - } else { - // use smaller depth (one from negative side) - fDepth = fDepthMin; - } - - - // if lower depth than best found so far - if (fDepth=0); - fBestDepth = fDepth; - } - - return TRUE; -} - - - - - -// Test cross products of box axis and triangle edges as separating axis -static BOOL _cldTestEdge( dReal fp0, dReal fp1, dReal fR, dReal fD, - dVector3 vNormal, int iAxis ) -{ - dReal fMin, fMax; - - // calculate min and max interval values - if ( fp0 < fp1 ) { - fMin = fp0; - fMax = fp1; - } else { - fMin = fp1; - fMax = fp0; - } - - // check if we overlapp - dReal fDepthMin = fR - fMin; - dReal fDepthMax = fMax + fR; - - // if we don't overlapp - if ( fDepthMin < 0 || fDepthMax < 0 ) { - // do nothing - return FALSE; - } - - dReal fDepth; - - - // if greater depth is on negative side - if ( fDepthMin > fDepthMax ) { - // use smaller depth (one from positive side) - fDepth = fDepthMax; - // flip normal direction - vNormal[0] = -vNormal[0]; - vNormal[1] = -vNormal[1]; - vNormal[2] = -vNormal[2]; - fD = -fD; - // if greater depth is on positive side - } else { - // use smaller depth (one from negative side) - fDepth = fDepthMin; - } - - // calculate normal's length - dReal fLength = LENGTHOF(vNormal); - - // if long enough - if ( fLength > 0.0f ) { - - // normalize depth - dReal fOneOverLength = 1.0f/fLength; - fDepth = fDepth*fOneOverLength; - fD*=fOneOverLength; - - - // if lower depth than best found so far (favor face over edges) - if (fDepth*1.5f=0); - fBestDepth = fDepth; - } - } - - return TRUE; -} - - - - - -// clip polygon with plane and generate new polygon points -static void _cldClipPolyToPlane( dVector3 avArrayIn[], int ctIn, - dVector3 avArrayOut[], int &ctOut, - const dVector4 &plPlane ) -{ - // start with no output points - ctOut = 0; - - int i0 = ctIn-1; - - // for each edge in input polygon - for (int i1=0; i1= 0 ) { - // emit point - avArrayOut[ctOut][0] = avArrayIn[i0][0]; - avArrayOut[ctOut][1] = avArrayIn[i0][1]; - avArrayOut[ctOut][2] = avArrayIn[i0][2]; - ctOut++; - } - - // if points are on different sides - if( (fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0) ) { - - // find intersection point of edge and plane - dVector3 vIntersectionPoint; - vIntersectionPoint[0]= avArrayIn[i0][0] - (avArrayIn[i0][0]-avArrayIn[i1][0])*fDistance0/(fDistance0-fDistance1); - vIntersectionPoint[1]= avArrayIn[i0][1] - (avArrayIn[i0][1]-avArrayIn[i1][1])*fDistance0/(fDistance0-fDistance1); - vIntersectionPoint[2]= avArrayIn[i0][2] - (avArrayIn[i0][2]-avArrayIn[i1][2])*fDistance0/(fDistance0-fDistance1); - - // emit intersection point - avArrayOut[ctOut][0] = vIntersectionPoint[0]; - avArrayOut[ctOut][1] = vIntersectionPoint[1]; - avArrayOut[ctOut][2] = vIntersectionPoint[2]; - ctOut++; - } - } - -} - - - - -static BOOL _cldTestSeparatingAxes(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) { - // reset best axis - iBestAxis = 0; - iExitAxis = -1; - fBestDepth = MAXVALUE; - - // calculate edges - SUBTRACT(v1,v0,vE0); - SUBTRACT(v2,v0,vE1); - SUBTRACT(vE1,vE0,vE2); - - // calculate poly normal - dCROSS(vN,=,vE0,vE1); - - // extract box axes as vectors - dVector3 vA0,vA1,vA2; - GETCOL(mHullBoxRot,0,vA0); - GETCOL(mHullBoxRot,1,vA1); - GETCOL(mHullBoxRot,2,vA2); - - // box halfsizes - dReal fa0 = vBoxHalfSize[0]; - dReal fa1 = vBoxHalfSize[1]; - dReal fa2 = vBoxHalfSize[2]; - - // calculate relative position between box and triangle - dVector3 vD; - SUBTRACT(v0,vHullBoxPos,vD); - - // calculate length of face normal - dReal fNLen = LENGTHOF( vN ); - - dVector3 vL; - dReal fp0, fp1, fp2, fR, fD; - - // Test separating axes for intersection - // ************************************************ - // Axis 1 - Triangle Normal - SET(vL,vN); - fp0 = dDOT(vL,vD); - fp1 = fp0; - fp2 = fp0; - fR=fa0*dFabs( dDOT(vN,vA0) ) + fa1 * dFabs( dDOT(vN,vA1) ) + fa2 * dFabs( dDOT(vN,vA2) ); - - - if( !_cldTestNormal( fp0, fR, vL, 1) ) { - iExitAxis=1; - return FALSE; - } - - // ************************************************ - - // Test Faces - // ************************************************ - // Axis 2 - Box X-Axis - SET(vL,vA0); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 + dDOT(vA0,vE0); - fp2 = fp0 + dDOT(vA0,vE1); - fR = fa0; - - - if( !_cldTestFace( fp0, fp1, fp2, fR, fD, vL, 2) ) { - iExitAxis=2; - return FALSE; - } - // ************************************************ - - // ************************************************ - // Axis 3 - Box Y-Axis - SET(vL,vA1); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 + dDOT(vA1,vE0); - fp2 = fp0 + dDOT(vA1,vE1); - fR = fa1; - - - if( !_cldTestFace( fp0, fp1, fp2, fR, fD, vL, 3) ) { - iExitAxis=3; - return FALSE; - } - - // ************************************************ - - // ************************************************ - // Axis 4 - Box Z-Axis - SET(vL,vA2); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 + dDOT(vA2,vE0); - fp2 = fp0 + dDOT(vA2,vE1); - fR = fa2; - - - if( !_cldTestFace( fp0, fp1, fp2, fR, fD, vL, 4) ) { - iExitAxis=4; - return FALSE; - } - - // ************************************************ - - // Test Edges - // ************************************************ - // Axis 5 - Box X-Axis cross Edge0 - dCROSS(vL,=,vA0,vE0); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0; - fp2 = fp0 + dDOT(vA0,vN); - fR = fa1 * dFabs(dDOT(vA2,vE0)) + fa2 * dFabs(dDOT(vA1,vE0)); - - - if( !_cldTestEdge( fp1, fp2, fR, fD, vL, 5) ) { - iExitAxis=5; - return FALSE; - } - // ************************************************ - - // ************************************************ - // Axis 6 - Box X-Axis cross Edge1 - dCROSS(vL,=,vA0,vE1); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 - dDOT(vA0,vN); - fp2 = fp0; - fR = fa1 * dFabs(dDOT(vA2,vE1)) + fa2 * dFabs(dDOT(vA1,vE1)); - - - if( !_cldTestEdge( fp0, fp1, fR, fD, vL, 6) ) { - iExitAxis=6; - return FALSE; - } - // ************************************************ - - // ************************************************ - // Axis 7 - Box X-Axis cross Edge2 - dCROSS(vL,=,vA0,vE2); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 - dDOT(vA0,vN); - fp2 = fp0 - dDOT(vA0,vN); - fR = fa1 * dFabs(dDOT(vA2,vE2)) + fa2 * dFabs(dDOT(vA1,vE2)); - - - if( !_cldTestEdge( fp0, fp1, fR, fD, vL, 7) ) { - iExitAxis=7; - return FALSE; - } - - // ************************************************ - - // ************************************************ - // Axis 8 - Box Y-Axis cross Edge0 - dCROSS(vL,=,vA1,vE0); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0; - fp2 = fp0 + dDOT(vA1,vN); - fR = fa0 * dFabs(dDOT(vA2,vE0)) + fa2 * dFabs(dDOT(vA0,vE0)); - - - if( !_cldTestEdge( fp0, fp2, fR, fD, vL, 8) ) { - iExitAxis=8; - return FALSE; - } - - // ************************************************ - - // ************************************************ - // Axis 9 - Box Y-Axis cross Edge1 - dCROSS(vL,=,vA1,vE1); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 - dDOT(vA1,vN); - fp2 = fp0; - fR = fa0 * dFabs(dDOT(vA2,vE1)) + fa2 * dFabs(dDOT(vA0,vE1)); - - - if( !_cldTestEdge( fp0, fp1, fR, fD, vL, 9) ) { - iExitAxis=9; - return FALSE; - } - - // ************************************************ - - // ************************************************ - // Axis 10 - Box Y-Axis cross Edge2 - dCROSS(vL,=,vA1,vE2); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 - dDOT(vA1,vN); - fp2 = fp0 - dDOT(vA1,vN); - fR = fa0 * dFabs(dDOT(vA2,vE2)) + fa2 * dFabs(dDOT(vA0,vE2)); - - - if( !_cldTestEdge( fp0, fp1, fR, fD, vL, 10) ) { - iExitAxis=10; - return FALSE; - } - - // ************************************************ - - // ************************************************ - // Axis 11 - Box Z-Axis cross Edge0 - dCROSS(vL,=,vA2,vE0); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0; - fp2 = fp0 + dDOT(vA2,vN); - fR = fa0 * dFabs(dDOT(vA1,vE0)) + fa1 * dFabs(dDOT(vA0,vE0)); - - - if( !_cldTestEdge( fp0, fp2, fR, fD, vL, 11) ) { - iExitAxis=11; - return FALSE; - } - // ************************************************ - - // ************************************************ - // Axis 12 - Box Z-Axis cross Edge1 - dCROSS(vL,=,vA2,vE1); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 - dDOT(vA2,vN); - fp2 = fp0; - fR = fa0 * dFabs(dDOT(vA1,vE1)) + fa1 * dFabs(dDOT(vA0,vE1)); - - - if( !_cldTestEdge( fp0, fp1, fR, fD, vL, 12) ) { - iExitAxis=12; - return FALSE; - } - // ************************************************ - - // ************************************************ - // Axis 13 - Box Z-Axis cross Edge2 - dCROSS(vL,=,vA2,vE2); - fD = dDOT(vL,vN)/fNLen; - fp0 = dDOT(vL,vD); - fp1 = fp0 - dDOT(vA2,vN); - fp2 = fp0 - dDOT(vA2,vN); - fR = fa0 * dFabs(dDOT(vA1,vE2)) + fa1 * dFabs(dDOT(vA0,vE2)); - - - if( !_cldTestEdge( fp0, fp1, fR, fD, vL, 13) ) { - iExitAxis=13; - return FALSE; - } - - // ************************************************ - return TRUE; -} - - - - - -// find two closest points on two lines -static BOOL _cldClosestPointOnTwoLines( dVector3 vPoint1, dVector3 vLenVec1, - dVector3 vPoint2, dVector3 vLenVec2, - dReal &fvalue1, dReal &fvalue2) -{ - // calulate denominator - dVector3 vp; - SUBTRACT(vPoint2,vPoint1,vp); - dReal fuaub = dDOT(vLenVec1,vLenVec2); - dReal fq1 = dDOT(vLenVec1,vp); - dReal fq2 = -dDOT(vLenVec2,vp); - dReal fd = 1.0f - fuaub * fuaub; - - // if denominator is positive - if (fd > 0.0f) { - // calculate points of closest approach - fd = 1.0f/fd; - fvalue1 = (fq1 + fuaub*fq2)*fd; - fvalue2 = (fuaub*fq1 + fq2)*fd; - return TRUE; - // otherwise - } else { - // lines are parallel - fvalue1 = 0.0f; - fvalue2 = 0.0f; - return FALSE; - } - -} - - - - - -// clip and generate contacts -static void _cldClipping(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2) { - - // if we have edge/edge intersection - if ( iBestAxis > 4 ) { - - dVector3 vub,vPb,vPa; - - SET(vPa,vHullBoxPos); - - // calculate point on box edge - for( int i=0; i<3; i++) { - dVector3 vRotCol; - GETCOL(mHullBoxRot,i,vRotCol); - dReal fSign = dDOT(vBestNormal,vRotCol) > 0 ? 1.0f : -1.0f; - - vPa[0] += fSign * vBoxHalfSize[i] * vRotCol[0]; - vPa[1] += fSign * vBoxHalfSize[i] * vRotCol[1]; - vPa[2] += fSign * vBoxHalfSize[i] * vRotCol[2]; - } - - int iEdge = (iBestAxis-5)%3; - - // decide which edge is on triangle - if ( iEdge == 0 ) { - SET(vPb,v0); - SET(vub,vE0); - } else if ( iEdge == 1) { - SET(vPb,v2); - SET(vub,vE1); - } else { - SET(vPb,v1); - SET(vub,vE2); - } - - - // setup direction parameter for face edge - dNormalize3(vub); - - dReal fParam1, fParam2; - - // setup direction parameter for box edge - dVector3 vua; - int col=(iBestAxis-5)/3; - GETCOL(mHullBoxRot,col,vua); - - // find two closest points on both edges - _cldClosestPointOnTwoLines( vPa, vua, vPb, vub, fParam1, fParam2 ); - vPa[0] += vua[0]*fParam1; - vPa[1] += vua[1]*fParam1; - vPa[2] += vua[2]*fParam1; - - vPb[0] += vub[0]*fParam2; - vPb[1] += vub[1]*fParam2; - vPb[2] += vub[2]*fParam2; - - // calculate collision point - dVector3 vPntTmp; - ADD(vPa,vPb,vPntTmp); - - vPntTmp[0]*=0.5f; - vPntTmp[1]*=0.5f; - vPntTmp[2]*=0.5f; - - // generate contact point between two closest points -#ifdef ORIG - if (ctContacts < (iFlags & 0x0ffff)) { - dContactGeom* Contact = SAFECONTACT(iFlags, ContactGeoms, ctContacts, iStride); - Contact->depth = fBestDepth; - SET(Contact->normal,vBestNormal); - SET(Contact->pos,vPntTmp); - Contact->g1 = Geom1; - Contact->g2 = Geom2; - ctContacts++; - } -#endif - GenerateContact(iFlags, ContactGeoms, iStride, Geom1, Geom2, - vPntTmp, vBestNormal, fBestDepth, ctContacts); - - - - // if triangle is the referent face then clip box to triangle face - } else if ( iBestAxis == 1 ) { - - - dVector3 vNormal2; - vNormal2[0]=-vBestNormal[0]; - vNormal2[1]=-vBestNormal[1]; - vNormal2[2]=-vBestNormal[2]; - - - // vNr is normal in box frame, pointing from triangle to box - dMatrix3 mTransposed; - mTransposed[0*4+0]=mHullBoxRot[0*4+0]; - mTransposed[0*4+1]=mHullBoxRot[1*4+0]; - mTransposed[0*4+2]=mHullBoxRot[2*4+0]; - - mTransposed[1*4+0]=mHullBoxRot[0*4+1]; - mTransposed[1*4+1]=mHullBoxRot[1*4+1]; - mTransposed[1*4+2]=mHullBoxRot[2*4+1]; - - mTransposed[2*4+0]=mHullBoxRot[0*4+2]; - mTransposed[2*4+1]=mHullBoxRot[1*4+2]; - mTransposed[2*4+2]=mHullBoxRot[2*4+2]; - - dVector3 vNr; - vNr[0]=mTransposed[0*4+0]*vNormal2[0]+ mTransposed[0*4+1]*vNormal2[1]+ mTransposed[0*4+2]*vNormal2[2]; - vNr[1]=mTransposed[1*4+0]*vNormal2[0]+ mTransposed[1*4+1]*vNormal2[1]+ mTransposed[1*4+2]*vNormal2[2]; - vNr[2]=mTransposed[2*4+0]*vNormal2[0]+ mTransposed[2*4+1]*vNormal2[1]+ mTransposed[2*4+2]*vNormal2[2]; - - - dVector3 vAbsNormal; - vAbsNormal[0] = dFabs( vNr[0] ); - vAbsNormal[1] = dFabs( vNr[1] ); - vAbsNormal[2] = dFabs( vNr[2] ); - - // get closest face from box - int iB0, iB1, iB2; - if (vAbsNormal[1] > vAbsNormal[0]) { - if (vAbsNormal[1] > vAbsNormal[2]) { - iB1 = 0; iB0 = 1; iB2 = 2; - } else { - iB1 = 0; iB2 = 1; iB0 = 2; - } - } else { - - if (vAbsNormal[0] > vAbsNormal[2]) { - iB0 = 0; iB1 = 1; iB2 = 2; - } else { - iB1 = 0; iB2 = 1; iB0 = 2; - } - } - - // Here find center of box face we are going to project - dVector3 vCenter; - dVector3 vRotCol; - GETCOL(mHullBoxRot,iB0,vRotCol); - - if (vNr[iB0] > 0) { - vCenter[0] = vHullBoxPos[0] - v0[0] - vBoxHalfSize[iB0] * vRotCol[0]; - vCenter[1] = vHullBoxPos[1] - v0[1] - vBoxHalfSize[iB0] * vRotCol[1]; - vCenter[2] = vHullBoxPos[2] - v0[2] - vBoxHalfSize[iB0] * vRotCol[2]; - } else { - vCenter[0] = vHullBoxPos[0] - v0[0] + vBoxHalfSize[iB0] * vRotCol[0]; - vCenter[1] = vHullBoxPos[1] - v0[1] + vBoxHalfSize[iB0] * vRotCol[1]; - vCenter[2] = vHullBoxPos[2] - v0[2] + vBoxHalfSize[iB0] * vRotCol[2]; - } - - // Here find 4 corner points of box - dVector3 avPoints[4]; - - dVector3 vRotCol2; - GETCOL(mHullBoxRot,iB1,vRotCol); - GETCOL(mHullBoxRot,iB2,vRotCol2); - - for(int x=0;x<3;x++) { - avPoints[0][x] = vCenter[x] + (vBoxHalfSize[iB1] * vRotCol[x]) - (vBoxHalfSize[iB2] * vRotCol2[x]); - avPoints[1][x] = vCenter[x] - (vBoxHalfSize[iB1] * vRotCol[x]) - (vBoxHalfSize[iB2] * vRotCol2[x]); - avPoints[2][x] = vCenter[x] - (vBoxHalfSize[iB1] * vRotCol[x]) + (vBoxHalfSize[iB2] * vRotCol2[x]); - avPoints[3][x] = vCenter[x] + (vBoxHalfSize[iB1] * vRotCol[x]) + (vBoxHalfSize[iB2] * vRotCol2[x]); - } - - - // clip Box face with 4 planes of triangle (1 face plane, 3 egde planes) - dVector3 avTempArray1[9]; - dVector3 avTempArray2[9]; - dVector4 plPlane; - - int iTempCnt1=0; - int iTempCnt2=0; - - // zeroify vectors - necessary? - for(int i=0; i<9; i++) { - avTempArray1[i][0]=0; - avTempArray1[i][1]=0; - avTempArray1[i][2]=0; - - avTempArray2[i][0]=0; - avTempArray2[i][1]=0; - avTempArray2[i][2]=0; - } - - - // Normal plane - dVector3 vTemp; - vTemp[0]=-vN[0]; - vTemp[1]=-vN[1]; - vTemp[2]=-vN[2]; - dNormalize3(vTemp); - CONSTRUCTPLANE(plPlane,vTemp,0); - - _cldClipPolyToPlane( avPoints, 4, avTempArray1, iTempCnt1, plPlane ); - - - // Plane p0 - dVector3 vTemp2; - SUBTRACT(v1,v0,vTemp2); - dCROSS(vTemp,=,vN,vTemp2); - dNormalize3(vTemp); - CONSTRUCTPLANE(plPlane,vTemp,0); - - _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); - - - // Plane p1 - SUBTRACT(v2,v1,vTemp2); - dCROSS(vTemp,=,vN,vTemp2); - dNormalize3(vTemp); - SUBTRACT(v0,v2,vTemp2); - CONSTRUCTPLANE(plPlane,vTemp,dDOT(vTemp2,vTemp)); - - _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); - - - // Plane p2 - SUBTRACT(v0,v2,vTemp2); - dCROSS(vTemp,=,vN,vTemp2); - dNormalize3(vTemp); - CONSTRUCTPLANE(plPlane,vTemp,0); - - _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); - - - // END of clipping polygons - - - - // for each generated contact point - for ( int i=0; i 0) { - fTempDepth = 0; - } - - dVector3 vPntTmp; - ADD(avTempArray2[i],v0,vPntTmp); - -#ifdef ORIG - if (ctContacts < (iFlags & 0x0ffff)) { - dContactGeom* Contact = SAFECONTACT(iFlags, ContactGeoms, ctContacts, iStride); - - Contact->depth = -fTempDepth; - SET(Contact->normal,vBestNormal); - SET(Contact->pos,vPntTmp); - Contact->g1 = Geom1; - Contact->g2 = Geom2; - ctContacts++; - } -#endif - GenerateContact(iFlags, ContactGeoms, iStride, Geom1, Geom2, - vPntTmp, vBestNormal, -fTempDepth, ctContacts); - } - - //dAASSERT(ctContacts>0); - - // if box face is the referent face, then clip triangle on box face - } else { // 2 <= if iBestAxis <= 4 - - // get normal of box face - dVector3 vNormal2; - SET(vNormal2,vBestNormal); - - // get indices of box axes in correct order - int iA0,iA1,iA2; - iA0 = iBestAxis-2; - if ( iA0 == 0 ) { - iA1 = 1; iA2 = 2; - } else if ( iA0 == 1 ) { - iA1 = 0; iA2 = 2; - } else { - iA1 = 0; iA2 = 1; - } - - dVector3 avPoints[3]; - // calculate triangle vertices in box frame - SUBTRACT(v0,vHullBoxPos,avPoints[0]); - SUBTRACT(v1,vHullBoxPos,avPoints[1]); - SUBTRACT(v2,vHullBoxPos,avPoints[2]); - - // CLIP Polygons - // define temp data for clipping - dVector3 avTempArray1[9]; - dVector3 avTempArray2[9]; - - int iTempCnt1, iTempCnt2; - - // zeroify vectors - necessary? - for(int i=0; i<9; i++) { - avTempArray1[i][0]=0; - avTempArray1[i][1]=0; - avTempArray1[i][2]=0; - - avTempArray2[i][0]=0; - avTempArray2[i][1]=0; - avTempArray2[i][2]=0; - } - - // clip triangle with 5 box planes (1 face plane, 4 edge planes) - - dVector4 plPlane; - - // Normal plane - dVector3 vTemp; - vTemp[0]=-vNormal2[0]; - vTemp[1]=-vNormal2[1]; - vTemp[2]=-vNormal2[2]; - CONSTRUCTPLANE(plPlane,vTemp,vBoxHalfSize[iA0]); - - _cldClipPolyToPlane( avPoints, 3, avTempArray1, iTempCnt1, plPlane ); - - - // Plane p0 - GETCOL(mHullBoxRot,iA1,vTemp); - CONSTRUCTPLANE(plPlane,vTemp,vBoxHalfSize[iA1]); - - _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); - - - // Plane p1 - GETCOL(mHullBoxRot,iA1,vTemp); - vTemp[0]=-vTemp[0]; - vTemp[1]=-vTemp[1]; - vTemp[2]=-vTemp[2]; - CONSTRUCTPLANE(plPlane,vTemp,vBoxHalfSize[iA1]); - - _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); - - - // Plane p2 - GETCOL(mHullBoxRot,iA2,vTemp); - CONSTRUCTPLANE(plPlane,vTemp,vBoxHalfSize[iA2]); - - _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); - - - // Plane p3 - GETCOL(mHullBoxRot,iA2,vTemp); - vTemp[0]=-vTemp[0]; - vTemp[1]=-vTemp[1]; - vTemp[2]=-vTemp[2]; - CONSTRUCTPLANE(plPlane,vTemp,vBoxHalfSize[iA2]); - - _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); - - - // for each generated contact point - for ( int i=0; i 0) { - fTempDepth = 0; - } - - // generate contact data - dVector3 vPntTmp; - ADD(avTempArray1[i],vHullBoxPos,vPntTmp); - -#ifdef ORIG - if (ctContacts < (iFlags & 0x0ffff)) { - dContactGeom* Contact = SAFECONTACT(iFlags, ContactGeoms, ctContacts, iStride); - - Contact->depth = -fTempDepth; - SET(Contact->normal,vBestNormal); - SET(Contact->pos,vPntTmp); - Contact->g1 = Geom1; - Contact->g2 = Geom2; - ctContacts++; - } -#endif - GenerateContact(iFlags, ContactGeoms, iStride, Geom1, Geom2, - vPntTmp, vBestNormal, -fTempDepth, ctContacts); - } - - //dAASSERT(ctContacts>0); - } - -} - - - - - -// test one mesh triangle on intersection with given box -static void _cldTestOneTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2)//, void *pvUser) -{ - // do intersection test and find best separating axis - if(!_cldTestSeparatingAxes(v0, v1, v2) ) { - // if not found do nothing - return; - } - - // if best separation axis is not found - if ( iBestAxis == 0 ) { - // this should not happen (we should already exit in that case) - //dMessage (0, "best separation axis not found"); - // do nothing - return; - } - - _cldClipping(v0, v1, v2); -} - - - - - -// box to mesh collider -int dCollideBTL(dxGeom* g1, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride){ - - dxTriMesh* TriMesh = (dxTriMesh*)g1; - - - // get source hull position, orientation and half size - const dMatrix3& mRotBox=*(const dMatrix3*)dGeomGetRotation(BoxGeom); - const dVector3& vPosBox=*(const dVector3*)dGeomGetPosition(BoxGeom); - - // to global - SETM(mHullBoxRot,mRotBox); - SET(vHullBoxPos,vPosBox); - - dGeomBoxGetLengths(BoxGeom, vBoxHalfSize); - vBoxHalfSize[0] *= 0.5f; - vBoxHalfSize[1] *= 0.5f; - vBoxHalfSize[2] *= 0.5f; - - - - // get destination hull position and orientation - const dMatrix3& mRotMesh=*(const dMatrix3*)dGeomGetRotation(TriMesh); - const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); - - // to global - SET(vHullDstPos,vPosMesh); - - - - // global info for contact creation - ctContacts = 0; - iStride=Stride; - iFlags=Flags; - ContactGeoms=Contacts; - Geom1=TriMesh; - Geom2=BoxGeom; - - - - // reset stuff - fBestDepth = MAXVALUE; - vBestNormal[0]=0; - vBestNormal[1]=0; - vBestNormal[2]=0; - - OBBCollider& Collider = TriMesh->_OBBCollider; - - - - - // Make OBB - OBB Box; - Box.mCenter.x = vPosBox[0]; - Box.mCenter.y = vPosBox[1]; - Box.mCenter.z = vPosBox[2]; - - - Box.mExtents.x = vBoxHalfSize[0]; - Box.mExtents.y = vBoxHalfSize[1]; - Box.mExtents.z = vBoxHalfSize[2]; - - Box.mRot.m[0][0] = mRotBox[0]; - Box.mRot.m[1][0] = mRotBox[1]; - Box.mRot.m[2][0] = mRotBox[2]; - - Box.mRot.m[0][1] = mRotBox[4]; - Box.mRot.m[1][1] = mRotBox[5]; - Box.mRot.m[2][1] = mRotBox[6]; - - Box.mRot.m[0][2] = mRotBox[8]; - Box.mRot.m[1][2] = mRotBox[9]; - Box.mRot.m[2][2] = mRotBox[10]; - - Matrix4x4 amatrix; - Matrix4x4 BoxMatrix = MakeMatrix(vPosBox, mRotBox, amatrix); - - Matrix4x4 InvBoxMatrix; - InvertPRMatrix(InvBoxMatrix, BoxMatrix); - - // TC results - if (TriMesh->doBoxTC) { - dxTriMesh::BoxTC* BoxTC = 0; - for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){ - if (TriMesh->BoxTCCache[i].Geom == BoxGeom){ - BoxTC = &TriMesh->BoxTCCache[i]; - break; - } - } - if (!BoxTC){ - TriMesh->BoxTCCache.push(dxTriMesh::BoxTC()); - - BoxTC = &TriMesh->BoxTCCache[TriMesh->BoxTCCache.size() - 1]; - BoxTC->Geom = BoxGeom; - BoxTC->FatCoeff = 1.1f; // Pierre recommends this, instead of 1.0 - } - - // Intersect - Collider.SetTemporalCoherence(true); - Collider.Collide(*BoxTC, Box, TriMesh->Data->BVTree, null, &MakeMatrix(vPosMesh, mRotMesh, amatrix)); - } - else { - Collider.SetTemporalCoherence(false); - Collider.Collide(dxTriMesh::defaultBoxCache, Box, TriMesh->Data->BVTree, null, - &MakeMatrix(vPosMesh, mRotMesh, amatrix)); - } - - if (!Collider.GetContactStatus()) { - /* no collision occurred */ - return 0; - } - - // Retrieve data - int TriCount = Collider.GetNbTouchedPrimitives(); - const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); - - if (TriCount != 0){ - if (TriMesh->ArrayCallback != null){ - TriMesh->ArrayCallback(TriMesh, BoxGeom, Triangles, TriCount); - } - - int OutTriCount = 0; - - // loop through all intersecting triangles - for (int i = 0; i < TriCount; i++){ - - - const int& Triint = Triangles[i]; - if (!Callback(TriMesh, BoxGeom, Triint)) continue; - - - dVector3 dv[3]; - FetchTriangle(TriMesh, Triint, vPosMesh, mRotMesh, dv); - - - // test this triangle - _cldTestOneTriangle(dv[0],dv[1],dv[2]); - } - } - - - return ctContacts; -} - - - - -// GenerateContact - Written by Jeff Smith (jeff@burri.to) -// Generate a "unique" contact. A unique contact has a unique -// position or normal. If the potential contact has the same -// position and normal as an existing contact, but a larger -// penetration depth, this new depth is used instead -// -static void -GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, - dxGeom* in_g1, dxGeom* in_g2, - const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, - int& OutTriCount) -{ - //if (in_Depth < 0.0) - //return; - - if (OutTriCount == (in_Flags & 0x0ffff)) - return; // contacts are full! - - dContactGeom* Contact; - dVector3 diff; - bool duplicate = false; - for (int i=0; ipos[j]; - if (dDOT(diff, diff) < 0.01) - { - // same normal? - if (fabs(dDOT(in_Normal, Contact->normal)) > 0.99) - { - if (in_Depth > Contact->depth) - Contact->depth = in_Depth; - duplicate = true; - } - } - } - - if (!duplicate) - { - // Add a new contact - Contact = SAFECONTACT(in_Flags, in_Contacts, OutTriCount, in_Stride); - - Contact->pos[0] = in_ContactPos[0]; - Contact->pos[1] = in_ContactPos[1]; - Contact->pos[2] = in_ContactPos[2]; - Contact->pos[3] = 0.0; - - Contact->normal[0] = in_Normal[0]; - Contact->normal[1] = in_Normal[1]; - Contact->normal[2] = in_Normal[2]; - Contact->normal[3] = 0.0; - - Contact->depth = in_Depth; - - Contact->g1 = in_g1; - Contact->g2 = in_g2; - - OutTriCount++; - } -} diff --git a/Extras/ode/ode/src/collision_trimesh_ccylinder.cpp b/Extras/ode/ode/src/collision_trimesh_ccylinder.cpp deleted file mode 100644 index 2b6f170b6..000000000 --- a/Extras/ode/ode/src/collision_trimesh_ccylinder.cpp +++ /dev/null @@ -1,1002 +0,0 @@ -/************************************************************************* -* * -* Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * -* All rights reserved. Email: russ@q12.org Web: www.q12.org * -* * -* This library is free software; you can redistribute it and/or * -* modify it under the terms of EITHER: * -* (1) The GNU Lesser General Public License as published by the Free * -* Software Foundation; either version 2.1 of the License, or (at * -* your option) any later version. The text of the GNU Lesser * -* General Public License is included with this library in the * -* file LICENSE.TXT. * -* (2) The BSD-style license that is included with this library in * -* the file LICENSE-BSD.TXT. * -* * -* This library 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 files * -* LICENSE.TXT and LICENSE-BSD.TXT for more details. * -* * -*************************************************************************/ - -/* - * Triangle-CCylinder(Capsule) collider by Alen Ladavac - * Ported to ODE by Nguyen Binh - */ - -// NOTES from Nguyen Binh -// 14 Apr : Seem to be robust -// There is a problem when you use original Step and set contact friction -// surface.mu = dInfinity; -// More description : -// When I dropped CCylinder over the bunny ears, it seems to stuck -// there for a while. I think the cause is when you set surface.mu = dInfinity; -// the friction force is too high so it just hang the capsule there. -// So the good cure for this is to set mu = around 1.5 (in my case) -// For StepFast1, this become as solid as rock : StepFast1 just approximate -// friction force. - -// NOTES from Croteam's Alen -//As a side note... there are some extra contacts that can be generated -//on the edge between two triangles, and if the capsule penetrates deeply into -//the triangle (usually happens with large mass or low FPS), some such -//contacts can in some cases push the capsule away from the edge instead of -//away from the two triangles. This shows up as capsule slowing down a bit -//when hitting an edge while sliding along a flat tesselated grid of -//triangles. This is only if capsule is standing upwards. - -//Same thing can appear whenever a smooth object (e.g sphere) hits such an -//edge, and it needs to be solved as a special case probably. This is a -//problem we are looking forward to address soon. - -#include -#include -#include -#include -#include "collision_util.h" - -#define TRIMESH_INTERNAL -#include "collision_trimesh_internal.h" - -// largest number, double or float -#if defined(dSINGLE) -#define MAX_REAL FLT_MAX -#define MIN_REAL (-FLT_MAX) -#else -#define MAX_REAL DBL_MAX -#define MIN_REAL (-DBL_MAX) -#endif - -// To optimize before send contacts to dynamic part -#define OPTIMIZE_CONTACTS - -// dVector3 -// r=a-b -#define SUBTRACT(a,b,r) \ - (r)[0]=(a)[0] - (b)[0]; \ - (r)[1]=(a)[1] - (b)[1]; \ - (r)[2]=(a)[2] - (b)[2]; - - -// dVector3 -// a=b -#define SET(a,b) \ - (a)[0]=(b)[0]; \ - (a)[1]=(b)[1]; \ - (a)[2]=(b)[2]; - - -// dMatrix3 -// a=b -#define SETM(a,b) \ - (a)[0]=(b)[0]; \ - (a)[1]=(b)[1]; \ - (a)[2]=(b)[2]; \ - (a)[3]=(b)[3]; \ - (a)[4]=(b)[4]; \ - (a)[5]=(b)[5]; \ - (a)[6]=(b)[6]; \ - (a)[7]=(b)[7]; \ - (a)[8]=(b)[8]; \ - (a)[9]=(b)[9]; \ - (a)[10]=(b)[10]; \ - (a)[11]=(b)[11]; - - -// dVector3 -// r=a+b -#define ADD(a,b,r) \ - (r)[0]=(a)[0] + (b)[0]; \ - (r)[1]=(a)[1] + (b)[1]; \ - (r)[2]=(a)[2] + (b)[2]; - - -// dMatrix3, int, dVector3 -// v=column a from m -#define GETCOL(m,a,v) \ - (v)[0]=(m)[(a)+0]; \ - (v)[1]=(m)[(a)+4]; \ - (v)[2]=(m)[(a)+8]; - - -// dVector4, dVector3 -// distance between plane p and point v -#define POINTDISTANCE(p,v) \ - ( p[0]*v[0] + p[1]*v[1] + p[2]*v[2] + p[3] ); \ - - -// dVector4, dVector3, dReal -// construct plane from normal and d -#define CONSTRUCTPLANE(plane,normal,d) \ - plane[0]=normal[0];\ - plane[1]=normal[1];\ - plane[2]=normal[2];\ - plane[3]=d; - - -// dVector3 -// length of vector a -#define LENGTHOF(a) \ - dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);\ - -inline dReal _length2OfVector3(dVector3 v) -{ - return (v[0] * v[0] + v[1] * v[1] + v[2] * v[2] ); -} - - -// Local contacts data -typedef struct _sLocalContactData -{ - dVector3 vPos; - dVector3 vNormal; - dReal fDepth; - int nFlags; // 0 = filtered out, 1 = OK -}sLocalContactData; - -static sLocalContactData *gLocalContacts; -static unsigned int ctContacts = 0; - -// capsule data -// real time data -static dMatrix3 mCapsuleRotation; -static dVector3 vCapsulePosition; -static dVector3 vCapsuleAxis; -// static data -static dReal vCapsuleRadius; -static dReal fCapsuleSize; - -// mesh data -static dMatrix4 mHullDstPl; -static dMatrix3 mTriMeshRot; -static dVector3 mTriMeshPos; -static dVector3 vE0, vE1, vE2; - -// Two geom -dxGeom* gCylinder; -dxGeom* gTriMesh; - -// global collider data -static dVector3 vNormal; -static dReal fBestDepth; -static dReal fBestCenter; -static dReal fBestrt; -static int iBestAxis; -static dVector3 vN = {0,0,0,0}; - -static dVector3 vV0; -static dVector3 vV1; -static dVector3 vV2; - -// ODE contact's specific -static int iFlags; -static dContactGeom *ContactGeoms; -static int iStride; - -// Capsule lie on axis number 3 = (Z axis) -static const int nCAPSULE_AXIS = 2; - -// Use to classify contacts to be "near" in position -static const dReal fSameContactPositionEpsilon = REAL(0.0001); // 1e-4 -// Use to classify contacts to be "near" in normal direction -static const dReal fSameContactNormalEpsilon = REAL(0.0001); // 1e-4 - - -// If this two contact can be classified as "near" -inline int _IsNearContacts(sLocalContactData& c1,sLocalContactData& c2) -{ - int bPosNear = 0; - int bSameDir = 0; - dVector3 vDiff; - - // First check if they are "near" in position - SUBTRACT(c1.vPos,c2.vPos,vDiff); - if ( (dFabs(vDiff[0]) < fSameContactPositionEpsilon) - &&(dFabs(vDiff[1]) < fSameContactPositionEpsilon) - &&(dFabs(vDiff[2]) < fSameContactPositionEpsilon)) - { - bPosNear = 1; - } - - // Second check if they are "near" in normal direction - SUBTRACT(c1.vNormal,c2.vNormal,vDiff); - if ( (dFabs(vDiff[0]) < fSameContactNormalEpsilon) - &&(dFabs(vDiff[1]) < fSameContactNormalEpsilon) - &&(dFabs(vDiff[2]) < fSameContactNormalEpsilon) ) - { - bSameDir = 1; - } - - // Will be "near" if position and normal direction are "near" - return (bPosNear && bSameDir); -} - -inline int _IsBetter(sLocalContactData& c1,sLocalContactData& c2) -{ - // The not better will be throw away - // You can change the selection criteria here - return (c1.fDepth > c2.fDepth); -} - -// iterate through gLocalContacts and filtered out "near contact" -inline void _OptimizeLocalContacts() -{ - int nContacts = ctContacts; - - for (int i = 0; i < nContacts-1; i++) - { - for (int j = i+1; j < nContacts; j++) - { - if (_IsNearContacts(gLocalContacts[i],gLocalContacts[j])) - { - // If they are seem to be the samed then filtered - // out the least penetrate one - if (_IsBetter(gLocalContacts[j],gLocalContacts[i])) - { - gLocalContacts[i].nFlags = 0; // filtered 1st contact - } - else - { - gLocalContacts[j].nFlags = 0; // filtered 2nd contact - } - - // NOTE - // There is other way is to add two depth together but - // it not work so well. Why??? - } - } - } -} - -inline int _ProcessLocalContacts() -{ - if (ctContacts == 0) - { - delete[] gLocalContacts; - return 0; - } - -#ifdef OPTIMIZE_CONTACTS - if (ctContacts > 1) - { - // Can be optimized... - _OptimizeLocalContacts(); - } -#endif - - unsigned int iContact = 0; - dContactGeom* Contact = 0; - - int nFinalContact = 0; - - for (iContact = 0; iContact < ctContacts; iContact ++) - { - // Ensure that we haven't created too many contacts - if( nFinalContact >= (iFlags & NUMC_MASK)) - { - break; - } - - if (1 == gLocalContacts[iContact].nFlags) - { - Contact = SAFECONTACT(iFlags, ContactGeoms, nFinalContact, iStride); - Contact->depth = gLocalContacts[iContact].fDepth; - SET(Contact->normal,gLocalContacts[iContact].vNormal); - SET(Contact->pos,gLocalContacts[iContact].vPos); - Contact->g1 = gCylinder; - Contact->g2 = gTriMesh; - - nFinalContact++; - } - } - // debug - //if (nFinalContact != ctContacts) - //{ - // printf("[Info] %d contacts generated,%d filtered.\n",ctContacts,ctContacts-nFinalContact); - //} - - delete[] gLocalContacts; - return nFinalContact; -} - -BOOL _cldClipEdgeToPlane( dVector3 &vEpnt0, dVector3 &vEpnt1, const dVector4& plPlane) -{ - // calculate distance of edge points to plane - dReal fDistance0 = POINTDISTANCE( plPlane, vEpnt0 ); - dReal fDistance1 = POINTDISTANCE( plPlane, vEpnt1 ); - - // if both points are behind the plane - if ( fDistance0 < 0 && fDistance1 < 0 ) - { - // do nothing - return FALSE; - // if both points in front of the plane - } else if ( fDistance0 > 0 && fDistance1 > 0 ) - { - // accept them - return TRUE; - // if we have edge/plane intersection - } else if ((fDistance0 > 0 && fDistance1 < 0) || ( fDistance0 < 0 && fDistance1 > 0)) - { - - // find intersection point of edge and plane - dVector3 vIntersectionPoint; - vIntersectionPoint[0]= vEpnt0[0]-(vEpnt0[0]-vEpnt1[0])*fDistance0/(fDistance0-fDistance1); - vIntersectionPoint[1]= vEpnt0[1]-(vEpnt0[1]-vEpnt1[1])*fDistance0/(fDistance0-fDistance1); - vIntersectionPoint[2]= vEpnt0[2]-(vEpnt0[2]-vEpnt1[2])*fDistance0/(fDistance0-fDistance1); - - // clamp correct edge to intersection point - if ( fDistance0 < 0 ) - { - SET(vEpnt0,vIntersectionPoint); - } else - { - SET(vEpnt1,vIntersectionPoint); - } - return TRUE; - } - return TRUE; -} - -static BOOL _cldTestAxis(const dVector3 &v0, - const dVector3 &v1, - const dVector3 &v2, - dVector3 vAxis, - int iAxis, - BOOL bNoFlip = FALSE) -{ - - // calculate length of separating axis vector - dReal fL = LENGTHOF(vAxis); - // if not long enough - // TODO : dReal epsilon please - if ( fL < 1e-5f ) - { - // do nothing - //iLastOutAxis = 0; - return TRUE; - } - - // otherwise normalize it - dNormalize3(vAxis); - - // project capsule on vAxis - dReal frc = dFabs(dDOT(vCapsuleAxis,vAxis))*(fCapsuleSize*REAL(0.5)-vCapsuleRadius) + vCapsuleRadius; - - // project triangle on vAxis - dReal afv[3]; - afv[0] = dDOT( vV0 , vAxis ); - afv[1] = dDOT( vV1 , vAxis ); - afv[2] = dDOT( vV2 , vAxis ); - - dReal fMin = MAX_REAL; - dReal fMax = MIN_REAL; - - // for each vertex - for(int i=0; i<3; i++) - { - // find minimum - if (afv[i]fMax) - { - fMax = afv[i]; - } - } - - // find triangle's center of interval on axis - dReal fCenter = (fMin+fMax)*REAL(0.5); - // calculate triangles half interval - dReal fTriangleRadius = (fMax-fMin)*REAL(0.5); - - // if they do not overlap, - if( dFabs(fCenter) > ( frc + fTriangleRadius ) ) - { - // exit, we have no intersection - return FALSE; - } - - // calculate depth - dReal fDepth = dFabs(fCenter) - (frc+fTriangleRadius); - - // if greater then best found so far - if ( fDepth > fBestDepth ) - { - // remember depth - fBestDepth = fDepth; - fBestCenter = fCenter; - fBestrt = fTriangleRadius; - - vNormal[0] = vAxis[0]; - vNormal[1] = vAxis[1]; - vNormal[2] = vAxis[2]; - - iBestAxis = iAxis; - - // flip normal if interval is wrong faced - if (fCenter<0 && !bNoFlip) - { - vNormal[0] = -vNormal[0]; - vNormal[1] = -vNormal[1]; - vNormal[2] = -vNormal[2]; - - fBestCenter = -fCenter; - } - } - - return TRUE; -} - -// helper for less key strokes -inline void _CalculateAxis(const dVector3& v1, - const dVector3& v2, - const dVector3& v3, - const dVector3& v4, - dVector3& r) -{ - dVector3 t1; - dVector3 t2; - - SUBTRACT(v1,v2,t1); - dCROSS(t2,=,t1,v3); - dCROSS(r,=,t2,v4); -} - -static BOOL _cldTestSeparatingAxesOfCapsule(const dVector3 &v0, - const dVector3 &v1, - const dVector3 &v2) -{ - // calculate caps centers in absolute space - dVector3 vCp0; - vCp0[0] = vCapsulePosition[0] + vCapsuleAxis[0]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCp0[1] = vCapsulePosition[1] + vCapsuleAxis[1]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCp0[2] = vCapsulePosition[2] + vCapsuleAxis[2]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - - dVector3 vCp1; - vCp1[0] = vCapsulePosition[0] - vCapsuleAxis[0]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCp1[1] = vCapsulePosition[1] - vCapsuleAxis[1]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCp1[2] = vCapsulePosition[2] - vCapsuleAxis[2]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - - // reset best axis - iBestAxis = 0; - // reset best depth - fBestDepth = -MAX_REAL; - // reset separating axis vector - dVector3 vAxis = {REAL(0.0),REAL(0.0),REAL(0.0),REAL(0.0)}; - - // Epsilon value for checking axis vector length - const dReal fEpsilon = 1e-6f; - - // Translate triangle to Cc cord. - SUBTRACT(v0 , vCapsulePosition, vV0); - SUBTRACT(v1 , vCapsulePosition, vV1); - SUBTRACT(v2 , vCapsulePosition, vV2); - - // We begin to test for 19 separating axis now - // I wonder does it help if we employ the method like ISA-GJK??? - // Or at least we should do experiment and find what axis will - // be most likely to be separating axis to check it first. - - // Original - // axis vN - //vAxis = -vN; - vAxis[0] = - vN[0]; - vAxis[1] = - vN[1]; - vAxis[2] = - vN[2]; - if (!_cldTestAxis( v0, v1, v2, vAxis, 1, TRUE)) - { - return FALSE; - } - - // axis CxE0 - Edge 0 - dCROSS(vAxis,=,vCapsuleAxis,vE0); - //vAxis = dCROSS( vCapsuleAxis cross vE0 ); - if( _length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 2)) { - return FALSE; - } - } - - // axis CxE1 - Edge 1 - dCROSS(vAxis,=,vCapsuleAxis,vE1); - //vAxis = ( vCapsuleAxis cross vE1 ); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 3)) { - return FALSE; - } - } - - // axis CxE2 - Edge 2 - //vAxis = ( vCapsuleAxis cross vE2 ); - dCROSS(vAxis,=,vCapsuleAxis,vE2); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 4)) { - return FALSE; - } - } - - // first capsule point - // axis ((Cp0-V0) x E0) x E0 - _CalculateAxis(vCp0,v0,vE0,vE0,vAxis); -// vAxis = ( ( vCp0-v0) cross vE0 ) cross vE0; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 5)) { - return FALSE; - } - } - - // axis ((Cp0-V1) x E1) x E1 - _CalculateAxis(vCp0,v1,vE1,vE1,vAxis); - //vAxis = ( ( vCp0-v1) cross vE1 ) cross vE1; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 6)) { - return FALSE; - } - } - - // axis ((Cp0-V2) x E2) x E2 - _CalculateAxis(vCp0,v2,vE2,vE2,vAxis); - //vAxis = ( ( vCp0-v2) cross vE2 ) cross vE2; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 7)) { - return FALSE; - } - } - - // second capsule point - // axis ((Cp1-V0) x E0) x E0 - _CalculateAxis(vCp1,v0,vE0,vE0,vAxis); - //vAxis = ( ( vCp1-v0 ) cross vE0 ) cross vE0; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 8)) { - return FALSE; - } - } - - // axis ((Cp1-V1) x E1) x E1 - _CalculateAxis(vCp1,v1,vE1,vE1,vAxis); - //vAxis = ( ( vCp1-v1 ) cross vE1 ) cross vE1; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 9)) { - return FALSE; - } - } - - // axis ((Cp1-V2) x E2) x E2 - _CalculateAxis(vCp1,v2,vE2,vE2,vAxis); - //vAxis = ( ( vCp1-v2 ) cross vE2 ) cross vE2; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 10)) { - return FALSE; - } - } - - // first vertex on triangle - // axis ((V0-Cp0) x C) x C - _CalculateAxis(v0,vCp0,vCapsuleAxis,vCapsuleAxis,vAxis); - //vAxis = ( ( v0-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 11)) { - return FALSE; - } - } - - // second vertex on triangle - // axis ((V1-Cp0) x C) x C - _CalculateAxis(v1,vCp0,vCapsuleAxis,vCapsuleAxis,vAxis); - //vAxis = ( ( v1-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 12)) { - return FALSE; - } - } - - // third vertex on triangle - // axis ((V2-Cp0) x C) x C - _CalculateAxis(v2,vCp0,vCapsuleAxis,vCapsuleAxis,vAxis); - //vAxis = ( ( v2-vCp0 ) cross vCapsuleAxis ) cross vCapsuleAxis; - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 13)) { - return FALSE; - } - } - - // Test as separating axes direction vectors between each triangle - // edge and each capsule's cap center - - // first triangle vertex and first capsule point - //vAxis = v0 - vCp0; - SUBTRACT(v0,vCp0,vAxis); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 14)) { - return FALSE; - } - } - - // second triangle vertex and first capsule point - //vAxis = v1 - vCp0; - SUBTRACT(v1,vCp0,vAxis); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 15)) { - return FALSE; - } - } - - // third triangle vertex and first capsule point - //vAxis = v2 - vCp0; - SUBTRACT(v2,vCp0,vAxis); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 16)) { - return FALSE; - } - } - - // first triangle vertex and second capsule point - //vAxis = v0 - vCp1; - SUBTRACT(v0,vCp1,vAxis); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 17)) { - return FALSE; - } - } - - // second triangle vertex and second capsule point - //vAxis = v1 - vCp1; - SUBTRACT(v1,vCp1,vAxis); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 18)) { - return FALSE; - } - } - - // third triangle vertex and second capsule point - //vAxis = v2 - vCp1; - SUBTRACT(v2,vCp1,vAxis); - if(_length2OfVector3( vAxis ) > fEpsilon ) { - if (!_cldTestAxis( v0, v1, v2, vAxis, 19)) { - return FALSE; - } - } - - return TRUE; -} - -// test one mesh triangle on intersection with capsule -static void _cldTestOneTriangleVSCCylinder( const dVector3 &v0, - const dVector3 &v1, - const dVector3 &v2 ) -{ - - // calculate edges - SUBTRACT(v1,v0,vE0); - SUBTRACT(v2,v1,vE1); - SUBTRACT(v0,v2,vE2); - - dVector3 _minus_vE0; - SUBTRACT(v0,v1,_minus_vE0); - - // calculate poly normal - dCROSS(vN,=,vE1,_minus_vE0); - dNormalize3(vN); - - // create plane from triangle - dReal plDistance = -dDOT(v0,vN); - dVector4 plTrianglePlane; - CONSTRUCTPLANE(plTrianglePlane,vN,plDistance); - - // calculate capsule distance to plane - dReal fDistanceCapsuleCenterToPlane = POINTDISTANCE(plTrianglePlane,vCapsulePosition); - - // Capsule must be over positive side of triangle - if(fDistanceCapsuleCenterToPlane < 0 /* && !bDoubleSided*/) - { - // if not don't generate contacts - return; - } - - dVector3 vPnt0; - SET (vPnt0,v0); - dVector3 vPnt1; - SET (vPnt1,v1); - dVector3 vPnt2; - SET (vPnt2,v2); - - if (fDistanceCapsuleCenterToPlane < 0 ) - { - SET (vPnt0,v0); - SET (vPnt1,v2); - SET (vPnt2,v1); - } - - // do intersection test and find best separating axis - if(!_cldTestSeparatingAxesOfCapsule(vPnt0, vPnt1, vPnt2) ) - { - // if not found do nothing - return; - } - - // if best separation axis is not found - if ( iBestAxis == 0 ) - { - // this should not happen (we should already exit in that case) - ASSERT(FALSE); - // do nothing - return; - } - - // calculate caps centers in absolute space - dVector3 vCposTrans; - vCposTrans[0] = vCapsulePosition[0] + vNormal[0]*vCapsuleRadius; - vCposTrans[1] = vCapsulePosition[1] + vNormal[1]*vCapsuleRadius; - vCposTrans[2] = vCapsulePosition[2] + vNormal[2]*vCapsuleRadius; - - dVector3 vCEdgePoint0; - vCEdgePoint0[0] = vCposTrans[0] + vCapsuleAxis[0]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCEdgePoint0[1] = vCposTrans[1] + vCapsuleAxis[1]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCEdgePoint0[2] = vCposTrans[2] + vCapsuleAxis[2]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - - dVector3 vCEdgePoint1; - vCEdgePoint1[0] = vCposTrans[0] - vCapsuleAxis[0]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCEdgePoint1[1] = vCposTrans[1] - vCapsuleAxis[1]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - vCEdgePoint1[2] = vCposTrans[2] - vCapsuleAxis[2]*(fCapsuleSize*REAL(0.5)-vCapsuleRadius); - - // transform capsule edge points into triangle space - vCEdgePoint0[0] -= vPnt0[0]; - vCEdgePoint0[1] -= vPnt0[1]; - vCEdgePoint0[2] -= vPnt0[2]; - - vCEdgePoint1[0] -= vPnt0[0]; - vCEdgePoint1[1] -= vPnt0[1]; - vCEdgePoint1[2] -= vPnt0[2]; - - dVector4 plPlane; - dVector3 _minus_vN; - _minus_vN[0] = -vN[0]; - _minus_vN[1] = -vN[1]; - _minus_vN[2] = -vN[2]; - // triangle plane - CONSTRUCTPLANE(plPlane,_minus_vN,0); - //plPlane = Plane4f( -vN, 0); - - if(!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) - { - return; - } - - // plane with edge 0 - dVector3 vTemp; - dCROSS(vTemp,=,vN,vE0); - CONSTRUCTPLANE(plPlane, vTemp, 1e-5f); - if(!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) - { - return; - } - - dCROSS(vTemp,=,vN,vE1); - CONSTRUCTPLANE(plPlane, vTemp, -(dDOT(vE0,vTemp)-1e-5f)); - if(!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) - { - return; - } - - dCROSS(vTemp,=,vN,vE2); - CONSTRUCTPLANE(plPlane, vTemp, 1e-5f); - if(!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { - return; - } - - // return capsule edge points into absolute space - vCEdgePoint0[0] += vPnt0[0]; - vCEdgePoint0[1] += vPnt0[1]; - vCEdgePoint0[2] += vPnt0[2]; - - vCEdgePoint1[0] += vPnt0[0]; - vCEdgePoint1[1] += vPnt0[1]; - vCEdgePoint1[2] += vPnt0[2]; - - // calculate depths for both contact points - SUBTRACT(vCEdgePoint0,vCapsulePosition,vTemp); - dReal fDepth0 = dDOT(vTemp,vNormal) - (fBestCenter-fBestrt); - SUBTRACT(vCEdgePoint1,vCapsulePosition,vTemp); - dReal fDepth1 = dDOT(vTemp,vNormal) - (fBestCenter-fBestrt); - - // clamp depths to zero - if(fDepth0 < 0) - { - fDepth0 = 0.0f; - } - - if(fDepth1 < 0 ) - { - fDepth1 = 0.0f; - } - - // Cached contacts's data - // contact 0 - if (ctContacts < (iFlags & NUMC_MASK)) { - gLocalContacts[ctContacts].fDepth = fDepth0; - SET(gLocalContacts[ctContacts].vNormal,vNormal); - SET(gLocalContacts[ctContacts].vPos,vCEdgePoint0); - gLocalContacts[ctContacts].nFlags = 1; - ctContacts++; - - if (ctContacts < (iFlags & NUMC_MASK)) { - // contact 1 - gLocalContacts[ctContacts].fDepth = fDepth1; - SET(gLocalContacts[ctContacts].vNormal,vNormal); - SET(gLocalContacts[ctContacts].vPos,vCEdgePoint1); - gLocalContacts[ctContacts].nFlags = 1; - ctContacts++; - } - } - -} - -// capsule - trimesh by CroTeam -// Ported by Nguyem Binh -int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) -{ - dxTriMesh* TriMesh = (dxTriMesh*)o1; - gCylinder = o2; - gTriMesh = o1; - - const dMatrix3* pRot = (const dMatrix3*) dGeomGetRotation(gCylinder); - memcpy(mCapsuleRotation,pRot,sizeof(dMatrix3)); - - const dVector3* pDst = (const dVector3*)dGeomGetPosition(gCylinder); - memcpy(vCapsulePosition,pDst,sizeof(dVector3)); - - vCapsuleAxis[0] = mCapsuleRotation[0*4 + nCAPSULE_AXIS]; - vCapsuleAxis[1] = mCapsuleRotation[1*4 + nCAPSULE_AXIS]; - vCapsuleAxis[2] = mCapsuleRotation[2*4 + nCAPSULE_AXIS]; - - // Get size of CCylinder - dGeomCCylinderGetParams(gCylinder,&vCapsuleRadius,&fCapsuleSize); - fCapsuleSize += 2*vCapsuleRadius; - - const dMatrix3* pTriRot = (const dMatrix3*)dGeomGetRotation(TriMesh); - memcpy(mTriMeshRot,pTriRot,sizeof(dMatrix3)); - - const dVector3* pTriPos = (const dVector3*)dGeomGetPosition(TriMesh); - memcpy(mTriMeshPos,pTriPos,sizeof(dVector3)); - - // global info for contact creation - iStride =skip; - iFlags =flags; - ContactGeoms =contact; - - // reset contact counter - ctContacts = 0; - // allocat local contact workspace - gLocalContacts = new sLocalContactData[(iFlags & NUMC_MASK)]; - - // reset best depth - fBestDepth = - MAX_REAL; - fBestCenter = 0; - fBestrt = 0; - - // reset collision normal - vNormal[0] = REAL(0.0); - vNormal[1] = REAL(0.0); - vNormal[2] = REAL(0.0); - - // Will it better to use LSS here? -> confirm Pierre. - OBBCollider& Collider = TriMesh->_OBBCollider; - - Point cCenter((float) vCapsulePosition[0],(float) vCapsulePosition[1],(float) vCapsulePosition[2]); - Point cExtents((float) vCapsuleRadius,(float) vCapsuleRadius,(float) fCapsuleSize/2); - - Matrix3x3 obbRot; - - obbRot[0][0] = (float) mCapsuleRotation[0]; - obbRot[1][0] = (float) mCapsuleRotation[1]; - obbRot[2][0] = (float) mCapsuleRotation[2]; - - obbRot[0][1] = (float) mCapsuleRotation[4]; - obbRot[1][1] = (float) mCapsuleRotation[5]; - obbRot[2][1] = (float) mCapsuleRotation[6]; - - obbRot[0][2] = (float) mCapsuleRotation[8]; - obbRot[1][2] = (float) mCapsuleRotation[9]; - obbRot[2][2] = (float) mCapsuleRotation[10]; - - OBB obbCCylinder(cCenter,cExtents,obbRot); - - Matrix4x4 CCylinderMatrix; - MakeMatrix(vCapsulePosition, mCapsuleRotation, CCylinderMatrix); - - Matrix4x4 MeshMatrix; - MakeMatrix(mTriMeshPos, mTriMeshRot, MeshMatrix); - - // TC results - if (TriMesh->doBoxTC) { - dxTriMesh::BoxTC* BoxTC = 0; - for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){ - if (TriMesh->BoxTCCache[i].Geom == gCylinder){ - BoxTC = &TriMesh->BoxTCCache[i]; - break; - } - } - if (!BoxTC){ - TriMesh->BoxTCCache.push(dxTriMesh::BoxTC()); - - BoxTC = &TriMesh->BoxTCCache[TriMesh->BoxTCCache.size() - 1]; - BoxTC->Geom = gCylinder; - BoxTC->FatCoeff = 1.0f; - } - - // Intersect - Collider.SetTemporalCoherence(true); - Collider.Collide(*BoxTC, obbCCylinder, TriMesh->Data->BVTree, null, &MeshMatrix); - } - else { - Collider.SetTemporalCoherence(false); - Collider.Collide(dxTriMesh::defaultBoxCache, obbCCylinder, TriMesh->Data->BVTree, null,&MeshMatrix); - } - - if (!Collider.GetContactStatus()) { - /* no collision occurred */ - return 0; - } - - // Retrieve data - int TriCount = Collider.GetNbTouchedPrimitives(); - const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); - - if (TriCount != 0) - { - if (TriMesh->ArrayCallback != null) - { - TriMesh->ArrayCallback(TriMesh, gCylinder, Triangles, TriCount); - } - - int OutTriCount = 0; - - // loop through all intersecting triangles - for (int i = 0; i < TriCount; i++) - { - if(ctContacts>=(iFlags & NUMC_MASK)) - { - break; - } - - const int& Triint = Triangles[i]; - if (!Callback(TriMesh, gCylinder, Triint)) continue; - - - dVector3 dv[3]; - FetchTriangle(TriMesh, Triint, mTriMeshPos, mTriMeshRot, dv); - - // test this triangle - _cldTestOneTriangleVSCCylinder(dv[0],dv[1],dv[2]); - - } - } - - return _ProcessLocalContacts(); -} - diff --git a/Extras/ode/ode/src/collision_trimesh_distance.cpp b/Extras/ode/ode/src/collision_trimesh_distance.cpp deleted file mode 100644 index 23aa3e612..000000000 --- a/Extras/ode/ode/src/collision_trimesh_distance.cpp +++ /dev/null @@ -1,2510 +0,0 @@ -// This file contains some code based on the code from Magic Software. - -// That code is available under a Free Source License Agreement - -// that can be found at http://www.magic-software.com/License/free.pdf - - - -#include - -#include - -#include - -#define TRIMESH_INTERNAL - -#include "collision_trimesh_internal.h" - - - -//------------------------------------------------------------------------------ - -/** - - @brief Finds the shortest distance squared between a point and a triangle. - - - - @param pfSParam Barycentric coordinate of triangle at point closest to p (u) - - @param pfTParam Barycentric coordinate of triangle at point closest to p (v) - - @return Shortest distance squared. - - - - The third Barycentric coordinate is implicit, ie. w = 1.0 - u - v - - - - Taken from: - - Magic Software, Inc. - - http://www.magic-software.com - -*/ - -dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin, - - const dVector3 triEdge0, const dVector3 triEdge1, - - dReal* pfSParam, dReal* pfTParam ) - -{ - - dVector3 kDiff; - - Vector3Subtract( triOrigin, p, kDiff ); - - dReal fA00 = dDOT( triEdge0, triEdge0 ); - - dReal fA01 = dDOT( triEdge0, triEdge1 ); - - dReal fA11 = dDOT( triEdge1, triEdge1 ); - - dReal fB0 = dDOT( kDiff, triEdge0 ); - - dReal fB1 = dDOT( kDiff, triEdge1 ); - - dReal fC = dDOT( kDiff, kDiff ); - - dReal fDet = dReal(fabs(fA00*fA11-fA01*fA01)); - - dReal fS = fA01*fB1-fA11*fB0; - - dReal fT = fA01*fB0-fA00*fB1; - - dReal fSqrDist; - - - - if ( fS + fT <= fDet ) - - { - - if ( fS < REAL(0.0) ) - - { - - if ( fT < REAL(0.0) ) // region 4 - - { - - if ( fB0 < REAL(0.0) ) - - { - - fT = REAL(0.0); - - if ( -fB0 >= fA00 ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else - - { - - fS = -fB0/fA00; - - fSqrDist = fB0*fS+fC; - - } - - } - - else - - { - - fS = REAL(0.0); - - if ( fB1 >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB1 >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = -fB1/fA11; - - fSqrDist = fB1*fT+fC; - - } - - } - - } - - else // region 3 - - { - - fS = REAL(0.0); - - if ( fB1 >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB1 >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = -fB1/fA11; - - fSqrDist = fB1*fT+fC; - - } - - } - - } - - else if ( fT < REAL(0.0) ) // region 5 - - { - - fT = REAL(0.0); - - if ( fB0 >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB0 >= fA00 ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else - - { - - fS = -fB0/fA00; - - fSqrDist = fB0*fS+fC; - - } - - } - - else // region 0 - - { - - // minimum at interior point - - if ( fDet == REAL(0.0) ) - - { - - fS = REAL(0.0); - - fT = REAL(0.0); - - fSqrDist = dInfinity; - - } - - else - - { - - float fInvDet = REAL(1.0)/fDet; - - fS *= fInvDet; - - fT *= fInvDet; - - fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + - - fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; - - } - - } - - } - - else - - { - - float fTmp0, fTmp1, fNumer, fDenom; - - - - if ( fS < REAL(0.0) ) // region 2 - - { - - fTmp0 = fA01 + fB0; - - fTmp1 = fA11 + fB1; - - if ( fTmp1 > fTmp0 ) - - { - - fNumer = fTmp1 - fTmp0; - - fDenom = fA00-REAL(2.0)*fA01+fA11; - - if ( fNumer >= fDenom ) - - { - - fS = REAL(1.0); - - fT = REAL(0.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else - - { - - fS = fNumer/fDenom; - - fT = REAL(1.0) - fS; - - fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + - - fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; - - } - - } - - else - - { - - fS = REAL(0.0); - - if ( fTmp1 <= REAL(0.0) ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else if ( fB1 >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else - - { - - fT = -fB1/fA11; - - fSqrDist = fB1*fT+fC; - - } - - } - - } - - else if ( fT < REAL(0.0) ) // region 6 - - { - - fTmp0 = fA01 + fB1; - - fTmp1 = fA00 + fB0; - - if ( fTmp1 > fTmp0 ) - - { - - fNumer = fTmp1 - fTmp0; - - fDenom = fA00-REAL(2.0)*fA01+fA11; - - if ( fNumer >= fDenom ) - - { - - fT = REAL(1.0); - - fS = REAL(0.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = fNumer/fDenom; - - fS = REAL(1.0) - fT; - - fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + - - fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; - - } - - } - - else - - { - - fT = REAL(0.0); - - if ( fTmp1 <= REAL(0.0) ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else if ( fB0 >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fSqrDist = fC; - - } - - else - - { - - fS = -fB0/fA00; - - fSqrDist = fB0*fS+fC; - - } - - } - - } - - else // region 1 - - { - - fNumer = fA11 + fB1 - fA01 - fB0; - - if ( fNumer <= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fDenom = fA00-REAL(2.0)*fA01+fA11; - - if ( fNumer >= fDenom ) - - { - - fS = REAL(1.0); - - fT = REAL(0.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else - - { - - fS = fNumer/fDenom; - - fT = REAL(1.0) - fS; - - fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + - - fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; - - } - - } - - } - - } - - - - if ( pfSParam ) - - *pfSParam = (float)fS; - - - - if ( pfTParam ) - - *pfTParam = (float)fT; - - - - return dReal(fabs(fSqrDist)); - -} - - - -//------------------------------------------------------------------------------ - -/** - - @brief Finds the shortest distance squared between two line segments. - - @param pfSegP0 t value for seg1 where the shortest distance between - - the segments exists. - - @param pfSegP0 t value for seg2 where the shortest distance between - - the segments exists. - - @return Shortest distance squared. - - - - Taken from: - - Magic Software, Inc. - - http://www.magic-software.com - -*/ - -dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction, - - const dVector3 seg2Origin, const dVector3 seg2Direction, - - dReal* pfSegP0, dReal* pfSegP1 ) - -{ - - const dReal gs_fTolerance = 1e-05f; - - dVector3 kDiff, kNegDiff, seg1NegDirection; - - Vector3Subtract( seg1Origin, seg2Origin, kDiff ); - - Vector3Negate( kDiff, kNegDiff ); - - dReal fA00 = dDOT( seg1Direction, seg1Direction ); - - Vector3Negate( seg1Direction, seg1NegDirection ); - - dReal fA01 = dDOT( seg1NegDirection, seg2Direction ); - - dReal fA11 = dDOT( seg2Direction, seg2Direction ); - - dReal fB0 = dDOT( kDiff, seg1Direction ); - - dReal fC = dDOT( kDiff, kDiff ); - - dReal fDet = dReal(fabs(fA00*fA11-fA01*fA01)); - - dReal fB1, fS, fT, fSqrDist, fTmp; - - - - if ( fDet >= gs_fTolerance ) - - { - - // line segments are not parallel - - fB1 = dDOT( kNegDiff, seg2Direction ); - - fS = fA01*fB1-fA11*fB0; - - fT = fA01*fB0-fA00*fB1; - - - - if ( fS >= REAL(0.0) ) - - { - - if ( fS <= fDet ) - - { - - if ( fT >= REAL(0.0) ) - - { - - if ( fT <= fDet ) // region 0 (interior) - - { - - // minimum at two interior points of 3D lines - - dReal fInvDet = REAL(1.0)/fDet; - - fS *= fInvDet; - - fT *= fInvDet; - - fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + - - fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; - - } - - else // region 3 (side) - - { - - fT = REAL(1.0); - - fTmp = fA01+fB0; - - if ( fTmp >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else if ( -fTmp >= fA00 ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB1+fTmp); - - } - - else - - { - - fS = -fTmp/fA00; - - fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; - - } - - } - - } - - else // region 7 (side) - - { - - fT = REAL(0.0); - - if ( fB0 >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB0 >= fA00 ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else - - { - - fS = -fB0/fA00; - - fSqrDist = fB0*fS+fC; - - } - - } - - } - - else - - { - - if ( fT >= REAL(0.0) ) - - { - - if ( fT <= fDet ) // region 1 (side) - - { - - fS = REAL(1.0); - - fTmp = fA01+fB1; - - if ( fTmp >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else if ( -fTmp >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); - - } - - else - - { - - fT = -fTmp/fA11; - - fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; - - } - - } - - else // region 2 (corner) - - { - - fTmp = fA01+fB0; - - if ( -fTmp <= fA00 ) - - { - - fT = REAL(1.0); - - if ( fTmp >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fS = -fTmp/fA00; - - fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; - - } - - } - - else - - { - - fS = REAL(1.0); - - fTmp = fA01+fB1; - - if ( fTmp >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else if ( -fTmp >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); - - } - - else - - { - - fT = -fTmp/fA11; - - fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; - - } - - } - - } - - } - - else // region 8 (corner) - - { - - if ( -fB0 < fA00 ) - - { - - fT = REAL(0.0); - - if ( fB0 >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fSqrDist = fC; - - } - - else - - { - - fS = -fB0/fA00; - - fSqrDist = fB0*fS+fC; - - } - - } - - else - - { - - fS = REAL(1.0); - - fTmp = fA01+fB1; - - if ( fTmp >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else if ( -fTmp >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); - - } - - else - - { - - fT = -fTmp/fA11; - - fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; - - } - - } - - } - - } - - } - - else - - { - - if ( fT >= REAL(0.0) ) - - { - - if ( fT <= fDet ) // region 5 (side) - - { - - fS = REAL(0.0); - - if ( fB1 >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB1 >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = -fB1/fA11; - - fSqrDist = fB1*fT+fC; - - } - - } - - else // region 4 (corner) - - { - - fTmp = fA01+fB0; - - if ( fTmp < REAL(0.0) ) - - { - - fT = REAL(1.0); - - if ( -fTmp >= fA00 ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB1+fTmp); - - } - - else - - { - - fS = -fTmp/fA00; - - fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; - - } - - } - - else - - { - - fS = REAL(0.0); - - if ( fB1 >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB1 >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = -fB1/fA11; - - fSqrDist = fB1*fT+fC; - - } - - } - - } - - } - - else // region 6 (corner) - - { - - if ( fB0 < REAL(0.0) ) - - { - - fT = REAL(0.0); - - if ( -fB0 >= fA00 ) - - { - - fS = REAL(1.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else - - { - - fS = -fB0/fA00; - - fSqrDist = fB0*fS+fC; - - } - - } - - else - - { - - fS = REAL(0.0); - - if ( fB1 >= REAL(0.0) ) - - { - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB1 >= fA11 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = -fB1/fA11; - - fSqrDist = fB1*fT+fC; - - } - - } - - } - - } - - } - - else - - { - - // line segments are parallel - - if ( fA01 > REAL(0.0) ) - - { - - // direction vectors form an obtuse angle - - if ( fB0 >= REAL(0.0) ) - - { - - fS = REAL(0.0); - - fT = REAL(0.0); - - fSqrDist = fC; - - } - - else if ( -fB0 <= fA00 ) - - { - - fS = -fB0/fA00; - - fT = REAL(0.0); - - fSqrDist = fB0*fS+fC; - - } - - else - - { - - //fB1 = -kDiff % seg2.m; - - fB1 = dDOT( kNegDiff, seg2Direction ); - - fS = REAL(1.0); - - fTmp = fA00+fB0; - - if ( -fTmp >= fA01 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA00+fA11+fC+REAL(2.0)*(fA01+fB0+fB1); - - } - - else - - { - - fT = -fTmp/fA01; - - fSqrDist = fA00+REAL(2.0)*fB0+fC+fT*(fA11*fT+REAL(2.0)*(fA01+fB1)); - - } - - } - - } - - else - - { - - // direction vectors form an acute angle - - if ( -fB0 >= fA00 ) - - { - - fS = REAL(1.0); - - fT = REAL(0.0); - - fSqrDist = fA00+REAL(2.0)*fB0+fC; - - } - - else if ( fB0 <= REAL(0.0) ) - - { - - fS = -fB0/fA00; - - fT = REAL(0.0); - - fSqrDist = fB0*fS+fC; - - } - - else - - { - - fB1 = dDOT( kNegDiff, seg2Direction ); - - fS = REAL(0.0); - - if ( fB0 >= -fA01 ) - - { - - fT = REAL(1.0); - - fSqrDist = fA11+REAL(2.0)*fB1+fC; - - } - - else - - { - - fT = -fB0/fA01; - - fSqrDist = fC+fT*(REAL(2.0)*fB1+fA11*fT); - - } - - } - - } - - } - - - - if ( pfSegP0 ) - - *pfSegP0 = fS; - - - - if ( pfSegP1 ) - - *pfSegP1 = fT; - - - - return dReal(fabs(fSqrDist)); - -} - - - -//------------------------------------------------------------------------------ - -/** - - @brief Finds the shortest distance squared between a line segment and - - a triangle. - - - - @param pfSegP t value for the line segment where the shortest distance between - - the segment and the triangle occurs. - - So the point along the segment that is the shortest distance - - away from the triangle can be obtained by (seg.end - seg.start) * t. - - @param pfTriP0 Barycentric coordinate of triangle at point closest to seg (u) - - @param pfTriP1 Barycentric coordinate of triangle at point closest to seg (v) - - @return Shortest distance squared. - - - - The third Barycentric coordinate is implicit, ie. w = 1.0 - u - v - - - - Taken from: - - Magic Software, Inc. - - http://www.magic-software.com - -*/ - -dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd, - - const dVector3 triOrigin, - - const dVector3 triEdge0, const dVector3 triEdge1, - - dReal* pfSegP, dReal* pfTriP0, dReal* pfTriP1 ) - -{ - - const dReal gs_fTolerance = 1e-06f; - - dVector3 segDirection, segNegDirection, kDiff, kNegDiff; - - Vector3Subtract( segEnd, segOrigin, segDirection ); - - Vector3Negate( segDirection, segNegDirection ); - - Vector3Subtract( triOrigin, segOrigin, kDiff ); - - Vector3Negate( kDiff, kNegDiff ); - - dReal fA00 = dDOT( segDirection, segDirection ); - - dReal fA01 = dDOT( segNegDirection, triEdge0 ); - - dReal fA02 = dDOT( segNegDirection, triEdge1 ); - - dReal fA11 = dDOT( triEdge0, triEdge0 ); - - dReal fA12 = dDOT( triEdge0, triEdge1 ); - - dReal fA22 = dDOT( triEdge1, triEdge1 ); - - dReal fB0 = dDOT( kNegDiff, segDirection ); - - dReal fB1 = dDOT( kDiff, triEdge0 ); - - dReal fB2 = dDOT( kDiff, triEdge1 ); - - - - dVector3 kTriSegOrigin, kTriSegDirection, kPt; - - dReal fSqrDist, fSqrDist0, fR, fS, fT, fR0, fS0, fT0; - - - - // Set up for a relative error test on the angle between ray direction - - // and triangle normal to determine parallel/nonparallel status. - - dVector3 kN; - - dCROSS( kN, =, triEdge0, triEdge1 ); - - dReal fNSqrLen = dDOT( kN, kN ); - - dReal fDot = dDOT( segDirection, kN ); - - bool bNotParallel = (fDot*fDot >= gs_fTolerance*fA00*fNSqrLen); - - - - if ( bNotParallel ) - - { - - dReal fCof00 = fA11*fA22-fA12*fA12; - - dReal fCof01 = fA02*fA12-fA01*fA22; - - dReal fCof02 = fA01*fA12-fA02*fA11; - - dReal fCof11 = fA00*fA22-fA02*fA02; - - dReal fCof12 = fA02*fA01-fA00*fA12; - - dReal fCof22 = fA00*fA11-fA01*fA01; - - dReal fInvDet = REAL(1.0)/(fA00*fCof00+fA01*fCof01+fA02*fCof02); - - dReal fRhs0 = -fB0*fInvDet; - - dReal fRhs1 = -fB1*fInvDet; - - dReal fRhs2 = -fB2*fInvDet; - - - - fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; - - fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; - - fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; - - - - if ( fR < REAL(0.0) ) - - { - - if ( fS+fT <= REAL(1.0) ) - - { - - if ( fS < REAL(0.0) ) - - { - - if ( fT < REAL(0.0) ) // region 4m - - { - - // min on face s=0 or t=0 or r=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fS0 ); - - fT0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 3m - - { - - // min on face s=0 or r=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR,&fT ); - - fS = REAL(0.0); - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - } - - else if ( fT < REAL(0.0) ) // region 5m - - { - - // min on face t=0 or r=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fS ); - - fT = REAL(0.0); - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 0m - - { - - // min on face r=0 - - fSqrDist = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS, &fT ); - - fR = REAL(0.0); - - } - - } - - else - - { - - if ( fS < REAL(0.0) ) // region 2m - - { - - // min on face s=0 or s+t=1 or r=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else if ( fT < REAL(0.0) ) // region 6m - - { - - // min on face t=0 or s+t=1 or r=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fS ); - - fT = REAL(0.0); - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 1m - - { - - // min on face s+t=1 or r=0 - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(1.0) - fT; - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - } - - } - - else if ( fR <= REAL(1.0) ) - - { - - if ( fS+fT <= REAL(1.0) ) - - { - - if ( fS < REAL(0.0) ) - - { - - if ( fT < REAL(0.0) ) // region 4 - - { - - // min on face s=0 or t=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fS0 ); - - fT0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 3 - - { - - // min on face s=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - } - - } - - else if ( fT < REAL(0.0) ) // region 5 - - { - - // min on face t=0 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fS ); - - fT = REAL(0.0); - - } - - else // region 0 - - { - - // global minimum is interior, done - - fSqrDist = REAL(0.0); - - } - - } - - else - - { - - if ( fS < REAL(0.0) ) // region 2 - - { - - // min on face s=0 or s+t=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else if ( fT < REAL(0.0) ) // region 6 - - { - - // min on face t=0 or s+t=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fS ); - - fT = REAL(0.0); - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 1 - - { - - // min on face s+t=1 - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(1.0) - fT; - - } - - } - - } - - else // fR > 1 - - { - - if ( fS+fT <= REAL(1.0) ) - - { - - if ( fS < REAL(0.0) ) - - { - - if ( fT < REAL(0.0) ) // region 4p - - { - - // min on face s=0 or t=0 or r=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fS0 ); - - fT0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 3p - - { - - // min on face s=0 or r=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - } - - else if ( fT < REAL(0.0) ) // region 5p - - { - - // min on face t=0 or r=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fS ); - - fT = REAL(0.0); - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 0p - - { - - // min face on r=1 - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS, &fT ); - - fR = REAL(1.0); - - } - - } - - else - - { - - if ( fS < REAL(0.0) ) // region 2p - - { - - // min on face s=0 or s+t=1 or r=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(0.0); - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else if ( fT < REAL(0.0) ) // region 6p - - { - - // min on face t=0 or s+t=1 or r=1 - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fS ); - - fT = REAL(0.0); - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - else // region 1p - - { - - // min on face s+t=1 or r=1 - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR, &fT ); - - fS = REAL(1.0) - fT; - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - } - - } - - } - - else - - { - - // segment and triangle are parallel - - Vector3Copy( triOrigin, kTriSegOrigin ); - - Vector3Copy( triEdge0, kTriSegDirection ); - - fSqrDist = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, &fR, &fS ); - - fT = REAL(0.0); - - - - Vector3Copy( triEdge1, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, - - &fR0, &fT0 ); - - fS0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - - - Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); - - Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); - - fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, - - kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); - - fS0 = REAL(1.0) - fT0; - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - - - fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(0.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - - - Vector3Add( segOrigin, segDirection, kPt ); - - fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, - - &fS0, &fT0 ); - - fR0 = REAL(1.0); - - if ( fSqrDist0 < fSqrDist ) - - { - - fSqrDist = fSqrDist0; - - fR = fR0; - - fS = fS0; - - fT = fT0; - - } - - } - - - - if ( pfSegP ) - - *pfSegP = fR; - - - - if ( pfTriP0 ) - - *pfTriP0 = fS; - - - - if ( pfTriP1 ) - - *pfTriP1 = fT; - - - - return fSqrDist; - -} - diff --git a/Extras/ode/ode/src/collision_trimesh_internal.h b/Extras/ode/ode/src/collision_trimesh_internal.h deleted file mode 100644 index 270518f9d..000000000 --- a/Extras/ode/ode/src/collision_trimesh_internal.h +++ /dev/null @@ -1,347 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// TriMesh code by Erwin de Vries. - -#ifndef _ODE_COLLISION_TRIMESH_INTERNAL_H_ -#define _ODE_COLLISION_TRIMESH_INTERNAL_H_ - -int dCollideTrimeshConvex(dxGeom* g1, dxGeom* cnvx, int Flags, dContactGeom* Contacts, int Stride); -int dCollideSTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); -int dCollideBTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); -int dCollideRTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); -int dCollideTTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); -int dCollideCCTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); - -//**************************************************************************** -// dxTriMesh class - -#ifdef TRIMESH_INTERNAL - -#include "collision_kernel.h" -#include - -#define BAN_OPCODE_AUTOLINK -#include "Opcode.h" -using namespace Opcode; - -struct dxTriMeshData : public dBase { - Model BVTree; - MeshInterface Mesh; - - dxTriMeshData(); - ~dxTriMeshData(); - - void Build(const void* Vertices, int VertexStide, int VertexCount, - const void* Indices, int IndexCount, int TriStride, - const void* Normals, - bool Single); - - /* aabb in model space */ - dVector3 AABBCenter; - dVector3 AABBExtents; - - /* data for use in collison resolution */ - const void* Normals; - //Matrix4x4 last_trans; - dMatrix4 last_trans; -}; - - -struct dxTriMesh : public dxGeom{ - // Callbacks - dTriCallback* Callback; - dTriArrayCallback* ArrayCallback; - dTriRayCallback* RayCallback; - - // Data types - dxTriMeshData* Data; - - - // Colliders - static PlanesCollider _PlanesCollider; - static SphereCollider _SphereCollider; - static OBBCollider _OBBCollider; - static RayCollider _RayCollider; - static AABBTreeCollider _AABBTreeCollider; - static LSSCollider _LSSCollider; - - // Some constants - static CollisionFaces Faces; - - // Temporal coherence - struct SphereTC : public SphereCache{ - dxGeom* Geom; - }; - dArray SphereTCCache; - static SphereCache defaultSphereCache; - - struct BoxTC : public OBBCache{ - dxGeom* Geom; - }; - dArray BoxTCCache; - static OBBCache defaultBoxCache; - - struct CCylinderTC : public LSSCache{ - dxGeom* Geom; - }; - dArray CCylinderTCCache; - static LSSCache defaultCCylinderCache; - - bool doSphereTC; - bool doBoxTC; - bool doCCylinderTC; - - // Functions - dxTriMesh(dSpaceID Space, dTriMeshDataID Data); - ~dxTriMesh(); - - void ClearTCCache(); - - int AABBTest(dxGeom* g, dReal aabb[6]); - void computeAABB(); -}; - -// Fetches a contact -inline dContactGeom* SAFECONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){ - dIASSERT(Index >= 0 && Index < (Flags & 0x0ffff)); - return ((dContactGeom*)(((char*)Contacts) + (Index * Stride))); -} - -// Fetches a triangle -inline void FetchTriangle(dxTriMesh* TriMesh, int Index, dVector3 Out[3]){ - VertexPointers VP; - TriMesh->Data->Mesh.GetTriangle(VP, Index); - for (int i = 0; i < 3; i++){ - Out[i][0] = VP.Vertex[i]->x; - Out[i][1] = VP.Vertex[i]->y; - Out[i][2] = VP.Vertex[i]->z; - Out[i][3] = 0; - } -} - -// Fetches a triangle -inline void FetchTriangle(dxTriMesh* TriMesh, int Index, const dVector3 Position, const dMatrix3 Rotation, dVector3 Out[3]){ - VertexPointers VP; - TriMesh->Data->Mesh.GetTriangle(VP, Index); - for (int i = 0; i < 3; i++){ - dVector3 v; - v[0] = VP.Vertex[i]->x; - v[1] = VP.Vertex[i]->y; - v[2] = VP.Vertex[i]->z; - v[3] = 0; - - dMULTIPLY0_331(Out[i], Rotation, v); - Out[i][0] += Position[0]; - Out[i][1] += Position[1]; - Out[i][2] += Position[2]; - Out[i][3] = 0; - } -} - -// Creates an OPCODE matrix from an ODE matrix -inline Matrix4x4& MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, Matrix4x4& Out){ - Out.m[0][0] = (float) Rotation[0]; - Out.m[1][0] = (float) Rotation[1]; - Out.m[2][0] = (float) Rotation[2]; - - Out.m[0][1] = (float) Rotation[4]; - Out.m[1][1] = (float) Rotation[5]; - Out.m[2][1] = (float) Rotation[6]; - - Out.m[0][2] = (float) Rotation[8]; - Out.m[1][2] = (float) Rotation[9]; - Out.m[2][2] = (float) Rotation[10]; - - Out.m[3][0] = (float) Position[0]; - Out.m[3][1] = (float) Position[1]; - Out.m[3][2] = (float) Position[2]; - - Out.m[0][3] = 0.0f; - Out.m[1][3] = 0.0f; - Out.m[2][3] = 0.0f; - Out.m[3][3] = 1.0f; - - return Out; -} - -// Outputs a matrix to 3 vectors -inline void Decompose(const dMatrix3 Matrix, dVector3 Right, dVector3 Up, dVector3 Direction){ - Right[0] = Matrix[0 * 4 + 0]; - Right[1] = Matrix[1 * 4 + 0]; - Right[2] = Matrix[2 * 4 + 0]; - Right[3] = REAL(0.0); - Up[0] = Matrix[0 * 4 + 1]; - Up[1] = Matrix[1 * 4 + 1]; - Up[2] = Matrix[2 * 4 + 1]; - Up[3] = REAL(0.0); - Direction[0] = Matrix[0 * 4 + 2]; - Direction[1] = Matrix[1 * 4 + 2]; - Direction[2] = Matrix[2 * 4 + 2]; - Direction[3] = REAL(0.0); -} - -// Outputs a matrix to 3 vectors -inline void Decompose(const dMatrix3 Matrix, dVector3 Vectors[3]){ - Decompose(Matrix, Vectors[0], Vectors[1], Vectors[2]); -} - -// Creates an OPCODE matrix from an ODE matrix -inline Matrix4x4& MakeMatrix(dxGeom* g, Matrix4x4& Out){ - const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); - const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); - return MakeMatrix(Position, Rotation, Out); -} - -// Finds barycentric -inline void GetPointFromBarycentric(const dVector3 dv[3], dReal u, dReal v, dVector3 Out){ - dReal w = REAL(1.0) - u - v; - - Out[0] = (dv[0][0] * w) + (dv[1][0] * u) + (dv[2][0] * v); - Out[1] = (dv[0][1] * w) + (dv[1][1] * u) + (dv[2][1] * v); - Out[2] = (dv[0][2] * w) + (dv[1][2] * u) + (dv[2][2] * v); - Out[3] = (dv[0][3] * w) + (dv[1][3] * u) + (dv[2][3] * v); -} - -// Performs a callback -inline bool Callback(dxTriMesh* TriMesh, dxGeom* Object, int TriIndex){ - if (TriMesh->Callback != null){ - return TriMesh->Callback(TriMesh, Object, TriIndex); - } - else return true; -} - -// Some utilities -template const T& dcMAX(const T& x, const T& y){ - return x > y ? x : y; -} - -template const T& dcMIN(const T& x, const T& y){ - return x < y ? x : y; -} - -dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin, - const dVector3 triEdge1, const dVector3 triEdge2, - dReal* pfSParam = 0, dReal* pfTParam = 0 ); - -dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction, - const dVector3 seg2Origin, const dVector3 seg2Direction, - dReal* pfSegP0 = 0, dReal* pfSegP1 = 0 ); - -dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd, - const dVector3 triOrigin, - const dVector3 triEdge1, const dVector3 triEdge2, - dReal* t = 0, dReal* u = 0, dReal* v = 0 ); - -inline -void Vector3Subtract( const dVector3 left, const dVector3 right, dVector3 result ) -{ - result[0] = left[0] - right[0]; - result[1] = left[1] - right[1]; - result[2] = left[2] - right[2]; - result[3] = REAL(0.0); -} - -inline -void Vector3Add( const dVector3 left, const dVector3 right, dVector3 result ) -{ - result[0] = left[0] + right[0]; - result[1] = left[1] + right[1]; - result[2] = left[2] + right[2]; - result[3] = REAL(0.0); -} - -inline -void Vector3Negate( const dVector3 in, dVector3 out ) -{ - out[0] = -in[0]; - out[1] = -in[1]; - out[2] = -in[2]; - out[3] = REAL(0.0); -} - -inline -void Vector3Copy( const dVector3 in, dVector3 out ) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = REAL(0.0); -} - -inline -void Vector3Multiply( const dVector3 in, dReal scalar, dVector3 out ) -{ - out[0] = in[0] * scalar; - out[1] = in[1] * scalar; - out[2] = in[2] * scalar; - out[3] = REAL(0.0); -} - -inline -void TransformVector3( const dVector3 in, - const dMatrix3 orientation, const dVector3 position, - dVector3 out ) -{ - dMULTIPLY0_331( out, orientation, in ); - out[0] += position[0]; - out[1] += position[1]; - out[2] += position[2]; -} - -//------------------------------------------------------------------------------ -/** - @brief Check for intersection between triangle and capsule. - - @param dist [out] Shortest distance squared between the triangle and - the capsule segment (central axis). - @param t [out] t value of point on segment that's the shortest distance - away from the triangle, the coordinates of this point - can be found by (cap.seg.end - cap.seg.start) * t, - or cap.seg.ipol(t). - @param u [out] Barycentric coord on triangle. - @param v [out] Barycentric coord on triangle. - @return True if intersection exists. - - The third Barycentric coord is implicit, ie. w = 1.0 - u - v - The Barycentric coords give the location of the point on the triangle - closest to the capsule (where the distance between the two shapes - is the shortest). -*/ -inline -bool IntersectCapsuleTri( const dVector3 segOrigin, const dVector3 segEnd, - const dReal radius, const dVector3 triOrigin, - const dVector3 triEdge0, const dVector3 triEdge1, - dReal* dist, dReal* t, dReal* u, dReal* v ) -{ - dReal sqrDist = SqrDistanceSegTri( segOrigin, segEnd, triOrigin, triEdge0, triEdge1, - t, u, v ); - - if ( dist ) - *dist = sqrDist; - - return ( sqrDist <= (radius * radius) ); -} - -#endif //TRIMESH_INTERNAL - -#endif //_ODE_COLLISION_TRIMESH_INTERNAL_H_ diff --git a/Extras/ode/ode/src/collision_trimesh_ray.cpp b/Extras/ode/ode/src/collision_trimesh_ray.cpp deleted file mode 100644 index bd2305e57..000000000 --- a/Extras/ode/ode/src/collision_trimesh_ray.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// TriMesh code by Erwin de Vries. - -#include -#include -#include -#include -#include "collision_util.h" - -#define TRIMESH_INTERNAL -#include "collision_trimesh_internal.h" - -int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride){ - dxTriMesh* TriMesh = (dxTriMesh*)g1; - - const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); - const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); - - RayCollider& Collider = TriMesh->_RayCollider; - - dReal Length = dGeomRayGetLength(RayGeom); - - int FirstContact, BackfaceCull; - dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull); - int ClosestHit = dGeomRayGetClosestHit(RayGeom); - - Collider.SetFirstContact(FirstContact != 0); - Collider.SetClosestHit(ClosestHit != 0); - Collider.SetCulling(BackfaceCull != 0); - Collider.SetMaxDist(Length); - - dVector3 Origin, Direction; - dGeomRayGet(RayGeom, Origin, Direction); - - /* Make Ray */ - Ray WorldRay; - WorldRay.mOrig.x = Origin[0]; - WorldRay.mOrig.y = Origin[1]; - WorldRay.mOrig.z = Origin[2]; - WorldRay.mDir.x = Direction[0]; - WorldRay.mDir.y = Direction[1]; - WorldRay.mDir.z = Direction[2]; - - /* Intersect */ - Matrix4x4 amatrix; - int TriCount = 0; - if (Collider.Collide(WorldRay, TriMesh->Data->BVTree, &MakeMatrix(TLPosition, TLRotation, amatrix))) { - TriCount = TriMesh->Faces.GetNbFaces(); - } - - if (TriCount == 0) { - return 0; - } - - const CollisionFace* Faces = TriMesh->Faces.GetFaces(); - - int OutTriCount = 0; - for (int i = 0; i < TriCount; i++) { - if (OutTriCount == (Flags & 0xffff)) { - break; - } - if (TriMesh->RayCallback == null || - TriMesh->RayCallback(TriMesh, RayGeom, Faces[i].mFaceID, - Faces[i].mU, Faces[i].mV)) { - const int& TriIndex = Faces[i].mFaceID; - if (!Callback(TriMesh, RayGeom, TriIndex)) { - continue; - } - - dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); - - dVector3 dv[3]; - FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv); - - float T = Faces[i].mDistance; - Contact->pos[0] = Origin[0] + (Direction[0] * T); - Contact->pos[1] = Origin[1] + (Direction[1] * T); - Contact->pos[2] = Origin[2] + (Direction[2] * T); - Contact->pos[3] = REAL(0.0); - - dVector3 vu; - vu[0] = dv[1][0] - dv[0][0]; - vu[1] = dv[1][1] - dv[0][1]; - vu[2] = dv[1][2] - dv[0][2]; - vu[3] = REAL(0.0); - - dVector3 vv; - vv[0] = dv[2][0] - dv[0][0]; - vv[1] = dv[2][1] - dv[0][1]; - vv[2] = dv[2][2] - dv[0][2]; - vv[3] = REAL(0.0); - - dCROSS(Contact->normal, =, vv, vu); // Reversed - - dNormalize3(Contact->normal); - - Contact->depth = T; - Contact->g1 = TriMesh; - Contact->g2 = RayGeom; - - OutTriCount++; - } - } - return OutTriCount; -} diff --git a/Extras/ode/ode/src/collision_trimesh_sphere.cpp b/Extras/ode/ode/src/collision_trimesh_sphere.cpp deleted file mode 100644 index 366ecf51e..000000000 --- a/Extras/ode/ode/src/collision_trimesh_sphere.cpp +++ /dev/null @@ -1,488 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// TriMesh code by Erwin de Vries. - -#include -#include -#include -#include -#include "collision_util.h" - -#define TRIMESH_INTERNAL -#include "collision_trimesh_internal.h" - -#define MERGECONTACTS - -// Ripped from Opcode 1.1. -static bool GetContactData(const dVector3& Center, dReal Radius, const dVector3 Origin, const dVector3 Edge0, const dVector3 Edge1, dReal& Dist, float& u, float& v){ - //calculate plane of triangle - dVector4 Plane; - dCROSS(Plane, =, Edge0, Edge1); - Plane[3] = dDOT(Plane, Origin); - - //normalize - dNormalize4(Plane); - - /* If the center of the sphere is within the positive halfspace of the - * triangle's plane, allow a contact to be generated. - * If the center of the sphere made it into the positive halfspace of a - * back-facing triangle, then the physics update and/or velocity needs - * to be adjusted (penetration has occured anyway). - */ - - float side = dDOT(Plane,Center) - Plane[3]; - - if(side < 0.0f) { - return false; - } - - // now onto the bulk of the collision... - - dVector3 Diff; - Diff[0] = Origin[0] - Center[0]; - Diff[1] = Origin[1] - Center[1]; - Diff[2] = Origin[2] - Center[2]; - Diff[3] = Origin[3] - Center[3]; - - float A00 = dDOT(Edge0, Edge0); - float A01 = dDOT(Edge0, Edge1); - float A11 = dDOT(Edge1, Edge1); - - float B0 = dDOT(Diff, Edge0); - float B1 = dDOT(Diff, Edge1); - - float C = dDOT(Diff, Diff); - - float Det = dFabs(A00 * A11 - A01 * A01); - u = A01 * B1 - A11 * B0; - v = A01 * B0 - A00 * B1; - - float DistSq; - - if (u + v <= Det){ - if(u < REAL(0.0)){ - if(v < REAL(0.0)){ // region 4 - if(B0 < REAL(0.0)){ - v = REAL(0.0); - if (-B0 >= A00){ - u = REAL(1.0); - DistSq = A00 + REAL(2.0) * B0 + C; - } - else{ - u = -B0 / A00; - DistSq = B0 * u + C; - } - } - else{ - u = REAL(0.0); - if(B1 >= REAL(0.0)){ - v = REAL(0.0); - DistSq = C; - } - else if(-B1 >= A11){ - v = REAL(1.0); - DistSq = A11 + REAL(2.0) * B1 + C; - } - else{ - v = -B1 / A11; - DistSq = B1 * v + C; - } - } - } - else{ // region 3 - u = REAL(0.0); - if(B1 >= REAL(0.0)){ - v = REAL(0.0); - DistSq = C; - } - else if(-B1 >= A11){ - v = REAL(1.0); - DistSq = A11 + REAL(2.0) * B1 + C; - } - else{ - v = -B1 / A11; - DistSq = B1 * v + C; - } - } - } - else if(v < REAL(0.0)){ // region 5 - v = REAL(0.0); - if (B0 >= REAL(0.0)){ - u = REAL(0.0); - DistSq = C; - } - else if (-B0 >= A00){ - u = REAL(1.0); - DistSq = A00 + REAL(2.0) * B0 + C; - } - else{ - u = -B0 / A00; - DistSq = B0 * u + C; - } - } - else{ // region 0 - // minimum at interior point - if (Det == REAL(0.0)){ - u = REAL(0.0); - v = REAL(0.0); - DistSq = FLT_MAX; - } - else{ - float InvDet = REAL(1.0) / Det; - u *= InvDet; - v *= InvDet; - DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; - } - } - } - else{ - float Tmp0, Tmp1, Numer, Denom; - - if(u < REAL(0.0)){ // region 2 - Tmp0 = A01 + B0; - Tmp1 = A11 + B1; - if (Tmp1 > Tmp0){ - Numer = Tmp1 - Tmp0; - Denom = A00 - REAL(2.0) * A01 + A11; - if (Numer >= Denom){ - u = REAL(1.0); - v = REAL(0.0); - DistSq = A00 + REAL(2.0) * B0 + C; - } - else{ - u = Numer / Denom; - v = REAL(1.0) - u; - DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; - } - } - else{ - u = REAL(0.0); - if(Tmp1 <= REAL(0.0)){ - v = REAL(1.0); - DistSq = A11 + REAL(2.0) * B1 + C; - } - else if(B1 >= REAL(0.0)){ - v = REAL(0.0); - DistSq = C; - } - else{ - v = -B1 / A11; - DistSq = B1 * v + C; - } - } - } - else if(v < REAL(0.0)){ // region 6 - Tmp0 = A01 + B1; - Tmp1 = A00 + B0; - if (Tmp1 > Tmp0){ - Numer = Tmp1 - Tmp0; - Denom = A00 - REAL(2.0) * A01 + A11; - if (Numer >= Denom){ - v = REAL(1.0); - u = REAL(0.0); - DistSq = A11 + REAL(2.0) * B1 + C; - } - else{ - v = Numer / Denom; - u = REAL(1.0) - v; - DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; - } - } - else{ - v = REAL(0.0); - if (Tmp1 <= REAL(0.0)){ - u = REAL(1.0); - DistSq = A00 + REAL(2.0) * B0 + C; - } - else if(B0 >= REAL(0.0)){ - u = REAL(0.0); - DistSq = C; - } - else{ - u = -B0 / A00; - DistSq = B0 * u + C; - } - } - } - else{ // region 1 - Numer = A11 + B1 - A01 - B0; - if (Numer <= REAL(0.0)){ - u = REAL(0.0); - v = REAL(1.0); - DistSq = A11 + REAL(2.0) * B1 + C; - } - else{ - Denom = A00 - REAL(2.0) * A01 + A11; - if (Numer >= Denom){ - u = REAL(1.0); - v = REAL(0.0); - DistSq = A00 + REAL(2.0) * B0 + C; - } - else{ - u = Numer / Denom; - v = REAL(1.0) - u; - DistSq = u * (A00 * u + A01 * v + REAL(2.0) * B0) + v * (A01 * u + A11 * v + REAL(2.0) * B1) + C; - } - } - } - } - - Dist = dSqrt(dFabs(DistSq)); - - if (Dist <= Radius){ - Dist = Radius - Dist; - return true; - } - else return false; -} - -int dCollideSTL(dxGeom* g1, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride){ - dxTriMesh* TriMesh = (dxTriMesh*)g1; - - // Init - const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); - const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); - - SphereCollider& Collider = TriMesh->_SphereCollider; - - const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom); - dReal Radius = dGeomSphereGetRadius(SphereGeom); - - // Sphere - Sphere Sphere; - Sphere.mCenter.x = Position[0]; - Sphere.mCenter.y = Position[1]; - Sphere.mCenter.z = Position[2]; - Sphere.mRadius = Radius; - - Matrix4x4 amatrix; - - // TC results - if (TriMesh->doSphereTC) { - dxTriMesh::SphereTC* sphereTC = 0; - for (int i = 0; i < TriMesh->SphereTCCache.size(); i++){ - if (TriMesh->SphereTCCache[i].Geom == SphereGeom){ - sphereTC = &TriMesh->SphereTCCache[i]; - break; - } - } - - if (!sphereTC){ - TriMesh->SphereTCCache.push(dxTriMesh::SphereTC()); - - sphereTC = &TriMesh->SphereTCCache[TriMesh->SphereTCCache.size() - 1]; - sphereTC->Geom = SphereGeom; - } - - // Intersect - Collider.SetTemporalCoherence(true); - Collider.Collide(*sphereTC, Sphere, TriMesh->Data->BVTree, null, - &MakeMatrix(TLPosition, TLRotation, amatrix)); - } - else { - Collider.SetTemporalCoherence(false); - Collider.Collide(dxTriMesh::defaultSphereCache, Sphere, TriMesh->Data->BVTree, null, - &MakeMatrix(TLPosition, TLRotation, amatrix)); - } - - if (!Collider.GetContactStatus()) { - /* no collision occurred */ - return 0; - } - - // get results - int TriCount = Collider.GetNbTouchedPrimitives(); - const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); - - if (TriCount != 0){ - if (TriMesh->ArrayCallback != null){ - TriMesh->ArrayCallback(TriMesh, SphereGeom, Triangles, TriCount); - } - - int OutTriCount = 0; - for (int i = 0; i < TriCount; i++){ - if (OutTriCount == (Flags & 0xffff)){ - break; - } - - const int& TriIndex = Triangles[i]; - - dVector3 dv[3]; - FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv); - - dVector3& v0 = dv[0]; - dVector3& v1 = dv[1]; - dVector3& v2 = dv[2]; - - dVector3 vu; - vu[0] = v1[0] - v0[0]; - vu[1] = v1[1] - v0[1]; - vu[2] = v1[2] - v0[2]; - vu[3] = REAL(0.0); - - dVector3 vv; - vv[0] = v2[0] - v0[0]; - vv[1] = v2[1] - v0[1]; - vv[2] = v2[2] - v0[2]; - vv[3] = REAL(0.0); - - dReal Depth; - float u, v; - if (!GetContactData(Position, Radius, v0, vu, vv, Depth, u, v)){ - continue; // Sphere doesnt hit triangle - } - dReal w = REAL(1.0) - u - v; - - if (Depth < REAL(0.0)){ - Depth = REAL(0.0); - } - - dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); - - Contact->pos[0] = (v0[0] * w) + (v1[0] * u) + (v2[0] * v); - Contact->pos[1] = (v0[1] * w) + (v1[1] * u) + (v2[1] * v); - Contact->pos[2] = (v0[2] * w) + (v1[2] * u) + (v2[2] * v); - Contact->pos[3] = REAL(0.0); - - dVector4 Plane; - dCROSS(Plane, =, vv, vu); // Reversed - Plane[3] = dDOT(Plane, v0); // Using normal as plane. - - dReal Area = dSqrt(dDOT(Plane, Plane)); // We can use this later - Plane[0] /= Area; - Plane[1] /= Area; - Plane[2] /= Area; - Plane[3] /= Area; - - Contact->normal[0] = Plane[0]; - Contact->normal[1] = Plane[1]; - Contact->normal[2] = Plane[2]; - Contact->normal[3] = REAL(0.0); - - Contact->depth = Depth; - - //Contact->g1 = TriMesh; - //Contact->g2 = SphereGeom; - - OutTriCount++; - } -#ifdef MERGECONTACTS // Merge all contacts into 1 - if (OutTriCount != 0){ - dContactGeom* Contact = SAFECONTACT(Flags, Contacts, 0, Stride); - - if (OutTriCount != 1){ - Contact->normal[0] *= Contact->depth; - Contact->normal[1] *= Contact->depth; - Contact->normal[2] *= Contact->depth; - Contact->normal[3] *= Contact->depth; - - for (int i = 1; i < OutTriCount; i++){ - dContactGeom* TempContact = SAFECONTACT(Flags, Contacts, i, Stride); - - Contact->pos[0] += TempContact->pos[0]; - Contact->pos[1] += TempContact->pos[1]; - Contact->pos[2] += TempContact->pos[2]; - Contact->pos[3] += TempContact->pos[3]; - - Contact->normal[0] += TempContact->normal[0] * TempContact->depth; - Contact->normal[1] += TempContact->normal[1] * TempContact->depth; - Contact->normal[2] += TempContact->normal[2] * TempContact->depth; - Contact->normal[3] += TempContact->normal[3] * TempContact->depth; - } - - Contact->pos[0] /= OutTriCount; - Contact->pos[1] /= OutTriCount; - Contact->pos[2] /= OutTriCount; - Contact->pos[3] /= OutTriCount; - - // Remember to divide in square space. - Contact->depth = dSqrt(dDOT(Contact->normal, Contact->normal) / OutTriCount); - - dNormalize3(Contact->normal); - } - - Contact->g1 = TriMesh; - Contact->g2 = SphereGeom; - - return 1; - } - else return 0; -#elif defined MERGECONTACTNORMALS // Merge all normals, and distribute between all contacts - if (OutTriCount != 0){ - if (OutTriCount != 1){ - dVector3& Normal = SAFECONTACT(Flags, Contacts, 0, Stride)->normal; - Normal[0] *= SAFECONTACT(Flags, Contacts, 0, Stride)->depth; - Normal[1] *= SAFECONTACT(Flags, Contacts, 0, Stride)->depth; - Normal[2] *= SAFECONTACT(Flags, Contacts, 0, Stride)->depth; - Normal[3] *= SAFECONTACT(Flags, Contacts, 0, Stride)->depth; - - for (int i = 1; i < OutTriCount; i++){ - dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); - - Normal[0] += Contact->normal[0] * Contact->depth; - Normal[1] += Contact->normal[1] * Contact->depth; - Normal[2] += Contact->normal[2] * Contact->depth; - Normal[3] += Contact->normal[3] * Contact->depth; - } - dNormalize3(Normal); - - for (int i = 1; i < OutTriCount; i++){ - dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); - - Contact->normal[0] = Normal[0]; - Contact->normal[1] = Normal[1]; - Contact->normal[2] = Normal[2]; - Contact->normal[3] = Normal[3]; - - Contact->g1 = TriMesh; - Contact->g2 = SphereGeom; - } - } - else{ - SAFECONTACT(Flags, Contacts, 0, Stride)->g1 = TriMesh; - SAFECONTACT(Flags, Contacts, 0, Stride)->g2 = SphereGeom; - } - - return OutTriCount; - } - else return 0; -#else //MERGECONTACTNORMALS // Just gather penetration depths and return - for (int i = 0; i < OutTriCount; i++){ - dContactGeom* Contact = SAFECONTACT(Flags, Contacts, i, Stride); - - //Contact->depth = dSqrt(dDOT(Contact->normal, Contact->normal)); - - /*Contact->normal[0] /= Contact->depth; - Contact->normal[1] /= Contact->depth; - Contact->normal[2] /= Contact->depth; - Contact->normal[3] /= Contact->depth;*/ - - Contact->g1 = TriMesh; - Contact->g2 = SphereGeom; - } - - return OutTriCount; -#endif // MERGECONTACTS - } - else return 0; -} diff --git a/Extras/ode/ode/src/collision_trimesh_trimesh.cpp b/Extras/ode/ode/src/collision_trimesh_trimesh.cpp deleted file mode 100644 index 73354151a..000000000 --- a/Extras/ode/ode/src/collision_trimesh_trimesh.cpp +++ /dev/null @@ -1,1957 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// TriMesh/TriMesh collision code by Jeff Smith (c) 2004 -// - -#ifdef _MSC_VER -#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints -#endif - -#include -#include -#include -#include -#include "collision_util.h" - -#define TRIMESH_INTERNAL -#include "collision_trimesh_internal.h" - -#define SMALL_ELT 2.5e-4 -#define EXPANDED_ELT_THRESH 1.0e-3 -#define DISTANCE_EPSILON 1.0e-8 -#define VELOCITY_EPSILON 1.0e-5 -#define TINY_PENETRATION 5.0e-6 - -struct LineContactSet -{ - dVector3 Points[8]; - int Count; -}; - - -static void GetTriangleGeometryCallback(udword, VertexPointers&, udword); -static void GenerateContact(int, dContactGeom*, int, dxTriMesh*, dxTriMesh*, - const dVector3, const dVector3, dReal, int&); -static int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], - dReal U0[3],dReal U1[3],dReal U2[3],int *coplanar, - dReal isectpt1[3],dReal isectpt2[3]); -inline void dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B); -static void dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ); -static int IntersectLineSegmentRay(dVector3, dVector3, dVector3, dVector3, dVector3); -static bool FindTriSolidIntrsection(const dVector3 Tri[3], - const dVector4 Planes[6], int numSides, - LineContactSet& ClippedPolygon ); -static void ClipConvexPolygonAgainstPlane( const dVector3, dReal, LineContactSet& ); -static bool SimpleUnclippedTest(dVector3 in_CoplanarPt, dVector3 in_v, dVector3 in_elt, - dVector3 in_n, dVector3* in_col_v, dReal &out_depth); -static int ExamineContactPoint(dVector3* v_col, dVector3 in_n, dVector3 in_point); -static int RayTriangleIntersect(const dVector3 orig, const dVector3 dir, - const dVector3 vert0, const dVector3 vert1,const dVector3 vert2, - dReal *t,dReal *u,dReal *v); - - - - -/* some math macros */ -#define CROSS(dest,v1,v2) { dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ - dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ - dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; } - -#define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) - -#define SUB(dest,v1,v2) { dest[0]=v1[0]-v2[0]; dest[1]=v1[1]-v2[1]; dest[2]=v1[2]-v2[2]; } - -#define ADD(dest,v1,v2) { dest[0]=v1[0]+v2[0]; dest[1]=v1[1]+v2[1]; dest[2]=v1[2]+v2[2]; } - -#define MULT(dest,v,factor) { dest[0]=factor*v[0]; dest[1]=factor*v[1]; dest[2]=factor*v[2]; } - -#define SET(dest,src) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; } - -#define SMULT(p,q,s) { p[0]=q[0]*s; p[1]=q[1]*s; p[2]=q[2]*s; } - -#define COMBO(combo,p,t,q) { combo[0]=p[0]+t*q[0]; combo[1]=p[1]+t*q[1]; combo[2]=p[2]+t*q[2]; } - -#define LENGTH(x) ((dReal) dSqrt(dDOT(x, x))) - -#define DEPTH(d, p, q, n) d = (p[0] - q[0])*n[0] + (p[1] - q[1])*n[1] + (p[2] - q[2])*n[2]; - -inline const dReal dMin(const dReal x, const dReal y) -{ - return x < y ? x : y; -} - - -inline void -SwapNormals(dVector3 *&pen_v, dVector3 *&col_v, dVector3* v1, dVector3* v2, - dVector3 *&pen_elt, dVector3 *elt_f1, dVector3 *elt_f2, - dVector3 n, dVector3 n1, dVector3 n2) -{ - if (pen_v == v1) { - pen_v = v2; - pen_elt = elt_f2; - col_v = v1; - SET(n, n1); - } - else { - pen_v = v1; - pen_elt = elt_f1; - col_v = v2; - SET(n, n2); - } -} - - - - -int -dCollideTTL(dxGeom* g1, dxGeom* g2, int Flags, dContactGeom* Contacts, int Stride) -{ - dxTriMesh* TriMesh1 = (dxTriMesh*) g1; - dxTriMesh* TriMesh2 = (dxTriMesh*) g2; - - dReal * TriNormals1 = (dReal *) TriMesh1->Data->Normals; - dReal * TriNormals2 = (dReal *) TriMesh2->Data->Normals; - - const dVector3& TLPosition1 = *(const dVector3*) dGeomGetPosition(TriMesh1); - // TLRotation1 = column-major order - const dMatrix3& TLRotation1 = *(const dMatrix3*) dGeomGetRotation(TriMesh1); - - const dVector3& TLPosition2 = *(const dVector3*) dGeomGetPosition(TriMesh2); - // TLRotation2 = column-major order - const dMatrix3& TLRotation2 = *(const dMatrix3*) dGeomGetRotation(TriMesh2); - - AABBTreeCollider& Collider = TriMesh1->_AABBTreeCollider; - - static BVTCache ColCache; - ColCache.Model0 = &TriMesh1->Data->BVTree; - ColCache.Model1 = &TriMesh2->Data->BVTree; - - // Collision query - Matrix4x4 amatrix, bmatrix; - BOOL IsOk = Collider.Collide(ColCache, - &MakeMatrix(TLPosition1, TLRotation1, amatrix), - &MakeMatrix(TLPosition2, TLRotation2, bmatrix) ); - - - // Make "double" versions of these matrices, if appropriate - dMatrix4 A, B; - dMakeMatrix4(TLPosition1, TLRotation1, A); - dMakeMatrix4(TLPosition2, TLRotation2, B); - - - if (IsOk) { - // Get collision status => if true, objects overlap - if ( Collider.GetContactStatus() ) { - // Number of colliding pairs and list of pairs - int TriCount = Collider.GetNbPairs(); - const Pair* CollidingPairs = Collider.GetPairs(); - - if (TriCount > 0) { - // step through the pairs, adding contacts - int id1, id2; - int OutTriCount = 0; - dVector3 v1[3], v2[3], CoplanarPt; - dVector3 e1, e2, e3, n1, n2, n, ContactNormal; - dReal depth; - dVector3 orig_pos, old_pos1, old_pos2, elt1, elt2, elt_sum; - dVector3 elt_f1[3], elt_f2[3]; - dReal contact_elt_length = SMALL_ELT; - LineContactSet firstClippedTri, secondClippedTri; - dVector3 *firstClippedElt = NULL; - dVector3 *secondClippedElt = NULL; - - - // only do these expensive inversions once - dMatrix4 InvMatrix1, InvMatrix2; - dInvertMatrix4(A, InvMatrix1); - dInvertMatrix4(B, InvMatrix2); - - - for (int i = 0; i < TriCount; i++) - if (OutTriCount < (Flags & 0xffff)) { - - id1 = CollidingPairs[i].id0; - id2 = CollidingPairs[i].id1; - - // grab the colliding triangles - FetchTriangle((dxTriMesh*) g1, id1, TLPosition1, TLRotation1, v1); - FetchTriangle((dxTriMesh*) g2, id2, TLPosition2, TLRotation2, v2); - // Since we'll be doing matrix transfomrations, we need to - // make sure that all vertices have four elements - for (int j=0; j<3; j++) { - v1[j][3] = 1.0; - v2[j][3] = 1.0; - } - - - int IsCoplanar = 0; - dReal IsectPt1[3], IsectPt2[3]; - - // Sometimes OPCODE makes mistakes, so we look at the return - // value for TriTriIntersectWithIsectLine. A retcode of "0" - // means no intersection took place - if ( TriTriIntersectWithIsectLine( v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], - &IsCoplanar, - IsectPt1, IsectPt2) ) { - - // Compute the normals of the colliding faces - // - if (TriNormals1 == NULL) { - SUB( e1, v1[1], v1[0] ); - SUB( e2, v1[2], v1[0] ); - CROSS( n1, e1, e2 ); - dNormalize3(n1); - } - else { - // If we were passed normals, we need to adjust them to take into - // account the objects' current rotations - e1[0] = TriNormals1[id1*3]; - e1[1] = TriNormals1[id1*3 + 1]; - e1[2] = TriNormals1[id1*3 + 2]; - e1[3] = 0.0; - - //dMultiply1(n1, TLRotation1, e1, 3, 3, 1); - dMultiply0(n1, TLRotation1, e1, 3, 3, 1); - n1[3] = 1.0; - } - - if (TriNormals2 == NULL) { - SUB( e1, v2[1], v2[0] ); - SUB( e2, v2[2], v2[0] ); - CROSS( n2, e1, e2); - dNormalize3(n2); - } - else { - // If we were passed normals, we need to adjust them to take into - // account the objects' current rotations - e2[0] = TriNormals2[id2*3]; - e2[1] = TriNormals2[id2*3 + 1]; - e2[2] = TriNormals2[id2*3 + 2]; - e2[3] = 0.0; - - //dMultiply1(n2, TLRotation2, e2, 3, 3, 1); - dMultiply0(n2, TLRotation2, e2, 3, 3, 1); - n2[3] = 1.0; - } - - - if (IsCoplanar) { - // We can reach this case if the faces are coplanar, OR - // if they don't actually intersect. (OPCODE can make - // mistakes) - if (fabs(dDOT(n1, n2)) > 0.999) { - // If the faces are coplanar, we declare that the point of - // contact is at the average location of the vertices of - // both faces - dVector3 ContactPt; - for (int j=0; j<3; j++) { - ContactPt[j] = 0.0; - for (int k=0; k<3; k++) - ContactPt[j] += v1[k][j] + v2[k][j]; - ContactPt[j] /= 6.0; - } - ContactPt[3] = 1.0; - - // and the contact normal is the normal of face 2 - // (could be face 1, because they are the same) - SET(n, n2); - - // and the penetration depth is the co-normal - // distance between any two vertices A and B, - // i.e. d = DOT(n, (A-B)) - DEPTH(depth, v1[1], v2[1], n); - if (depth < 0) - depth *= -1.0; - - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - ContactPt, n, depth, OutTriCount); - } - } - else { - // Otherwise (in non-co-planar cases), we create a coplanar - // point -- the middle of the line of intersection -- that - // will be used for various computations down the road - for (int j=0; j<3; j++) - CoplanarPt[j] = (dReal) ( (IsectPt1[j] + IsectPt2[j]) / 2.0 ); - CoplanarPt[3] = 1.0; - - // Find the ELT of the coplanar point - // - dMultiply1(orig_pos, InvMatrix1, CoplanarPt, 4, 4, 1); - dMultiply1(old_pos1, TriMesh1->Data->last_trans, orig_pos, 4, 4, 1); - SUB(elt1, CoplanarPt, old_pos1); - - dMultiply1(orig_pos, InvMatrix2, CoplanarPt, 4, 4, 1); - dMultiply1(old_pos2, TriMesh2->Data->last_trans, orig_pos, 4, 4, 1); - SUB(elt2, CoplanarPt, old_pos2); - - SUB(elt_sum, elt1, elt2); // net motion of the coplanar point - - - // Calculate how much the vertices of each face moved in the - // direction of the opposite face's normal - // - dReal total_dp1, total_dp2; - total_dp1 = 0.0; - total_dp2 = 0.0; - - for (int ii=0; ii<3; ii++) { - // find the estimated linear translation (ELT) of the vertices - // on face 1, wrt to the center of face 2. - - // un-transform this vertex by the current transform - dMultiply1(orig_pos, InvMatrix1, v1[ii], 4, 4, 1 ); - - // re-transform this vertex by last_trans (to get its old - // position) - dMultiply1(old_pos1, TriMesh1->Data->last_trans, orig_pos, 4, 4, 1); - - // Then subtract this position from our current one to find - // the elapsed linear translation (ELT) - for (int k=0; k<3; k++) { - elt_f1[ii][k] = (v1[ii][k] - old_pos1[k]) - elt2[k]; - } - - // Take the dot product of the ELT for each vertex (wrt the - // center of face2) - total_dp1 += fabs( dDOT(elt_f1[ii], n2) ); - } - - for (int ii=0; ii<3; ii++) { - // find the estimated linear translation (ELT) of the vertices - // on face 2, wrt to the center of face 1. - dMultiply1(orig_pos, InvMatrix2, v2[ii], 4, 4, 1); - dMultiply1(old_pos2, TriMesh2->Data->last_trans, orig_pos, 4, 4, 1); - for (int k=0; k<3; k++) { - elt_f2[ii][k] = (v2[ii][k] - old_pos2[k]) - elt1[k]; - } - - // Take the dot product of the ELT for each vertex (wrt the - // center of face2) and add them - total_dp2 += fabs( dDOT(elt_f2[ii], n1) ); - } - - - //////// - // Estimate the penetration depth. - // - dReal dp; - BOOL badPen = true; - dVector3 *pen_v; // the "penetrating vertices" - dVector3 *pen_elt; // the elt_f of the penetrating face - dVector3 *col_v; // the "collision vertices" (the penetrated face) - - - depth = 0.0; - if ((total_dp1 > DISTANCE_EPSILON) || (total_dp2 > DISTANCE_EPSILON)) { - //////// - // Find the collision normal, by finding the face - // that is pointed "most" in the direction of travel - // of the two triangles - // - if (total_dp2 > total_dp1) { - pen_v = v2; - pen_elt = elt_f2; - col_v = v1; - SET(n, n1); - } - else { - pen_v = v1; - pen_elt = elt_f1; - col_v = v2; - SET(n, n2); - } - } - else { - // the total_dp is very small, so let's fall back - // to a different test - if (LENGTH(elt2) > LENGTH(elt1)) { - pen_v = v2; - pen_elt = elt_f2; - col_v = v1; - SET(n, n1); - } - else { - pen_v = v1; - pen_elt = elt_f1; - col_v = v2; - SET(n, n2); - } - } - - - for (int j=0; j<3; j++) - if (SimpleUnclippedTest(CoplanarPt, pen_v[j], pen_elt[j], n, col_v, depth)) { - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - pen_v[j], n, depth, OutTriCount); - badPen = false; - } - - - if (badPen) { - // try the other normal - SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); - - for (int j=0; j<3; j++) - if (SimpleUnclippedTest(CoplanarPt, pen_v[j], pen_elt[j], n, col_v, depth)) { - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - pen_v[j], n, depth, OutTriCount); - badPen = false; - } - } - - - - //////////////////////////////////////// - // - // If we haven't found a good penetration, then we're probably straddling - // the edge of one of the objects, or the penetraing face is big - // enough that all of its vertices are outside the bounds of the - // penetrated face. - // In these cases, we do a more expensive test. We clip the penetrating - // triangle with a solid defined by the penetrated triangle, and repeat - // the tests above on this new polygon - if (badPen) { - - // Switch pen_v and n back again - SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); - - - // Find the three sides (no top or bottom) of the solid defined by - // the edges of the penetrated triangle. - - // The dVector4 "plane" structures contain the following information: - // [0]-[2]: The normal of the face, pointing INWARDS (i.e. - // the inverse normal - // [3]: The distance between the face and the center of the - // solid, along the normal - dVector4 SolidPlanes[3]; - dVector3 tmp1; - dVector3 sn; - - for (int j=0; j<3; j++) { - e1[j] = col_v[1][j] - col_v[0][j]; - e2[j] = col_v[0][j] - col_v[2][j]; - e3[j] = col_v[2][j] - col_v[1][j]; - } - - // side 1 - CROSS(sn, e1, n); - dNormalize3(sn); - SMULT( SolidPlanes[0], sn, -1.0 ); - - ADD(tmp1, col_v[0], col_v[1]); - SMULT(tmp1, tmp1, 0.5); // center of edge - // distance from center to edge along normal - SolidPlanes[0][3] = dDOT(tmp1, SolidPlanes[0]); - - - // side 2 - CROSS(sn, e2, n); - dNormalize3(sn); - SMULT( SolidPlanes[1], sn, -1.0 ); - - ADD(tmp1, col_v[0], col_v[2]); - SMULT(tmp1, tmp1, 0.5); // center of edge - // distance from center to edge along normal - SolidPlanes[1][3] = dDOT(tmp1, SolidPlanes[1]); - - - // side 3 - CROSS(sn, e3, n); - dNormalize3(sn); - SMULT( SolidPlanes[2], sn, -1.0 ); - - ADD(tmp1, col_v[2], col_v[1]); - SMULT(tmp1, tmp1, 0.5); // center of edge - // distance from center to edge along normal - SolidPlanes[2][3] = dDOT(tmp1, SolidPlanes[2]); - - - FindTriSolidIntrsection(pen_v, SolidPlanes, 3, firstClippedTri); - - firstClippedElt = new dVector3[firstClippedTri.Count]; - - for (int j=0; jData->last_trans, orig_pos, 4, 4, 1); - for (int k=0; k<3; k++) { - firstClippedElt[j][k] = (firstClippedTri.Points[j][k] - old_pos1[k]) - elt2[k]; - } - } - else { - dMultiply1(orig_pos, InvMatrix2, firstClippedTri.Points[j], 4, 4, 1); - dMultiply1(old_pos2, TriMesh2->Data->last_trans, orig_pos, 4, 4, 1); - for (int k=0; k<3; k++) { - firstClippedElt[j][k] = (firstClippedTri.Points[j][k] - old_pos2[k]) - elt1[k]; - } - } - - contact_elt_length = fabs(dDOT(firstClippedElt[j], n)); - - if (dp >= 0.0) { - depth = dp; - if (depth == 0.0) - depth = dMin(DISTANCE_EPSILON, contact_elt_length); - - if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) - depth = contact_elt_length; - - if (depth <= contact_elt_length) { - // Add a contact - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - firstClippedTri.Points[j], n, depth, OutTriCount); - badPen = false; - } - } - - } - } - - if (badPen) { - // Switch pen_v and n (again!) - SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); - - - // Find the three sides (no top or bottom) of the solid created by - // the penetrated triangle. - // The dVector4 "plane" structures contain the following information: - // [0]-[2]: The normal of the face, pointing INWARDS (i.e. - // the inverse normal - // [3]: The distance between the face and the center of the - // solid, along the normal - dVector4 SolidPlanes[3]; - dVector3 tmp1; - - dVector3 sn; - for (int j=0; j<3; j++) { - e1[j] = col_v[1][j] - col_v[0][j]; - e2[j] = col_v[0][j] - col_v[2][j]; - e3[j] = col_v[2][j] - col_v[1][j]; - } - - // side 1 - CROSS(sn, e1, n); - dNormalize3(sn); - SMULT( SolidPlanes[0], sn, -1.0 ); - - ADD(tmp1, col_v[0], col_v[1]); - SMULT(tmp1, tmp1, 0.5); // center of edge - // distance from center to edge along normal - SolidPlanes[0][3] = dDOT(tmp1, SolidPlanes[0]); - - - // side 2 - CROSS(sn, e2, n); - dNormalize3(sn); - SMULT( SolidPlanes[1], sn, -1.0 ); - - ADD(tmp1, col_v[0], col_v[2]); - SMULT(tmp1, tmp1, 0.5); // center of edge - // distance from center to edge along normal - SolidPlanes[1][3] = dDOT(tmp1, SolidPlanes[1]); - - - // side 3 - CROSS(sn, e3, n); - dNormalize3(sn); - SMULT( SolidPlanes[2], sn, -1.0 ); - - ADD(tmp1, col_v[2], col_v[1]); - SMULT(tmp1, tmp1, 0.5); // center of edge - // distance from center to edge along normal - SolidPlanes[2][3] = dDOT(tmp1, SolidPlanes[2]); - - FindTriSolidIntrsection(pen_v, SolidPlanes, 3, secondClippedTri); - - secondClippedElt = new dVector3[secondClippedTri.Count]; - - for (int j=0; jData->last_trans, orig_pos, 4, 4, 1); - for (int k=0; k<3; k++) { - secondClippedElt[j][k] = (secondClippedTri.Points[j][k] - old_pos1[k]) - elt2[k]; - } - } - else { - dMultiply1(orig_pos, InvMatrix2, secondClippedTri.Points[j], 4, 4, 1); - dMultiply1(old_pos2, TriMesh2->Data->last_trans, orig_pos, 4, 4, 1); - for (int k=0; k<3; k++) { - secondClippedElt[j][k] = (secondClippedTri.Points[j][k] - old_pos2[k]) - elt1[k]; - } - } - - - contact_elt_length = fabs(dDOT(secondClippedElt[j],n)); - - if (dp >= 0.0) { - depth = dp; - if (depth == 0.0) - depth = dMin(DISTANCE_EPSILON, contact_elt_length); - - if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) - depth = contact_elt_length; - - if (depth <= contact_elt_length) { - // Add a contact - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - secondClippedTri.Points[j], n, depth, OutTriCount); - badPen = false; - } - } - - - } - } - - - - ///////////////// - // All conventional tests have failed at this point, so now we deal with - // cases on a more "heuristic" basis - // - - if (badPen) { - // Switch pen_v and n (for the fourth time, so they're - // what my original guess said they were) - SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); - - if (fabs(dDOT(n1, n2)) < 0.01) { - // If we reach this point, we have (close to) perpindicular - // faces, either resting on each other or sliding in a - // direction orthogonal to both surface normals. - if (LENGTH(elt_sum) < DISTANCE_EPSILON) { - depth = (dReal) fabs(dDOT(n, elt_sum)); - - if (depth > 1e-12) { - dNormalize3(n); - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - CoplanarPt, n, depth, OutTriCount); - badPen = false; - } - else { - // If the two faces are (nearly) perfectly at rest with - // respect to each other, then we ignore the contact, - // allowing the objects to slip a little in the hopes - // that next frame, they'll give us something to work - // with. - badPen = false; - } - } - else { - // The faces are perpindicular, but moving significantly - // This can be sliding, or an unusual edge-straddling - // penetration. - dVector3 cn; - - CROSS(cn, n1, n2); - dNormalize3(cn); - SET(n, cn); - - // The shallowest ineterpenetration of the faces - // is the depth - dVector3 ContactPt; - dVector3 dvTmp; - dReal rTmp; - depth = dInfinity; - for (int j=0; j<3; j++) { - for (int k=0; k<3; k++) { - SUB(dvTmp, col_v[k], pen_v[j]); - - rTmp = dDOT(dvTmp, n); - if ( fabs(rTmp) < fabs(depth) ) { - depth = rTmp; - SET( ContactPt, pen_v[j] ); - contact_elt_length = fabs(dDOT(pen_elt[j], n)); - } - } - } - if (depth < 0.0) { - SMULT(n, n, -1.0); - depth *= -1.0; - } - - if ((depth > 0.0) && (depth <= contact_elt_length)) { - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - ContactPt, n, depth, OutTriCount); - badPen = false; - } - - } - } - } - - - if (badPen) { - // Use as the normal the direction of travel, rather than any particular - // face normal - // - dVector3 esn; - - if (pen_v == v1) { - SMULT(esn, elt_sum, -1.0); - } - else { - SET(esn, elt_sum); - } - dNormalize3(esn); - - - // The shallowest ineterpenetration of the faces - // is the depth - dVector3 ContactPt; - depth = dInfinity; - for (int j=0; j<3; j++) { - for (int k=0; k<3; k++) { - DEPTH(dp, col_v[k], pen_v[j], esn); - if ( (ExamineContactPoint(col_v, esn, pen_v[j])) && - ( fabs(dp) < fabs(depth)) ) { - depth = dp; - SET( ContactPt, pen_v[j] ); - contact_elt_length = fabs(dDOT(pen_elt[j], esn)); - } - } - } - - if ((depth > 0.0) && (depth <= contact_elt_length)) { - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - ContactPt, esn, depth, OutTriCount); - badPen = false; - } - } - - - if (badPen) { - // If the direction of motion is perpindicular to both normals - if ( (fabs(dDOT(n1, elt_sum)) < 0.01) && (fabs(dDOT(n2, elt_sum)) < 0.01) ) { - dVector3 esn; - if (pen_v == v1) { - SMULT(esn, elt_sum, -1.0); - } - else { - SET(esn, elt_sum); - } - - dNormalize3(esn); - - - // Look at the clipped points again, checking them against this - // new normal - for (int j=0; j= 0.0) { - contact_elt_length = fabs(dDOT(firstClippedElt[j], esn)); - - depth = dp; - //if (depth == 0.0) - //depth = dMin(DISTANCE_EPSILON, contact_elt_length); - - if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) - depth = contact_elt_length; - - if (depth <= contact_elt_length) { - // Add a contact - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - firstClippedTri.Points[j], esn, depth, OutTriCount); - badPen = false; - } - } - } - - if (badPen) { - // If this test failed, try it with the second set of clipped faces - for (int j=0; j= 0.0) { - contact_elt_length = fabs(dDOT(secondClippedElt[j], esn)); - - depth = dp; - //if (depth == 0.0) - //depth = dMin(DISTANCE_EPSILON, contact_elt_length); - - if ((contact_elt_length < SMALL_ELT) && (depth < EXPANDED_ELT_THRESH)) - depth = contact_elt_length; - - if (depth <= contact_elt_length) { - // Add a contact - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - secondClippedTri.Points[j], esn, depth, OutTriCount); - badPen = false; - } - } - } - } - } - } - - - - if (badPen) { - // if we have very little motion, we're dealing with resting contact - // and shouldn't reference the ELTs at all - // - if (LENGTH(elt_sum) < VELOCITY_EPSILON) { - - // instead of a "contact_elt_length" threshhold, we'll use an - // arbitrary, small one - for (int j=0; j<3; j++) { - DEPTH(dp, CoplanarPt, pen_v[j], n); - - if (dp == 0.0) - dp = TINY_PENETRATION; - - if ( (dp > 0.0) && (dp <= SMALL_ELT)) { - // Add a contact - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - pen_v[j], n, (dReal) dp, OutTriCount); - badPen = false; - } - } - - - if (badPen) { - // try the other normal - SwapNormals(pen_v, col_v, v1, v2, pen_elt, elt_f1, elt_f2, n, n1, n2); - - for (int j=0; j<3; j++) { - DEPTH(dp, CoplanarPt, pen_v[j], n); - - if (dp == 0.0) - dp = TINY_PENETRATION; - - if ( (dp > 0.0) && (dp <= SMALL_ELT)) { - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - pen_v[j], n, (dReal) dp, OutTriCount); - badPen = false; - } - } - } - - - - } - } - - if (badPen) { - // find the nearest existing contact, and replicate it's - // normal and depth - // - dContactGeom* Contact; - dVector3 pos_diff; - dReal min_dist, dist; - - min_dist = dInfinity; - depth = 0.0; - for (int j=0; jpos, CoplanarPt); - - dist = dDOT(pos_diff, pos_diff); - if (dist < min_dist) { - min_dist = dist; - depth = Contact->depth; - SMULT(ContactNormal, Contact->normal, -1.0); - } - } - - if (depth > 0.0) { - // Add a tiny contact at the coplanar point - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - CoplanarPt, ContactNormal, depth, OutTriCount); - badPen = false; - } - } - - - if (badPen) { - // Add a tiny contact at the coplanar point - if (-dDOT(elt_sum, n1) > -dDOT(elt_sum, n2)) { - SET(ContactNormal, n1); - } - else { - SET(ContactNormal, n2); - } - - GenerateContact(Flags, Contacts, Stride, TriMesh1, TriMesh2, - CoplanarPt, ContactNormal, TINY_PENETRATION, OutTriCount); - badPen = false; - } - - - } // not coplanar (main loop) - } // TriTriIntersectWithIsectLine - - // Free memory - delete[] firstClippedElt; - firstClippedElt = NULL; - delete[] secondClippedElt; - secondClippedElt = NULL; - - } // if (OutTriCount < (Flags & 0xffff)) - - // Return the number of contacts - return OutTriCount; - - } - } - } - - - // There was some kind of failure during the Collide call or - // there are no faces overlapping - return 0; -} - - - -static void -GetTriangleGeometryCallback(udword triangleindex, VertexPointers& triangle, udword user_data) -{ - dVector3 Out[3]; - - FetchTriangle((dxTriMesh*) user_data, (int) triangleindex, Out); - - for (int i = 0; i < 3; i++) - triangle.Vertex[i] = (const Point*) ((dReal*) Out[i]); -} - - -// -// -// -#define B11 B[0] -#define B12 B[1] -#define B13 B[2] -#define B14 B[3] -#define B21 B[4] -#define B22 B[5] -#define B23 B[6] -#define B24 B[7] -#define B31 B[8] -#define B32 B[9] -#define B33 B[10] -#define B34 B[11] -#define B41 B[12] -#define B42 B[13] -#define B43 B[14] -#define B44 B[15] - -#define Binv11 Binv[0] -#define Binv12 Binv[1] -#define Binv13 Binv[2] -#define Binv14 Binv[3] -#define Binv21 Binv[4] -#define Binv22 Binv[5] -#define Binv23 Binv[6] -#define Binv24 Binv[7] -#define Binv31 Binv[8] -#define Binv32 Binv[9] -#define Binv33 Binv[10] -#define Binv34 Binv[11] -#define Binv41 Binv[12] -#define Binv42 Binv[13] -#define Binv43 Binv[14] -#define Binv44 Binv[15] - -inline void -dMakeMatrix4(const dVector3 Position, const dMatrix3 Rotation, dMatrix4 &B) -{ - B11 = Rotation[0]; B21 = Rotation[1]; B31 = Rotation[2]; B41 = Position[0]; - B12 = Rotation[4]; B22 = Rotation[5]; B32 = Rotation[6]; B42 = Position[1]; - B13 = Rotation[8]; B23 = Rotation[9]; B33 = Rotation[10]; B43 = Position[2]; - - B14 = 0.0; B24 = 0.0; B34 = 0.0; B44 = 1.0; -} - - -static void -dInvertMatrix4( dMatrix4& B, dMatrix4& Binv ) -{ - dReal det = (B11 * B22 - B12 * B21) * (B33 * B44 - B34 * B43) - -(B11 * B23 - B13 * B21) * (B32 * B44 - B34 * B42) - +(B11 * B24 - B14 * B21) * (B32 * B43 - B33 * B42) - +(B12 * B23 - B13 * B22) * (B31 * B44 - B34 * B41) - -(B12 * B24 - B14 * B22) * (B31 * B43 - B33 * B41) - +(B13 * B24 - B14 * B23) * (B31 * B42 - B32 * B41); - - dAASSERT (det != 0.0); - - det = 1.0 / det; - - Binv11 = (dReal) (det * ((B22 * B33) - (B23 * B32))); - Binv12 = (dReal) (det * ((B32 * B13) - (B33 * B12))); - Binv13 = (dReal) (det * ((B12 * B23) - (B13 * B22))); - Binv14 = 0.0f; - Binv21 = (dReal) (det * ((B23 * B31) - (B21 * B33))); - Binv22 = (dReal) (det * ((B33 * B11) - (B31 * B13))); - Binv23 = (dReal) (det * ((B13 * B21) - (B11 * B23))); - Binv24 = 0.0f; - Binv31 = (dReal) (det * ((B21 * B32) - (B22 * B31))); - Binv32 = (dReal) (det * ((B31 * B12) - (B32 * B11))); - Binv33 = (dReal) (det * ((B11 * B22) - (B12 * B21))); - Binv34 = 0.0f; - Binv41 = (dReal) (det * (B21*(B33*B42 - B32*B43) + B22*(B31*B43 - B33*B41) + B23*(B32*B41 - B31*B42))); - Binv42 = (dReal) (det * (B31*(B13*B42 - B12*B43) + B32*(B11*B43 - B13*B41) + B33*(B12*B41 - B11*B42))); - Binv43 = (dReal) (det * (B41*(B13*B22 - B12*B23) + B42*(B11*B23 - B13*B21) + B43*(B12*B21 - B11*B22))); - Binv44 = 1.0f; -} - - - -///////////////////////////////////////////////// -// -// Triangle/Triangle intersection utilities -// -// From the article "A Fast Triangle-Triangle Intersection Test", -// Journal of Graphics Tools, 2(2), 1997 -// -// Some of this functionality is duplicated in OPCODE (see -// OPC_TriTriOverlap.h) but we have replicated it here so we don't -// have to mess with the internals of OPCODE, as well as so we can -// further optimize some of the functions. -// -// This version computes the line of intersection as well (if they -// are not coplanar): -// int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], -// dReal U0[3],dReal U1[3],dReal U2[3], -// int *coplanar, -// dReal isectpt1[3],dReal isectpt2[3]); -// -// parameters: vertices of triangle 1: V0,V1,V2 -// vertices of triangle 2: U0,U1,U2 -// -// result : returns 1 if the triangles intersect, otherwise 0 -// "coplanar" returns whether the tris are coplanar -// isectpt1, isectpt2 are the endpoints of the line of -// intersection -// - - - -#define FABS(x) ((dReal)fabs(x)) /* implement as is fastest on your machine */ - -/* if USE_EPSILON_TEST is true then we do a check: - if |dv|b) \ - { \ - dReal c; \ - c=a; \ - a=b; \ - b=c; \ - } - -#define ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1) \ - isect0=VV0+(VV1-VV0)*D0/(D0-D1); \ - isect1=VV0+(VV2-VV0)*D0/(D0-D2); - - -#define COMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1) \ - if(D0D1>0.0f) \ - { \ - /* here we know that D0D2<=0.0 */ \ - /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ - ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ - } \ - else if(D0D2>0.0f) \ - { \ - /* here we know that d0d1<=0.0 */ \ - ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ - } \ - else if(D1*D2>0.0f || D0!=0.0f) \ - { \ - /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ - ISECT(VV0,VV1,VV2,D0,D1,D2,isect0,isect1); \ - } \ - else if(D1!=0.0f) \ - { \ - ISECT(VV1,VV0,VV2,D1,D0,D2,isect0,isect1); \ - } \ - else if(D2!=0.0f) \ - { \ - ISECT(VV2,VV0,VV1,D2,D0,D1,isect0,isect1); \ - } \ - else \ - { \ - /* triangles are coplanar */ \ - return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ - } - - - -/* this edge to edge test is based on Franlin Antonio's gem: - "Faster Line Segment Intersection", in Graphics Gems III, - pp. 199-202 */ -#define EDGE_EDGE_TEST(V0,U0,U1) \ - Bx=U0[i0]-U1[i0]; \ - By=U0[i1]-U1[i1]; \ - Cx=V0[i0]-U0[i0]; \ - Cy=V0[i1]-U0[i1]; \ - f=Ay*Bx-Ax*By; \ - d=By*Cx-Bx*Cy; \ - if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \ - { \ - e=Ax*Cy-Ay*Cx; \ - if(f>0) \ - { \ - if(e>=0 && e<=f) return 1; \ - } \ - else \ - { \ - if(e<=0 && e>=f) return 1; \ - } \ - } - -#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \ -{ \ - dReal Ax,Ay,Bx,By,Cx,Cy,e,d,f; \ - Ax=V1[i0]-V0[i0]; \ - Ay=V1[i1]-V0[i1]; \ - /* test edge U0,U1 against V0,V1 */ \ - EDGE_EDGE_TEST(V0,U0,U1); \ - /* test edge U1,U2 against V0,V1 */ \ - EDGE_EDGE_TEST(V0,U1,U2); \ - /* test edge U2,U1 against V0,V1 */ \ - EDGE_EDGE_TEST(V0,U2,U0); \ -} - -#define POINT_IN_TRI(V0,U0,U1,U2) \ -{ \ - dReal a,b,c,d0,d1,d2; \ - /* is T1 completly inside T2? */ \ - /* check if V0 is inside tri(U0,U1,U2) */ \ - a=U1[i1]-U0[i1]; \ - b=-(U1[i0]-U0[i0]); \ - c=-a*U0[i0]-b*U0[i1]; \ - d0=a*V0[i0]+b*V0[i1]+c; \ - \ - a=U2[i1]-U1[i1]; \ - b=-(U2[i0]-U1[i0]); \ - c=-a*U1[i0]-b*U1[i1]; \ - d1=a*V0[i0]+b*V0[i1]+c; \ - \ - a=U0[i1]-U2[i1]; \ - b=-(U0[i0]-U2[i0]); \ - c=-a*U2[i0]-b*U2[i1]; \ - d2=a*V0[i0]+b*V0[i1]+c; \ - if(d0*d1>0.0) \ - { \ - if(d0*d2>0.0) return 1; \ - } \ -} - -int coplanar_tri_tri(dReal N[3],dReal V0[3],dReal V1[3],dReal V2[3], - dReal U0[3],dReal U1[3],dReal U2[3]) -{ - dReal A[3]; - short i0,i1; - /* first project onto an axis-aligned plane, that maximizes the area */ - /* of the triangles, compute indices: i0,i1. */ - A[0]= (dReal) fabs(N[0]); - A[1]= (dReal) fabs(N[1]); - A[2]= (dReal) fabs(N[2]); - if(A[0]>A[1]) - { - if(A[0]>A[2]) - { - i0=1; /* A[0] is greatest */ - i1=2; - } - else - { - i0=0; /* A[2] is greatest */ - i1=1; - } - } - else /* A[0]<=A[1] */ - { - if(A[2]>A[1]) - { - i0=0; /* A[2] is greatest */ - i1=1; - } - else - { - i0=0; /* A[1] is greatest */ - i1=2; - } - } - - /* test all edges of triangle 1 against the edges of triangle 2 */ - EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2); - EDGE_AGAINST_TRI_EDGES(V1,V2,U0,U1,U2); - EDGE_AGAINST_TRI_EDGES(V2,V0,U0,U1,U2); - - /* finally, test if tri1 is totally contained in tri2 or vice versa */ - POINT_IN_TRI(V0,U0,U1,U2); - POINT_IN_TRI(U0,V0,V1,V2); - - return 0; -} - - - -#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \ -{ \ - if(D0D1>0.0f) \ - { \ - /* here we know that D0D2<=0.0 */ \ - /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ - A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ - } \ - else if(D0D2>0.0f)\ - { \ - /* here we know that d0d1<=0.0 */ \ - A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ - } \ - else if(D1*D2>0.0f || D0!=0.0f) \ - { \ - /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ - A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \ - } \ - else if(D1!=0.0f) \ - { \ - A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ - } \ - else if(D2!=0.0f) \ - { \ - A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ - } \ - else \ - { \ - /* triangles are coplanar */ \ - return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ - } \ -} - - - - -/* sort so that a<=b */ -#define SORT2(a,b,smallest) \ - if(a>b) \ - { \ - dReal c; \ - c=a; \ - a=b; \ - b=c; \ - smallest=1; \ - } \ - else smallest=0; - - -inline void isect2(dReal VTX0[3],dReal VTX1[3],dReal VTX2[3],dReal VV0,dReal VV1,dReal VV2, - dReal D0,dReal D1,dReal D2,dReal *isect0,dReal *isect1,dReal isectpoint0[3],dReal isectpoint1[3]) -{ - dReal tmp=D0/(D0-D1); - dReal diff[3]; - *isect0=VV0+(VV1-VV0)*tmp; - SUB(diff,VTX1,VTX0); - MULT(diff,diff,tmp); - ADD(isectpoint0,diff,VTX0); - tmp=D0/(D0-D2); - *isect1=VV0+(VV2-VV0)*tmp; - SUB(diff,VTX2,VTX0); - MULT(diff,diff,tmp); - ADD(isectpoint1,VTX0,diff); -} - - -#if 0 -#define ISECT2(VTX0,VTX1,VTX2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1) \ - tmp=D0/(D0-D1); \ - isect0=VV0+(VV1-VV0)*tmp; \ - SUB(diff,VTX1,VTX0); \ - MULT(diff,diff,tmp); \ - ADD(isectpoint0,diff,VTX0); \ - tmp=D0/(D0-D2); -/* isect1=VV0+(VV2-VV0)*tmp; \ */ -/* SUB(diff,VTX2,VTX0); \ */ -/* MULT(diff,diff,tmp); \ */ -/* ADD(isectpoint1,VTX0,diff); */ -#endif - -inline int compute_intervals_isectline(dReal VERT0[3],dReal VERT1[3],dReal VERT2[3], - dReal VV0,dReal VV1,dReal VV2,dReal D0,dReal D1,dReal D2, - dReal D0D1,dReal D0D2,dReal *isect0,dReal *isect1, - dReal isectpoint0[3],dReal isectpoint1[3]) -{ - if(D0D1>0.0f) - { - /* here we know that D0D2<=0.0 */ - /* that is D0, D1 are on the same side, D2 on the other or on the plane */ - isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D0D2>0.0f) - { - /* here we know that d0d1<=0.0 */ - isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D1*D2>0.0f || D0!=0.0f) - { - /* here we know that d0d1<=0.0 or that D0!=0.0 */ - isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D1!=0.0f) - { - isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,isect0,isect1,isectpoint0,isectpoint1); - } - else if(D2!=0.0f) - { - isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,isect0,isect1,isectpoint0,isectpoint1); - } - else - { - /* triangles are coplanar */ - return 1; - } - return 0; -} - -#define COMPUTE_INTERVALS_ISECTLINE(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,isect0,isect1,isectpoint0,isectpoint1) \ - if(D0D1>0.0f) \ - { \ - /* here we know that D0D2<=0.0 */ \ - /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ - isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ - } -#if 0 - else if(D0D2>0.0f) \ - { \ - /* here we know that d0d1<=0.0 */ \ - isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ - } \ - else if(D1*D2>0.0f || D0!=0.0f) \ - { \ - /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ - isect2(VERT0,VERT1,VERT2,VV0,VV1,VV2,D0,D1,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ - } \ - else if(D1!=0.0f) \ - { \ - isect2(VERT1,VERT0,VERT2,VV1,VV0,VV2,D1,D0,D2,&isect0,&isect1,isectpoint0,isectpoint1); \ - } \ - else if(D2!=0.0f) \ - { \ - isect2(VERT2,VERT0,VERT1,VV2,VV0,VV1,D2,D0,D1,&isect0,&isect1,isectpoint0,isectpoint1); \ - } \ - else \ - { \ - /* triangles are coplanar */ \ - coplanar=1; \ - return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); \ - } -#endif - - - -static int TriTriIntersectWithIsectLine(dReal V0[3],dReal V1[3],dReal V2[3], - dReal U0[3],dReal U1[3],dReal U2[3],int *coplanar, - dReal isectpt1[3],dReal isectpt2[3]) -{ - dReal E1[3],E2[3]; - dReal N1[3],N2[3],d1,d2; - dReal du0,du1,du2,dv0,dv1,dv2; - dReal D[3]; - dReal isect1[2], isect2[2]; - dReal isectpointA1[3],isectpointA2[3]; - dReal isectpointB1[3],isectpointB2[3]; - dReal du0du1,du0du2,dv0dv1,dv0dv2; - short index; - dReal vp0,vp1,vp2; - dReal up0,up1,up2; - dReal b,c,max; - int smallest1,smallest2; - - /* compute plane equation of triangle(V0,V1,V2) */ - SUB(E1,V1,V0); - SUB(E2,V2,V0); - CROSS(N1,E1,E2); - d1=-DOT(N1,V0); - /* plane equation 1: N1.X+d1=0 */ - - /* put U0,U1,U2 into plane equation 1 to compute signed distances to the plane*/ - du0=DOT(N1,U0)+d1; - du1=DOT(N1,U1)+d1; - du2=DOT(N1,U2)+d1; - - /* coplanarity robustness check */ -#if USE_EPSILON_TEST==TRUE - if(fabs(du0)0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */ - return 0; /* no intersection occurs */ - - /* compute plane of triangle (U0,U1,U2) */ - SUB(E1,U1,U0); - SUB(E2,U2,U0); - CROSS(N2,E1,E2); - d2=-DOT(N2,U0); - /* plane equation 2: N2.X+d2=0 */ - - /* put V0,V1,V2 into plane equation 2 */ - dv0=DOT(N2,V0)+d2; - dv1=DOT(N2,V1)+d2; - dv2=DOT(N2,V2)+d2; - -#if USE_EPSILON_TEST==TRUE - if(fabs(dv0)0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */ - return 0; /* no intersection occurs */ - - /* compute direction of intersection line */ - CROSS(D,N1,N2); - - /* compute and index to the largest component of D */ - max= (dReal) fabs(D[0]); - index=0; - b= (dReal) fabs(D[1]); - c= (dReal) fabs(D[2]); - if(b>max) max=b,index=1; - if(c>max) max=c,index=2; - - /* this is the simplified projection onto L*/ - vp0=V0[index]; - vp1=V1[index]; - vp2=V2[index]; - - up0=U0[index]; - up1=U1[index]; - up2=U2[index]; - - /* compute interval for triangle 1 */ - *coplanar=compute_intervals_isectline(V0,V1,V2,vp0,vp1,vp2,dv0,dv1,dv2, - dv0dv1,dv0dv2,&isect1[0],&isect1[1],isectpointA1,isectpointA2); - if(*coplanar) return coplanar_tri_tri(N1,V0,V1,V2,U0,U1,U2); - - - /* compute interval for triangle 2 */ - compute_intervals_isectline(U0,U1,U2,up0,up1,up2,du0,du1,du2, - du0du1,du0du2,&isect2[0],&isect2[1],isectpointB1,isectpointB2); - - SORT2(isect1[0],isect1[1],smallest1); - SORT2(isect2[0],isect2[1],smallest2); - - if(isect1[1]isect1[1]) - { - if(smallest1==0) { SET(isectpt2,isectpointA2); } - else { SET(isectpt2,isectpointA1); } - } - else - { - if(smallest2==0) { SET(isectpt2,isectpointB2); } - else { SET(isectpt2,isectpointB1); } - } - } - return 1; -} - - - - - -// Find the intersectiojn point between a coplanar line segement, -// defined by X1 and X2, and a ray defined by X3 and direction N. -// -// This forumla for this calculation is: -// (c x b) . (a x b) -// Q = x1 + a ------------------- -// | a x b | ^2 -// -// where a = x2 - x1 -// b = x4 - x3 -// c = x3 - x1 -// x1 and x2 are the edges of the triangle, and x3 is CoplanarPt -// and x4 is (CoplanarPt - n) -static int -IntersectLineSegmentRay(dVector3 x1, dVector3 x2, dVector3 x3, dVector3 n, - dVector3 out_pt) -{ - dVector3 a, b, c, x4; - - ADD(x4, x3, n); // x4 = x3 + n - - SUB(a, x2, x1); // a = x2 - x1 - SUB(b, x4, x3); - SUB(c, x3, x1); - - dVector3 tmp1, tmp2; - CROSS(tmp1, c, b); - CROSS(tmp2, a, b); - - dReal num, denom; - num = dDOT(tmp1, tmp2); - denom = LENGTH( tmp2 ); - - dReal s; - s = num /(denom*denom); - - for (int i=0; i<3; i++) - out_pt[i] = x1[i] + a[i]*s; - - // Test if this intersection is "behind" x3, w.r.t. n - SUB(a, x3, out_pt); - if (dDOT(a, n) > 0.0) - return 0; - - // Test if this intersection point is outside the edge limits, - // if (dot( (out_pt-x1), (out_pt-x2) ) < 0) it's inside - // else outside - SUB(a, out_pt, x1); - SUB(b, out_pt, x2); - if (dDOT(a,b) < 0.0) - return 1; - else - return 0; -} - - -// FindTriSolidIntersection - Clips the input trinagle TRI with the -// sides of a convex bounding solid, described by PLANES, returning -// the (convex) clipped polygon in CLIPPEDPOLYGON -// -static bool -FindTriSolidIntrsection(const dVector3 Tri[3], - const dVector4 Planes[6], int numSides, - LineContactSet& ClippedPolygon ) -{ - // Set up the LineContactSet structure - for (int k=0; k<3; k++) { - SET(ClippedPolygon.Points[k], Tri[k]); - } - ClippedPolygon.Count = 3; - - // Clip wrt the sides - for ( int i = 0; i < numSides; i++ ) - ClipConvexPolygonAgainstPlane( Planes[i], Planes[i][3], ClippedPolygon ); - - return (ClippedPolygon.Count > 0); -} - - - - -// ClipConvexPolygonAgainstPlane - Clip a a convex polygon, described by -// CONTACTS, with a plane (described by N and C). Note: the input -// vertices are assumed to be in counterclockwise order. -// -// This code is taken from The Nebula Device: -// http://nebuladevice.sourceforge.net/cgi-bin/twiki/view/Nebula/WebHome -// and is licensed under the following license: -// http://nebuladevice.sourceforge.net/doc/source/license.txt -// -static void -ClipConvexPolygonAgainstPlane( const dVector3 N, dReal C, - LineContactSet& Contacts ) -{ - // test on which side of line are the vertices - int Positive = 0, Negative = 0, PIndex = -1; - int Quantity = Contacts.Count; - - dReal Test[8]; - for ( int i = 0; i < Contacts.Count; i++ ) { - // An epsilon is used here because it is possible for the dot product - // and C to be exactly equal to each other (in theory), but differ - // slightly because of floating point problems. Thus, add a little - // to the test number to push actually equal numbers over the edge - // towards the positive. This should probably be somehow a relative - // tolerance, and I don't think multiplying by the constant is the best - // way to do this. - Test[i] = dDOT(N, Contacts.Points[i]) - C + dFabs(C)*1e-08; - - if (Test[i] >= REAL(0.0)) { - Positive++; - if (PIndex < 0) { - PIndex = i; - } - } - else Negative++; - } - - if (Positive > 0) { - if (Negative > 0) { - // plane transversely intersects polygon - dVector3 CV[8]; - int CQuantity = 0, Cur, Prv; - dReal T; - - if (PIndex > 0) { - // first clip vertex on line - Cur = PIndex; - Prv = Cur - 1; - T = Test[Cur] / (Test[Cur] - Test[Prv]); - CV[CQuantity][0] = Contacts.Points[Cur][0] - + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); - CV[CQuantity][1] = Contacts.Points[Cur][1] - + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); - CV[CQuantity][2] = Contacts.Points[Cur][2] - + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); - CV[CQuantity][3] = Contacts.Points[Cur][3] - + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); - CQuantity++; - - // vertices on positive side of line - while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { - CV[CQuantity][0] = Contacts.Points[Cur][0]; - CV[CQuantity][1] = Contacts.Points[Cur][1]; - CV[CQuantity][2] = Contacts.Points[Cur][2]; - CV[CQuantity][3] = Contacts.Points[Cur][3]; - CQuantity++; - Cur++; - } - - // last clip vertex on line - if (Cur < Quantity) { - Prv = Cur - 1; - } - else { - Cur = 0; - Prv = Quantity - 1; - } - - T = Test[Cur] / (Test[Cur] - Test[Prv]); - CV[CQuantity][0] = Contacts.Points[Cur][0] - + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); - CV[CQuantity][1] = Contacts.Points[Cur][1] - + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); - CV[CQuantity][2] = Contacts.Points[Cur][2] - + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); - CV[CQuantity][3] = Contacts.Points[Cur][3] - + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); - CQuantity++; - } - else { - // iPIndex is 0 - // vertices on positive side of line - Cur = 0; - while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { - CV[CQuantity][0] = Contacts.Points[Cur][0]; - CV[CQuantity][1] = Contacts.Points[Cur][1]; - CV[CQuantity][2] = Contacts.Points[Cur][2]; - CV[CQuantity][3] = Contacts.Points[Cur][3]; - CQuantity++; - Cur++; - } - - // last clip vertex on line - Prv = Cur - 1; - T = Test[Cur] / (Test[Cur] - Test[Prv]); - CV[CQuantity][0] = Contacts.Points[Cur][0] - + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); - CV[CQuantity][1] = Contacts.Points[Cur][1] - + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); - CV[CQuantity][2] = Contacts.Points[Cur][2] - + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); - CV[CQuantity][3] = Contacts.Points[Cur][3] - + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); - CQuantity++; - - // skip vertices on negative side - while (Cur < Quantity && Test[Cur] < REAL(0.0)) { - Cur++; - } - - // first clip vertex on line - if (Cur < Quantity) { - Prv = Cur - 1; - T = Test[Cur] / (Test[Cur] - Test[Prv]); - CV[CQuantity][0] = Contacts.Points[Cur][0] - + T * (Contacts.Points[Prv][0] - Contacts.Points[Cur][0]); - CV[CQuantity][1] = Contacts.Points[Cur][1] - + T * (Contacts.Points[Prv][1] - Contacts.Points[Cur][1]); - CV[CQuantity][2] = Contacts.Points[Cur][2] - + T * (Contacts.Points[Prv][2] - Contacts.Points[Cur][2]); - CV[CQuantity][3] = Contacts.Points[Cur][3] - + T * (Contacts.Points[Prv][3] - Contacts.Points[Cur][3]); - CQuantity++; - - // vertices on positive side of line - while (Cur < Quantity && Test[Cur] >= REAL(0.0)) { - CV[CQuantity][0] = Contacts.Points[Cur][0]; - CV[CQuantity][1] = Contacts.Points[Cur][1]; - CV[CQuantity][2] = Contacts.Points[Cur][2]; - CV[CQuantity][3] = Contacts.Points[Cur][3]; - CQuantity++; - Cur++; - } - } - else { - // iCur = 0 - Prv = Quantity - 1; - T = Test[0] / (Test[0] - Test[Prv]); - CV[CQuantity][0] = Contacts.Points[0][0] - + T * (Contacts.Points[Prv][0] - Contacts.Points[0][0]); - CV[CQuantity][1] = Contacts.Points[0][1] - + T * (Contacts.Points[Prv][1] - Contacts.Points[0][1]); - CV[CQuantity][2] = Contacts.Points[0][2] - + T * (Contacts.Points[Prv][2] - Contacts.Points[0][2]); - CV[CQuantity][3] = Contacts.Points[0][3] - + T * (Contacts.Points[Prv][3] - Contacts.Points[0][3]); - CQuantity++; - } - } - Quantity = CQuantity; - memcpy( Contacts.Points, CV, CQuantity * sizeof(dVector3) ); - } - // else polygon fully on positive side of plane, nothing to do - Contacts.Count = Quantity; - } - else { - Contacts.Count = 0; // This should not happen, but for safety - } - -} - - - -// Determine if a potential collision point is -// -// -static int -ExamineContactPoint(dVector3* v_col, dVector3 in_n, dVector3 in_point) -{ - // Cast a ray from in_point, along the collison normal. Does it intersect the - // collision face. - dReal t, u, v; - - if (!RayTriangleIntersect(in_point, in_n, v_col[0], v_col[1], v_col[2], - &t, &u, &v)) - return 0; - else - return 1; -} - - - -// RayTriangleIntersect - If an intersection is found, t contains the -// distance along the ray (dir) and u/v contain u/v coordinates into -// the triangle. Returns 0 if no hit is found -// From "Real-Time Rendering," page 305 -// -static int -RayTriangleIntersect(const dVector3 orig, const dVector3 dir, - const dVector3 vert0, const dVector3 vert1,const dVector3 vert2, - dReal *t,dReal *u,dReal *v) - -{ - dReal edge1[3], edge2[3], tvec[3], pvec[3], qvec[3]; - dReal det,inv_det; - - // find vectors for two edges sharing vert0 - SUB(edge1, vert1, vert0); - SUB(edge2, vert2, vert0); - - // begin calculating determinant - also used to calculate U parameter - CROSS(pvec, dir, edge2); - - // if determinant is near zero, ray lies in plane of triangle - det = DOT(edge1, pvec); - - if ((det > -0.001) && (det < 0.001)) - return 0; - inv_det = 1.0 / det; - - // calculate distance from vert0 to ray origin - SUB(tvec, orig, vert0); - - // calculate U parameter and test bounds - *u = DOT(tvec, pvec) * inv_det; - if ((*u < 0.0) || (*u > 1.0)) - return 0; - - // prepare to test V parameter - CROSS(qvec, tvec, edge1); - - // calculate V parameter and test bounds - *v = DOT(dir, qvec) * inv_det; - if ((*v < 0.0) || ((*u + *v) > 1.0)) - return 0; - - // calculate t, ray intersects triangle - *t = DOT(edge2, qvec) * inv_det; - - return 1; -} - - - -static bool -SimpleUnclippedTest(dVector3 in_CoplanarPt, dVector3 in_v, dVector3 in_elt, - dVector3 in_n, dVector3* in_col_v, dReal &out_depth) -{ - dReal dp = 0.0; - dReal contact_elt_length; - - DEPTH(dp, in_CoplanarPt, in_v, in_n); - - if (dp >= 0.0) { - // if the penetration depth (calculated above) is more than - // the contact point's ELT, then we've chosen the wrong face - // and should switch faces - contact_elt_length = fabs(dDOT(in_elt, in_n)); - - if (dp == 0.0) - dp = dMin(DISTANCE_EPSILON, contact_elt_length); - - if ((contact_elt_length < SMALL_ELT) && (dp < EXPANDED_ELT_THRESH)) - dp = contact_elt_length; - - if ( (dp > 0.0) && (dp <= contact_elt_length)) { - // Add a contact - - if ( ExamineContactPoint(in_col_v, in_n, in_v) ) { - out_depth = dp; - return true; - } - } - } - - return false; -} - - - - -// Generate a "unique" contact. A unique contact has a unique -// position or normal. If the potential contact has the same -// position and normal as an existing contact, but a larger -// penetration depth, this new depth is used instead -// -static void -GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, - dxTriMesh* in_TriMesh1, dxTriMesh* in_TriMesh2, - const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, - int& OutTriCount) -{ - if (in_Depth < 0.0) - return; - - if (OutTriCount == (in_Flags & 0x0ffff)) - return; // contacts are full! - - - dContactGeom* Contact; - dVector3 diff; - bool duplicate = false; - - for (int i=0; ipos); - if (dDOT(diff, diff) < 0.01) - { - // same normal? - if (fabs(dDOT(in_Normal, Contact->normal)) > 0.99 ) - { - if (in_Depth > Contact->depth) { - Contact->depth = in_Depth; - SMULT( Contact->normal, in_Normal, -1.0); - Contact->normal[3] = 0.0; - } - duplicate = true; - } - } - } - - - if (!duplicate) - { - // Add a new contact - Contact = SAFECONTACT(in_Flags, in_Contacts, OutTriCount, in_Stride); - - SET( Contact->pos, in_ContactPos ); - Contact->pos[3] = 0.0; - - SMULT( Contact->normal, in_Normal, -1.0); - Contact->normal[3] = 0.0; - - Contact->depth = in_Depth; - - Contact->g1 = in_TriMesh1; - Contact->g2 = in_TriMesh2; - - OutTriCount++; - } - - -} diff --git a/Extras/ode/ode/src/collision_util.cpp b/Extras/ode/ode/src/collision_util.cpp deleted file mode 100644 index 96a3b7868..000000000 --- a/Extras/ode/ode/src/collision_util.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -some useful collision utility stuff. this includes some API utility -functions that are defined in the public header files. - -*/ - -#include -#include -#include -#include "collision_util.h" - -//**************************************************************************** - -int dCollideSpheres (dVector3 p1, dReal r1, - dVector3 p2, dReal r2, dContactGeom *c) -{ - // printf ("d=%.2f (%.2f %.2f %.2f) (%.2f %.2f %.2f) r1=%.2f r2=%.2f\n", - // d,p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],r1,r2); - - dReal d = dDISTANCE (p1,p2); - if (d > (r1 + r2)) return 0; - if (d <= 0) { - c->pos[0] = p1[0]; - c->pos[1] = p1[1]; - c->pos[2] = p1[2]; - c->normal[0] = 1; - c->normal[1] = 0; - c->normal[2] = 0; - c->depth = r1 + r2; - } - else { - dReal d1 = dRecip (d); - c->normal[0] = (p1[0]-p2[0])*d1; - c->normal[1] = (p1[1]-p2[1])*d1; - c->normal[2] = (p1[2]-p2[2])*d1; - dReal k = REAL(0.5) * (r2 - r1 - d); - c->pos[0] = p1[0] + c->normal[0]*k; - c->pos[1] = p1[1] + c->normal[1]*k; - c->pos[2] = p1[2] + c->normal[2]*k; - c->depth = r1 + r2 - d; - } - return 1; -} - - -void dLineClosestApproach (const dVector3 pa, const dVector3 ua, - const dVector3 pb, const dVector3 ub, - dReal *alpha, dReal *beta) -{ - dVector3 p; - p[0] = pb[0] - pa[0]; - p[1] = pb[1] - pa[1]; - p[2] = pb[2] - pa[2]; - dReal uaub = dDOT(ua,ub); - dReal q1 = dDOT(ua,p); - dReal q2 = -dDOT(ub,p); - dReal d = 1-uaub*uaub; - if (d <= REAL(0.0001)) { - // @@@ this needs to be made more robust - *alpha = 0; - *beta = 0; - } - else { - d = dRecip(d); - *alpha = (q1 + uaub*q2)*d; - *beta = (uaub*q1 + q2)*d; - } -} - - -// given two line segments A and B with endpoints a1-a2 and b1-b2, return the -// points on A and B that are closest to each other (in cp1 and cp2). -// in the case of parallel lines where there are multiple solutions, a -// solution involving the endpoint of at least one line will be returned. -// this will work correctly for zero length lines, e.g. if a1==a2 and/or -// b1==b2. -// -// the algorithm works by applying the voronoi clipping rule to the features -// of the line segments. the three features of each line segment are the two -// endpoints and the line between them. the voronoi clipping rule states that, -// for feature X on line A and feature Y on line B, the closest points PA and -// PB between X and Y are globally the closest points if PA is in V(Y) and -// PB is in V(X), where V(X) is the voronoi region of X. - -void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2, - const dVector3 b1, const dVector3 b2, - dVector3 cp1, dVector3 cp2) -{ - dVector3 a1a2,b1b2,a1b1,a1b2,a2b1,a2b2,n; - dReal la,lb,k,da1,da2,da3,da4,db1,db2,db3,db4,det; - -#define SET2(a,b) a[0]=b[0]; a[1]=b[1]; a[2]=b[2]; -#define SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2]; - - // check vertex-vertex features - - SET3 (a1a2,a2,-,a1); - SET3 (b1b2,b2,-,b1); - SET3 (a1b1,b1,-,a1); - da1 = dDOT(a1a2,a1b1); - db1 = dDOT(b1b2,a1b1); - if (da1 <= 0 && db1 >= 0) { - SET2 (cp1,a1); - SET2 (cp2,b1); - return; - } - - SET3 (a1b2,b2,-,a1); - da2 = dDOT(a1a2,a1b2); - db2 = dDOT(b1b2,a1b2); - if (da2 <= 0 && db2 <= 0) { - SET2 (cp1,a1); - SET2 (cp2,b2); - return; - } - - SET3 (a2b1,b1,-,a2); - da3 = dDOT(a1a2,a2b1); - db3 = dDOT(b1b2,a2b1); - if (da3 >= 0 && db3 >= 0) { - SET2 (cp1,a2); - SET2 (cp2,b1); - return; - } - - SET3 (a2b2,b2,-,a2); - da4 = dDOT(a1a2,a2b2); - db4 = dDOT(b1b2,a2b2); - if (da4 >= 0 && db4 <= 0) { - SET2 (cp1,a2); - SET2 (cp2,b2); - return; - } - - // check edge-vertex features. - // if one or both of the lines has zero length, we will never get to here, - // so we do not have to worry about the following divisions by zero. - - la = dDOT(a1a2,a1a2); - if (da1 >= 0 && da3 <= 0) { - k = da1 / la; - SET3 (n,a1b1,-,k*a1a2); - if (dDOT(b1b2,n) >= 0) { - SET3 (cp1,a1,+,k*a1a2); - SET2 (cp2,b1); - return; - } - } - - if (da2 >= 0 && da4 <= 0) { - k = da2 / la; - SET3 (n,a1b2,-,k*a1a2); - if (dDOT(b1b2,n) <= 0) { - SET3 (cp1,a1,+,k*a1a2); - SET2 (cp2,b2); - return; - } - } - - lb = dDOT(b1b2,b1b2); - if (db1 <= 0 && db2 >= 0) { - k = -db1 / lb; - SET3 (n,-a1b1,-,k*b1b2); - if (dDOT(a1a2,n) >= 0) { - SET2 (cp1,a1); - SET3 (cp2,b1,+,k*b1b2); - return; - } - } - - if (db3 <= 0 && db4 >= 0) { - k = -db3 / lb; - SET3 (n,-a2b1,-,k*b1b2); - if (dDOT(a1a2,n) <= 0) { - SET2 (cp1,a2); - SET3 (cp2,b1,+,k*b1b2); - return; - } - } - - // it must be edge-edge - - k = dDOT(a1a2,b1b2); - det = la*lb - k*k; - if (det <= 0) { - // this should never happen, but just in case... - SET2(cp1,a1); - SET2(cp2,b1); - return; - } - det = dRecip (det); - dReal alpha = (lb*da1 - k*db1) * det; - dReal beta = ( k*da1 - la*db1) * det; - SET3 (cp1,a1,+,alpha*a1a2); - SET3 (cp2,b1,+,beta*b1b2); - -# undef SET2 -# undef SET3 -} - - -// a simple root finding algorithm is used to find the value of 't' that -// satisfies: -// d|D(t)|^2/dt = 0 -// where: -// |D(t)| = |p(t)-b(t)| -// where p(t) is a point on the line parameterized by t: -// p(t) = p1 + t*(p2-p1) -// and b(t) is that same point clipped to the boundary of the box. in box- -// relative coordinates d|D(t)|^2/dt is the sum of three x,y,z components -// each of which looks like this: -// -// t_lo / -// ______/ -->t -// / t_hi -// / -// -// t_lo and t_hi are the t values where the line passes through the planes -// corresponding to the sides of the box. the algorithm computes d|D(t)|^2/dt -// in a piecewise fashion from t=0 to t=1, stopping at the point where -// d|D(t)|^2/dt crosses from negative to positive. - -void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2, - const dVector3 c, const dMatrix3 R, - const dVector3 side, - dVector3 lret, dVector3 bret) -{ - int i; - - // compute the start and delta of the line p1-p2 relative to the box. - // we will do all subsequent computations in this box-relative coordinate - // system. we have to do a translation and rotation for each point. - dVector3 tmp,s,v; - tmp[0] = p1[0] - c[0]; - tmp[1] = p1[1] - c[1]; - tmp[2] = p1[2] - c[2]; - dMULTIPLY1_331 (s,R,tmp); - tmp[0] = p2[0] - p1[0]; - tmp[1] = p2[1] - p1[1]; - tmp[2] = p2[2] - p1[2]; - dMULTIPLY1_331 (v,R,tmp); - - // mirror the line so that v has all components >= 0 - dVector3 sign; - for (i=0; i<3; i++) { - if (v[i] < 0) { - s[i] = -s[i]; - v[i] = -v[i]; - sign[i] = -1; - } - else sign[i] = 1; - } - - // compute v^2 - dVector3 v2; - v2[0] = v[0]*v[0]; - v2[1] = v[1]*v[1]; - v2[2] = v[2]*v[2]; - - // compute the half-sides of the box - dReal h[3]; - h[0] = REAL(0.5) * side[0]; - h[1] = REAL(0.5) * side[1]; - h[2] = REAL(0.5) * side[2]; - - // region is -1,0,+1 depending on which side of the box planes each - // coordinate is on. tanchor is the next t value at which there is a - // transition, or the last one if there are no more. - int region[3]; - dReal tanchor[3]; - - // find the region and tanchor values for p1 - for (i=0; i<3; i++) { - if (v[i] > 0) { - if (s[i] < -h[i]) { - region[i] = -1; - tanchor[i] = (-h[i]-s[i])/v[i]; - } - else { - region[i] = (s[i] > h[i]); - tanchor[i] = (h[i]-s[i])/v[i]; - } - } - else { - region[i] = 0; - tanchor[i] = 2; // this will never be a valid tanchor - } - } - - // compute d|d|^2/dt for t=0. if it's >= 0 then p1 is the closest point - dReal t=0; - dReal dd2dt = 0; - for (i=0; i<3; i++) dd2dt -= (region[i] ? v2[i] : 0) * tanchor[i]; - if (dd2dt >= 0) goto got_answer; - - do { - // find the point on the line that is at the next clip plane boundary - dReal next_t = 1; - for (i=0; i<3; i++) { - if (tanchor[i] > t && tanchor[i] < 1 && tanchor[i] < next_t) - next_t = tanchor[i]; - } - - // compute d|d|^2/dt for the next t - dReal next_dd2dt = 0; - for (i=0; i<3; i++) { - next_dd2dt += (region[i] ? v2[i] : 0) * (next_t - tanchor[i]); - } - - // if the sign of d|d|^2/dt has changed, solution = the crossover point - if (next_dd2dt >= 0) { - dReal m = (next_dd2dt-dd2dt)/(next_t - t); - t -= dd2dt/m; - goto got_answer; - } - - // advance to the next anchor point / region - for (i=0; i<3; i++) { - if (tanchor[i] == next_t) { - tanchor[i] = (h[i]-s[i])/v[i]; - region[i]++; - } - } - t = next_t; - dd2dt = next_dd2dt; - } - while (t < 1); - t = 1; - - got_answer: - - // compute closest point on the line - for (i=0; i<3; i++) lret[i] = p1[i] + t*tmp[i]; // note: tmp=p2-p1 - - // compute closest point on the box - for (i=0; i<3; i++) { - tmp[i] = sign[i] * (s[i] + t*v[i]); - if (tmp[i] < -h[i]) tmp[i] = -h[i]; - else if (tmp[i] > h[i]) tmp[i] = h[i]; - } - dMULTIPLY0_331 (s,R,tmp); - for (i=0; i<3; i++) bret[i] = s[i] + c[i]; -} - - -// given boxes (p1,R1,side1) and (p1,R1,side1), return 1 if they intersect -// or 0 if not. - -int dBoxTouchesBox (const dVector3 p1, const dMatrix3 R1, - const dVector3 side1, const dVector3 p2, - const dMatrix3 R2, const dVector3 side2) -{ - // two boxes are disjoint if (and only if) there is a separating axis - // perpendicular to a face from one box or perpendicular to an edge from - // either box. the following tests are derived from: - // "OBB Tree: A Hierarchical Structure for Rapid Interference Detection", - // S.Gottschalk, M.C.Lin, D.Manocha., Proc of ACM Siggraph 1996. - - // Rij is R1'*R2, i.e. the relative rotation between R1 and R2. - // Qij is abs(Rij) - dVector3 p,pp; - dReal A1,A2,A3,B1,B2,B3,R11,R12,R13,R21,R22,R23,R31,R32,R33, - Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33; - - // get vector from centers of box 1 to box 2, relative to box 1 - p[0] = p2[0] - p1[0]; - p[1] = p2[1] - p1[1]; - p[2] = p2[2] - p1[2]; - dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1 - - // get side lengths / 2 - A1 = side1[0]*REAL(0.5); A2 = side1[1]*REAL(0.5); A3 = side1[2]*REAL(0.5); - B1 = side2[0]*REAL(0.5); B2 = side2[1]*REAL(0.5); B3 = side2[2]*REAL(0.5); - - // for the following tests, excluding computation of Rij, in the worst case, - // 15 compares, 60 adds, 81 multiplies, and 24 absolutes. - // notation: R1=[u1 u2 u3], R2=[v1 v2 v3] - - // separating axis = u1,u2,u3 - R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); - Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13); - if (dFabs(pp[0]) > (A1 + B1*Q11 + B2*Q12 + B3*Q13)) return 0; - R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); - Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23); - if (dFabs(pp[1]) > (A2 + B1*Q21 + B2*Q22 + B3*Q23)) return 0; - R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); - Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33); - if (dFabs(pp[2]) > (A3 + B1*Q31 + B2*Q32 + B3*Q33)) return 0; - - // separating axis = v1,v2,v3 - if (dFabs(dDOT41(R2+0,p)) > (A1*Q11 + A2*Q21 + A3*Q31 + B1)) return 0; - if (dFabs(dDOT41(R2+1,p)) > (A1*Q12 + A2*Q22 + A3*Q32 + B2)) return 0; - if (dFabs(dDOT41(R2+2,p)) > (A1*Q13 + A2*Q23 + A3*Q33 + B3)) return 0; - - // separating axis = u1 x (v1,v2,v3) - if (dFabs(pp[2]*R21-pp[1]*R31) > A2*Q31 + A3*Q21 + B2*Q13 + B3*Q12) return 0; - if (dFabs(pp[2]*R22-pp[1]*R32) > A2*Q32 + A3*Q22 + B1*Q13 + B3*Q11) return 0; - if (dFabs(pp[2]*R23-pp[1]*R33) > A2*Q33 + A3*Q23 + B1*Q12 + B2*Q11) return 0; - - // separating axis = u2 x (v1,v2,v3) - if (dFabs(pp[0]*R31-pp[2]*R11) > A1*Q31 + A3*Q11 + B2*Q23 + B3*Q22) return 0; - if (dFabs(pp[0]*R32-pp[2]*R12) > A1*Q32 + A3*Q12 + B1*Q23 + B3*Q21) return 0; - if (dFabs(pp[0]*R33-pp[2]*R13) > A1*Q33 + A3*Q13 + B1*Q22 + B2*Q21) return 0; - - // separating axis = u3 x (v1,v2,v3) - if (dFabs(pp[1]*R11-pp[0]*R21) > A1*Q21 + A2*Q11 + B2*Q33 + B3*Q32) return 0; - if (dFabs(pp[1]*R12-pp[0]*R22) > A1*Q22 + A2*Q12 + B1*Q33 + B3*Q31) return 0; - if (dFabs(pp[1]*R13-pp[0]*R23) > A1*Q23 + A2*Q13 + B1*Q32 + B2*Q31) return 0; - - return 1; -} - -//**************************************************************************** -// other utility functions - -void dInfiniteAABB (dxGeom *geom, dReal aabb[6]) -{ - aabb[0] = -dInfinity; - aabb[1] = dInfinity; - aabb[2] = -dInfinity; - aabb[3] = dInfinity; - aabb[4] = -dInfinity; - aabb[5] = dInfinity; -} diff --git a/Extras/ode/ode/src/collision_util.h b/Extras/ode/ode/src/collision_util.h deleted file mode 100644 index 4c5fb0814..000000000 --- a/Extras/ode/ode/src/collision_util.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -some useful collision utility stuff. - -*/ - -#ifndef _ODE_COLLISION_UTIL_H_ -#define _ODE_COLLISION_UTIL_H_ - -#include -#include - - -// given a pointer `p' to a dContactGeom, return the dContactGeom at -// p + skip bytes. -#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) - - -// if the spheres (p1,r1) and (p2,r2) collide, set the contact `c' and -// return 1, else return 0. - -int dCollideSpheres (dVector3 p1, dReal r1, - dVector3 p2, dReal r2, dContactGeom *c); - - -// given two lines -// qa = pa + alpha* ua -// qb = pb + beta * ub -// where pa,pb are two points, ua,ub are two unit length vectors, and alpha, -// beta go from [-inf,inf], return alpha and beta such that qa and qb are -// as close as possible - -void dLineClosestApproach (const dVector3 pa, const dVector3 ua, - const dVector3 pb, const dVector3 ub, - dReal *alpha, dReal *beta); - - -// given a line segment p1-p2 and a box (center 'c', rotation 'R', side length -// vector 'side'), compute the points of closest approach between the box -// and the line. return these points in 'lret' (the point on the line) and -// 'bret' (the point on the box). if the line actually penetrates the box -// then the solution is not unique, but only one solution will be returned. -// in this case the solution points will coincide. - -void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2, - const dVector3 c, const dMatrix3 R, - const dVector3 side, - dVector3 lret, dVector3 bret); - -#endif diff --git a/Extras/ode/ode/src/error.cpp b/Extras/ode/ode/src/error.cpp deleted file mode 100644 index 9b33db55f..000000000 --- a/Extras/ode/ode/src/error.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include - - -static dMessageFunction *error_function = 0; -static dMessageFunction *debug_function = 0; -static dMessageFunction *message_function = 0; - - -extern "C" void dSetErrorHandler (dMessageFunction *fn) -{ - error_function = fn; -} - - -extern "C" void dSetDebugHandler (dMessageFunction *fn) -{ - debug_function = fn; -} - - -extern "C" void dSetMessageHandler (dMessageFunction *fn) -{ - message_function = fn; -} - - -extern "C" dMessageFunction *dGetErrorHandler() -{ - return error_function; -} - - -extern "C" dMessageFunction *dGetDebugHandler() -{ - return debug_function; -} - - -extern "C" dMessageFunction *dGetMessageHandler() -{ - return message_function; -} - - -static void printMessage (int num, const char *msg1, const char *msg2, - va_list ap) -{ - fflush (stderr); - fflush (stdout); - if (num) fprintf (stderr,"\n%s %d: ",msg1,num); - else fprintf (stderr,"\n%s: ",msg1); - vfprintf (stderr,msg2,ap); - fprintf (stderr,"\n"); - fflush (stderr); -} - -//**************************************************************************** -// unix - -#ifndef WIN32 - -extern "C" void dError (int num, const char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - if (error_function) error_function (num,msg,ap); - else printMessage (num,"ODE Error",msg,ap); - exit (1); -} - - -extern "C" void dDebug (int num, const char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - if (debug_function) debug_function (num,msg,ap); - else printMessage (num,"ODE INTERNAL ERROR",msg,ap); - // *((char *)0) = 0; ... commit SEGVicide - abort(); -} - - -extern "C" void dMessage (int num, const char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - if (message_function) message_function (num,msg,ap); - else printMessage (num,"ODE Message",msg,ap); -} - -#endif - -//**************************************************************************** -// windows - -#ifdef WIN32 - -// isn't cygwin annoying! -#ifdef CYGWIN -#define _snprintf snprintf -#define _vsnprintf vsnprintf -#endif - - -#include "windows.h" - - -extern "C" void dError (int num, const char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - if (error_function) error_function (num,msg,ap); - else { - char s[1000],title[100]; - _snprintf (title,sizeof(title),"ODE Error %d",num); - _vsnprintf (s,sizeof(s),msg,ap); - s[sizeof(s)-1] = 0; - MessageBox(0,s,title,MB_OK | MB_ICONWARNING); - } - exit (1); -} - - -extern "C" void dDebug (int num, const char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - if (debug_function) debug_function (num,msg,ap); - else { - char s[1000],title[100]; - _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num); - _vsnprintf (s,sizeof(s),msg,ap); - s[sizeof(s)-1] = 0; - MessageBox(0,s,title,MB_OK | MB_ICONSTOP); - } - abort(); -} - - -extern "C" void dMessage (int num, const char *msg, ...) -{ - va_list ap; - va_start (ap,msg); - if (message_function) message_function (num,msg,ap); - else printMessage (num,"ODE Message",msg,ap); -} - - -#endif diff --git a/Extras/ode/ode/src/export-dif.cpp b/Extras/ode/ode/src/export-dif.cpp deleted file mode 100644 index 8a73beade..000000000 --- a/Extras/ode/ode/src/export-dif.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - * Export a DIF (Dynamics Interchange Format) file. - */ - - -// @@@ TODO: -// * export all spaces, and geoms in spaces, not just ones attached to bodies -// (separate export function?) -// * say the space each geom is in, so reader can construct space heirarchy -// * limot --> separate out into limits and motors? -// * make sure ODE-specific parameters divided out - - -#include "ode/ode.h" -#include "objects.h" -#include "joint.h" -#include "collision_kernel.h" - -//*************************************************************************** -// utility - -struct PrintingContext { - FILE *file; // file to write to - int precision; // digits of precision to print - int indent; // number of levels of indent - - void printIndent(); - void printReal (dReal x); - void print (const char *name, int x); - void print (const char *name, dReal x); - void print (const char *name, const dReal *x, int n=3); - void print (const char *name, const char *x=0); - void printNonzero (const char *name, dReal x); - void printNonzero (const char *name, const dReal x[3]); -}; - - -void PrintingContext::printIndent() -{ - for (int i=0; i= 0) { - c.printIndent(); - fprintf (c.file,"limit%d = {\n",num); - } - else { - c.print ("limit = {"); - } - c.indent++; - c.print ("low_stop",limot.lostop); - c.print ("high_stop",limot.histop); - c.printNonzero ("bounce",limot.bounce); - c.print ("ODE = {"); - c.indent++; - c.printNonzero ("stop_erp",limot.stop_erp); - c.printNonzero ("stop_cfm",limot.stop_cfm); - c.indent--; - c.print ("},"); - c.indent--; - c.print ("},"); - - if (num >= 0) { - c.printIndent(); - fprintf (c.file,"motor%d = {\n",num); - } - else { - c.print ("motor = {"); - } - c.indent++; - c.printNonzero ("vel",limot.vel); - c.printNonzero ("fmax",limot.fmax); - c.print ("ODE = {"); - c.indent++; - c.printNonzero ("fudge_factor",limot.fudge_factor); - c.printNonzero ("normal_cfm",limot.normal_cfm); - c.indent--; - c.print ("},"); - c.indent--; - c.print ("},"); -} - - -static const char *getJointName (dxJoint *j) -{ - switch (j->vtable->typenum) { - case dJointTypeBall: return "ball"; - case dJointTypeHinge: return "hinge"; - case dJointTypeSlider: return "slider"; - case dJointTypeContact: return "contact"; - case dJointTypeUniversal: return "universal"; - case dJointTypeHinge2: return "ODE_hinge2"; - case dJointTypeFixed: return "fixed"; - case dJointTypeNull: return "null"; - case dJointTypeAMotor: return "ODE_angular_motor"; - } - return "unknown"; -} - - -static void printBall (PrintingContext &c, dxJoint *j) -{ - dxJointBall *b = (dxJointBall*) j; - c.print ("anchor1",b->anchor1); - c.print ("anchor2",b->anchor2); -} - - -static void printHinge (PrintingContext &c, dxJoint *j) -{ - dxJointHinge *h = (dxJointHinge*) j; - c.print ("anchor1",h->anchor1); - c.print ("anchor2",h->anchor2); - c.print ("axis1",h->axis1); - c.print ("axis2",h->axis2); - c.print ("qrel",h->qrel,4); - printLimot (c,h->limot,-1); -} - - -static void printSlider (PrintingContext &c, dxJoint *j) -{ - dxJointSlider *s = (dxJointSlider*) j; - c.print ("axis1",s->axis1); - c.print ("qrel",s->qrel,4); - c.print ("offset",s->offset); - printLimot (c,s->limot,-1); -} - - -static void printContact (PrintingContext &c, dxJoint *j) -{ - dxJointContact *ct = (dxJointContact*) j; - int mode = ct->contact.surface.mode; - c.print ("pos",ct->contact.geom.pos); - c.print ("normal",ct->contact.geom.normal); - c.print ("depth",ct->contact.geom.depth); - //@@@ may want to write the geoms g1 and g2 that are involved, for debugging. - // to do this we must have written out all geoms in all spaces, not just - // geoms that are attached to bodies. - c.print ("mu",ct->contact.surface.mu); - if (mode & dContactMu2) c.print ("mu2",ct->contact.surface.mu2); - if (mode & dContactBounce) c.print ("bounce",ct->contact.surface.bounce); - if (mode & dContactBounce) c.print ("bounce_vel",ct->contact.surface.bounce_vel); - if (mode & dContactSoftERP) c.print ("soft_ERP",ct->contact.surface.soft_erp); - if (mode & dContactSoftCFM) c.print ("soft_CFM",ct->contact.surface.soft_cfm); - if (mode & dContactMotion1) c.print ("motion1",ct->contact.surface.motion1); - if (mode & dContactMotion2) c.print ("motion2",ct->contact.surface.motion2); - if (mode & dContactSlip1) c.print ("slip1",ct->contact.surface.slip1); - if (mode & dContactSlip2) c.print ("slip2",ct->contact.surface.slip2); - int fa = 0; // friction approximation code - if (mode & dContactApprox1_1) fa |= 1; - if (mode & dContactApprox1_2) fa |= 2; - if (fa) c.print ("friction_approximation",fa); - if (mode & dContactFDir1) c.print ("fdir1",ct->contact.fdir1); -} - - -static void printUniversal (PrintingContext &c, dxJoint *j) -{ - dxJointUniversal *u = (dxJointUniversal*) j; - c.print ("anchor1",u->anchor1); - c.print ("anchor2",u->anchor2); - c.print ("axis1",u->axis1); - c.print ("axis2",u->axis2); - c.print ("qrel1",u->qrel1,4); - c.print ("qrel2",u->qrel2,4); - printLimot (c,u->limot1,1); - printLimot (c,u->limot2,2); -} - - -static void printHinge2 (PrintingContext &c, dxJoint *j) -{ - dxJointHinge2 *h = (dxJointHinge2*) j; - c.print ("anchor1",h->anchor1); - c.print ("anchor2",h->anchor2); - c.print ("axis1",h->axis1); - c.print ("axis2",h->axis2); - c.print ("v1",h->v1); //@@@ much better to write out 'qrel' here, if it's available - c.print ("v2",h->v2); - c.print ("susp_erp",h->susp_erp); - c.print ("susp_cfm",h->susp_cfm); - printLimot (c,h->limot1,1); - printLimot (c,h->limot2,2); -} - - -static void printFixed (PrintingContext &c, dxJoint *j) -{ - dxJointFixed *f = (dxJointFixed*) j; - c.print ("qrel",f->qrel); - c.print ("offset",f->offset); -} - - -static void printAMotor (PrintingContext &c, dxJoint *j) -{ - dxJointAMotor *a = (dxJointAMotor*) j; - c.print ("num",a->num); - c.print ("mode",a->mode); - c.printIndent(); - fprintf (c.file,"rel = {%d,%d,%d},\n",a->rel[0],a->rel[1],a->rel[2]); - c.print ("axis1",a->axis[0]); - c.print ("axis2",a->axis[1]); - c.print ("axis3",a->axis[2]); - for (int i=0; i<3; i++) printLimot (c,a->limot[i],i+1); - c.print ("angle1",a->angle[0]); - c.print ("angle2",a->angle[1]); - c.print ("angle3",a->angle[2]); -} - -//*************************************************************************** -// geometry - -static void printGeom (PrintingContext &c, dxGeom *g); - -static void printSphere (PrintingContext &c, dxGeom *g) -{ - c.print ("type","sphere"); - c.print ("radius",dGeomSphereGetRadius (g)); -} - - -static void printBox (PrintingContext &c, dxGeom *g) -{ - dVector3 sides; - dGeomBoxGetLengths (g,sides); - c.print ("type","box"); - c.print ("sides",sides); -} - - - -static void printCCylinder (PrintingContext &c, dxGeom *g) -{ - dReal radius,length; - dGeomCCylinderGetParams (g,&radius,&length); - c.print ("type","capsule"); - c.print ("radius",radius); - c.print ("length",length); -} - - -static void printPlane (PrintingContext &c, dxGeom *g) -{ - dVector4 e; - dGeomPlaneGetParams (g,e); - c.print ("type","plane"); - c.print ("normal",e); - c.print ("d",e[3]); -} - - - -static void printRay (PrintingContext &c, dxGeom *g) -{ - dReal length = dGeomRayGetLength (g); - c.print ("type","ray"); - c.print ("length",length); -} - - - -static void printGeomTransform (PrintingContext &c, dxGeom *g) -{ - dxGeom *g2 = dGeomTransformGetGeom (g); - const dReal *pos = dGeomGetPosition (g2); - dQuaternion q; - dGeomGetQuaternion (g2,q); - c.print ("type","transform"); - c.print ("pos",pos); - c.print ("q",q,4); - c.print ("geometry = {"); - c.indent++; - printGeom (c,g2); - c.indent--; - c.print ("}"); -} - - - -static void printTriMesh (PrintingContext &c, dxGeom *g) -{ - c.print ("type","trimesh"); - //@@@ i don't think that the trimesh accessor functions are really - // sufficient to read out all the triangle data, and anyway we - // should have a method of not duplicating trimesh data that is - // shared. -} - - -static void printGeom (PrintingContext &c, dxGeom *g) -{ - unsigned long category = dGeomGetCategoryBits (g); - if (category != (unsigned long)(~0)) { - c.printIndent(); - fprintf (c.file,"category_bits = %lu\n",category); - } - unsigned long collide = dGeomGetCollideBits (g); - if (collide != (unsigned long)(~0)) { - c.printIndent(); - fprintf (c.file,"collide_bits = %lu\n",collide); - } - if (!dGeomIsEnabled (g)) { - c.print ("disabled",1); - } - switch (g->type) { - case dSphereClass: printSphere (c,g); break; - case dBoxClass: printBox (c,g); break; - case dCCylinderClass: printCCylinder (c,g); break; - case dPlaneClass: printPlane (c,g); break; - case dRayClass: printRay (c,g); break; - case dGeomTransformClass: printGeomTransform (c,g); break; - case dTriMeshClass: printTriMesh (c,g); break; - } -} - -//*************************************************************************** -// world - -void dWorldExportDIF (dWorldID w, FILE *file, const char *prefix) -{ - PrintingContext c; - c.file = file; -#if defined(dSINGLE) - c.precision = 7; -#else - c.precision = 15; -#endif - c.indent = 1; - - fprintf (file,"-- Dynamics Interchange Format v0.1\n\n%sworld = dynamics.world {\n",prefix); - c.print ("gravity",w->gravity); - c.print ("ODE = {"); - c.indent++; - c.print ("ERP",w->global_erp); - c.print ("CFM",w->global_cfm); - c.print ("auto_disable = {"); - c.indent++; - c.print ("linear_threshold",w->adis.linear_threshold); - c.print ("angular_threshold",w->adis.angular_threshold); - c.print ("idle_time",w->adis.idle_time); - c.print ("idle_steps",w->adis.idle_steps); - fprintf (file,"\t\t},\n\t},\n}\n"); - c.indent -= 3; - - // bodies - int num = 0; - fprintf (file,"%sbody = {}\n",prefix); - for (dxBody *b=w->firstbody; b; b=(dxBody*)b->next) { - b->tag = num; - fprintf (file,"%sbody[%d] = dynamics.body {\n\tworld = %sworld,\n",prefix,num,prefix); - c.indent++; - c.print ("pos",b->pos); - c.print ("q",b->q,4); - c.print ("lvel",b->lvel); - c.print ("avel",b->avel); - c.print ("mass",b->mass.mass); - fprintf (file,"\tI = {{"); - for (int i=0; i<3; i++) { - for (int j=0; j<3; j++) { - c.printReal (b->mass.I[i*4+j]); - if (j < 2) fputc (',',file); - } - if (i < 2) fprintf (file,"},{"); - } - fprintf (file,"}},\n"); - c.printNonzero ("com",b->mass.c); - c.print ("ODE = {"); - c.indent++; - if (b->flags & dxBodyFlagFiniteRotation) c.print ("finite_rotation",1); - if (b->flags & dxBodyDisabled) c.print ("disabled",1); - if (b->flags & dxBodyNoGravity) c.print ("no_gravity",1); - if (b->flags & dxBodyAutoDisable) { - c.print ("auto_disable = {"); - c.indent++; - c.print ("linear_threshold",b->adis.linear_threshold); - c.print ("angular_threshold",b->adis.angular_threshold); - c.print ("idle_time",b->adis.idle_time); - c.print ("idle_steps",b->adis.idle_steps); - c.print ("time_left",b->adis_timeleft); - c.print ("steps_left",b->adis_stepsleft); - c.indent--; - c.print ("},"); - } - c.printNonzero ("facc",b->facc); - c.printNonzero ("tacc",b->tacc); - if (b->flags & dxBodyFlagFiniteRotationAxis) { - c.print ("finite_rotation_axis",b->finite_rot_axis); - } - c.indent--; - c.print ("},"); - if (b->geom) { - c.print ("geometry = {"); - c.indent++; - for (dxGeom *g=b->geom; g; g=g->body_next) { - c.print ("{"); - c.indent++; - printGeom (c,g); - c.indent--; - c.print ("},"); - } - c.indent--; - c.print ("},"); - } - c.indent--; - c.print ("}"); - num++; - } - - // joints - num = 0; - fprintf (file,"%sjoint = {}\n",prefix); - for (dxJoint *j=w->firstjoint; j; j=(dxJoint*)j->next) { - c.indent++; - const char *name = getJointName (j); - fprintf (file, - "%sjoint[%d] = dynamics.%s_joint {\n" - "\tworld = %sworld,\n" - "\tbody = {%sbody[%d]" - ,prefix,num,name,prefix,prefix,j->node[0].body->tag); - if (j->node[1].body) fprintf (file,",%sbody[%d]",prefix,j->node[1].body->tag); - fprintf (file,"},\n"); - switch (j->vtable->typenum) { - case dJointTypeBall: printBall (c,j); break; - case dJointTypeHinge: printHinge (c,j); break; - case dJointTypeSlider: printSlider (c,j); break; - case dJointTypeContact: printContact (c,j); break; - case dJointTypeUniversal: printUniversal (c,j); break; - case dJointTypeHinge2: printHinge2 (c,j); break; - case dJointTypeFixed: printFixed (c,j); break; - case dJointTypeAMotor: printAMotor (c,j); break; - } - c.indent--; - c.print ("}"); - num++; - } -} diff --git a/Extras/ode/ode/src/fastdot.c b/Extras/ode/ode/src/fastdot.c deleted file mode 100644 index 148d2dd9e..000000000 --- a/Extras/ode/ode/src/fastdot.c +++ /dev/null @@ -1,30 +0,0 @@ -/* generated code, do not edit. */ - -#include "ode/matrix.h" - - -dReal dDot (const dReal *a, const dReal *b, int n) -{ - dReal p0,q0,m0,p1,q1,m1,sum; - sum = 0; - n -= 2; - while (n >= 0) { - p0 = a[0]; q0 = b[0]; - m0 = p0 * q0; - p1 = a[1]; q1 = b[1]; - m1 = p1 * q1; - sum += m0; - sum += m1; - a += 2; - b += 2; - n -= 2; - } - n += 2; - while (n > 0) { - sum += (*a) * (*b); - a++; - b++; - n--; - } - return sum; -} diff --git a/Extras/ode/ode/src/fastldlt.c b/Extras/ode/ode/src/fastldlt.c deleted file mode 100644 index df2ea6ec2..000000000 --- a/Extras/ode/ode/src/fastldlt.c +++ /dev/null @@ -1,381 +0,0 @@ -/* generated code, do not edit. */ - -#include "ode/matrix.h" - -/* solve L*X=B, with B containing 1 right hand sides. - * L is an n*n lower triangular matrix with ones on the diagonal. - * L is stored by rows and its leading dimension is lskip. - * B is an n*1 matrix that contains the right hand sides. - * B is stored by columns and its leading dimension is also lskip. - * B is overwritten with X. - * this processes blocks of 2*2. - * if this is in the factorizer source file, n must be a multiple of 2. - */ - -static void dSolveL1_1 (const dReal *L, dReal *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - dReal Z11,m11,Z21,m21,p1,q1,p2,*ex; - const dReal *ell; - int i,j; - /* compute all 2 x 1 blocks of X */ - for (i=0; i < n; i+=2) { - /* compute all 2 x 1 block of X, from rows i..i+2-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z21=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-2; j >= 0; j -= 2) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - p2=ell[lskip1]; - m21 = p2 * q1; - Z11 += m11; - Z21 += m21; - /* compute outer product and add it to the Z matrix */ - p1=ell[1]; - q1=ex[1]; - m11 = p1 * q1; - p2=ell[1+lskip1]; - m21 = p2 * q1; - /* advance pointers */ - ell += 2; - ex += 2; - Z11 += m11; - Z21 += m21; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 2; - for (; j > 0; j--) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - p2=ell[lskip1]; - m21 = p2 * q1; - /* advance pointers */ - ell += 1; - ex += 1; - Z11 += m11; - Z21 += m21; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - p1 = ell[lskip1]; - Z21 = ex[1] - Z21 - p1*Z11; - ex[1] = Z21; - /* end of outer loop */ - } -} - -/* solve L*X=B, with B containing 2 right hand sides. - * L is an n*n lower triangular matrix with ones on the diagonal. - * L is stored by rows and its leading dimension is lskip. - * B is an n*2 matrix that contains the right hand sides. - * B is stored by columns and its leading dimension is also lskip. - * B is overwritten with X. - * this processes blocks of 2*2. - * if this is in the factorizer source file, n must be a multiple of 2. - */ - -static void dSolveL1_2 (const dReal *L, dReal *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - dReal Z11,m11,Z12,m12,Z21,m21,Z22,m22,p1,q1,p2,q2,*ex; - const dReal *ell; - int i,j; - /* compute all 2 x 2 blocks of X */ - for (i=0; i < n; i+=2) { - /* compute all 2 x 2 block of X, from rows i..i+2-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z12=0; - Z21=0; - Z22=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-2; j >= 0; j -= 2) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - q2=ex[lskip1]; - m12 = p1 * q2; - p2=ell[lskip1]; - m21 = p2 * q1; - m22 = p2 * q2; - Z11 += m11; - Z12 += m12; - Z21 += m21; - Z22 += m22; - /* compute outer product and add it to the Z matrix */ - p1=ell[1]; - q1=ex[1]; - m11 = p1 * q1; - q2=ex[1+lskip1]; - m12 = p1 * q2; - p2=ell[1+lskip1]; - m21 = p2 * q1; - m22 = p2 * q2; - /* advance pointers */ - ell += 2; - ex += 2; - Z11 += m11; - Z12 += m12; - Z21 += m21; - Z22 += m22; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 2; - for (; j > 0; j--) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - q2=ex[lskip1]; - m12 = p1 * q2; - p2=ell[lskip1]; - m21 = p2 * q1; - m22 = p2 * q2; - /* advance pointers */ - ell += 1; - ex += 1; - Z11 += m11; - Z12 += m12; - Z21 += m21; - Z22 += m22; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - Z12 = ex[lskip1] - Z12; - ex[lskip1] = Z12; - p1 = ell[lskip1]; - Z21 = ex[1] - Z21 - p1*Z11; - ex[1] = Z21; - Z22 = ex[1+lskip1] - Z22 - p1*Z12; - ex[1+lskip1] = Z22; - /* end of outer loop */ - } -} - - -void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1) -{ - int i,j; - dReal sum,*ell,*dee,dd,p1,p2,q1,q2,Z11,m11,Z21,m21,Z22,m22; - if (n < 1) return; - - for (i=0; i<=n-2; i += 2) { - /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */ - dSolveL1_2 (A,A+i*nskip1,i,nskip1); - /* scale the elements in a 2 x i block at A(i,0), and also */ - /* compute Z = the outer product matrix that we'll need. */ - Z11 = 0; - Z21 = 0; - Z22 = 0; - ell = A+i*nskip1; - dee = d; - for (j=i-6; j >= 0; j -= 6) { - p1 = ell[0]; - p2 = ell[nskip1]; - dd = dee[0]; - q1 = p1*dd; - q2 = p2*dd; - ell[0] = q1; - ell[nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[1]; - p2 = ell[1+nskip1]; - dd = dee[1]; - q1 = p1*dd; - q2 = p2*dd; - ell[1] = q1; - ell[1+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[2]; - p2 = ell[2+nskip1]; - dd = dee[2]; - q1 = p1*dd; - q2 = p2*dd; - ell[2] = q1; - ell[2+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[3]; - p2 = ell[3+nskip1]; - dd = dee[3]; - q1 = p1*dd; - q2 = p2*dd; - ell[3] = q1; - ell[3+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[4]; - p2 = ell[4+nskip1]; - dd = dee[4]; - q1 = p1*dd; - q2 = p2*dd; - ell[4] = q1; - ell[4+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[5]; - p2 = ell[5+nskip1]; - dd = dee[5]; - q1 = p1*dd; - q2 = p2*dd; - ell[5] = q1; - ell[5+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - ell += 6; - dee += 6; - } - /* compute left-over iterations */ - j += 6; - for (; j > 0; j--) { - p1 = ell[0]; - p2 = ell[nskip1]; - dd = dee[0]; - q1 = p1*dd; - q2 = p2*dd; - ell[0] = q1; - ell[nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - ell++; - dee++; - } - /* solve for diagonal 2 x 2 block at A(i,i) */ - Z11 = ell[0] - Z11; - Z21 = ell[nskip1] - Z21; - Z22 = ell[1+nskip1] - Z22; - dee = d + i; - /* factorize 2 x 2 block Z,dee */ - /* factorize row 1 */ - dee[0] = dRecip(Z11); - /* factorize row 2 */ - sum = 0; - q1 = Z21; - q2 = q1 * dee[0]; - Z21 = q2; - sum += q1*q2; - dee[1] = dRecip(Z22 - sum); - /* done factorizing 2 x 2 block */ - ell[nskip1] = Z21; - } - /* compute the (less than 2) rows at the bottom */ - switch (n-i) { - case 0: - break; - - case 1: - dSolveL1_1 (A,A+i*nskip1,i,nskip1); - /* scale the elements in a 1 x i block at A(i,0), and also */ - /* compute Z = the outer product matrix that we'll need. */ - Z11 = 0; - ell = A+i*nskip1; - dee = d; - for (j=i-6; j >= 0; j -= 6) { - p1 = ell[0]; - dd = dee[0]; - q1 = p1*dd; - ell[0] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[1]; - dd = dee[1]; - q1 = p1*dd; - ell[1] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[2]; - dd = dee[2]; - q1 = p1*dd; - ell[2] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[3]; - dd = dee[3]; - q1 = p1*dd; - ell[3] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[4]; - dd = dee[4]; - q1 = p1*dd; - ell[4] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[5]; - dd = dee[5]; - q1 = p1*dd; - ell[5] = q1; - m11 = p1*q1; - Z11 += m11; - ell += 6; - dee += 6; - } - /* compute left-over iterations */ - j += 6; - for (; j > 0; j--) { - p1 = ell[0]; - dd = dee[0]; - q1 = p1*dd; - ell[0] = q1; - m11 = p1*q1; - Z11 += m11; - ell++; - dee++; - } - /* solve for diagonal 1 x 1 block at A(i,i) */ - Z11 = ell[0] - Z11; - dee = d + i; - /* factorize 1 x 1 block Z,dee */ - /* factorize row 1 */ - dee[0] = dRecip(Z11); - /* done factorizing 1 x 1 block */ - break; - - default: *((char*)0)=0; /* this should never happen! */ - } -} diff --git a/Extras/ode/ode/src/fastlsolve.c b/Extras/ode/ode/src/fastlsolve.c deleted file mode 100644 index 0ae99d62d..000000000 --- a/Extras/ode/ode/src/fastlsolve.c +++ /dev/null @@ -1,298 +0,0 @@ -/* generated code, do not edit. */ - -#include "ode/matrix.h" - -/* solve L*X=B, with B containing 1 right hand sides. - * L is an n*n lower triangular matrix with ones on the diagonal. - * L is stored by rows and its leading dimension is lskip. - * B is an n*1 matrix that contains the right hand sides. - * B is stored by columns and its leading dimension is also lskip. - * B is overwritten with X. - * this processes blocks of 4*4. - * if this is in the factorizer source file, n must be a multiple of 4. - */ - -void dSolveL1 (const dReal *L, dReal *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - dReal Z11,Z21,Z31,Z41,p1,q1,p2,p3,p4,*ex; - const dReal *ell; - int lskip2,lskip3,i,j; - /* compute lskip values */ - lskip2 = 2*lskip1; - lskip3 = 3*lskip1; - /* compute all 4 x 1 blocks of X */ - for (i=0; i <= n-4; i+=4) { - /* compute all 4 x 1 block of X, from rows i..i+4-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z21=0; - Z31=0; - Z41=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-12; j >= 0; j -= 12) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[lskip1]; - p3=ell[lskip2]; - p4=ell[lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[1]; - q1=ex[1]; - p2=ell[1+lskip1]; - p3=ell[1+lskip2]; - p4=ell[1+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[2]; - q1=ex[2]; - p2=ell[2+lskip1]; - p3=ell[2+lskip2]; - p4=ell[2+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[3]; - q1=ex[3]; - p2=ell[3+lskip1]; - p3=ell[3+lskip2]; - p4=ell[3+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[4]; - q1=ex[4]; - p2=ell[4+lskip1]; - p3=ell[4+lskip2]; - p4=ell[4+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[5]; - q1=ex[5]; - p2=ell[5+lskip1]; - p3=ell[5+lskip2]; - p4=ell[5+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[6]; - q1=ex[6]; - p2=ell[6+lskip1]; - p3=ell[6+lskip2]; - p4=ell[6+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[7]; - q1=ex[7]; - p2=ell[7+lskip1]; - p3=ell[7+lskip2]; - p4=ell[7+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[8]; - q1=ex[8]; - p2=ell[8+lskip1]; - p3=ell[8+lskip2]; - p4=ell[8+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[9]; - q1=ex[9]; - p2=ell[9+lskip1]; - p3=ell[9+lskip2]; - p4=ell[9+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[10]; - q1=ex[10]; - p2=ell[10+lskip1]; - p3=ell[10+lskip2]; - p4=ell[10+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[11]; - q1=ex[11]; - p2=ell[11+lskip1]; - p3=ell[11+lskip2]; - p4=ell[11+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* advance pointers */ - ell += 12; - ex += 12; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 12; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[lskip1]; - p3=ell[lskip2]; - p4=ell[lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* advance pointers */ - ell += 1; - ex += 1; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - p1 = ell[lskip1]; - Z21 = ex[1] - Z21 - p1*Z11; - ex[1] = Z21; - p1 = ell[lskip2]; - p2 = ell[1+lskip2]; - Z31 = ex[2] - Z31 - p1*Z11 - p2*Z21; - ex[2] = Z31; - p1 = ell[lskip3]; - p2 = ell[1+lskip3]; - p3 = ell[2+lskip3]; - Z41 = ex[3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; - ex[3] = Z41; - /* end of outer loop */ - } - /* compute rows at end that are not a multiple of block size */ - for (; i < n; i++) { - /* compute all 1 x 1 block of X, from rows i..i+1-1 */ - /* set the Z matrix to 0 */ - Z11=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-12; j >= 0; j -= 12) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[1]; - q1=ex[1]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[2]; - q1=ex[2]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[3]; - q1=ex[3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[4]; - q1=ex[4]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[5]; - q1=ex[5]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[6]; - q1=ex[6]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[7]; - q1=ex[7]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[8]; - q1=ex[8]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[9]; - q1=ex[9]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[10]; - q1=ex[10]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[11]; - q1=ex[11]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* advance pointers */ - ell += 12; - ex += 12; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 12; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* advance pointers */ - ell += 1; - ex += 1; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - } -} diff --git a/Extras/ode/ode/src/fastltsolve.c b/Extras/ode/ode/src/fastltsolve.c deleted file mode 100644 index eb950f607..000000000 --- a/Extras/ode/ode/src/fastltsolve.c +++ /dev/null @@ -1,199 +0,0 @@ -/* generated code, do not edit. */ - -#include "ode/matrix.h" - -/* solve L^T * x=b, with b containing 1 right hand side. - * L is an n*n lower triangular matrix with ones on the diagonal. - * L is stored by rows and its leading dimension is lskip. - * b is an n*1 matrix that contains the right hand side. - * b is overwritten with x. - * this processes blocks of 4. - */ - -void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - dReal Z11,m11,Z21,m21,Z31,m31,Z41,m41,p1,q1,p2,p3,p4,*ex; - const dReal *ell; - int lskip2,lskip3,i,j; - /* special handling for L and B because we're solving L1 *transpose* */ - L = L + (n-1)*(lskip1+1); - B = B + n-1; - lskip1 = -lskip1; - /* compute lskip values */ - lskip2 = 2*lskip1; - lskip3 = 3*lskip1; - /* compute all 4 x 1 blocks of X */ - for (i=0; i <= n-4; i+=4) { - /* compute all 4 x 1 block of X, from rows i..i+4-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z21=0; - Z31=0; - Z41=0; - ell = L - i; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-4; j >= 0; j -= 4) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* load p and q values */ - p1=ell[0]; - q1=ex[-1]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* load p and q values */ - p1=ell[0]; - q1=ex[-2]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* load p and q values */ - p1=ell[0]; - q1=ex[-3]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - ex -= 4; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 4; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - ex -= 1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - p1 = ell[-1]; - Z21 = ex[-1] - Z21 - p1*Z11; - ex[-1] = Z21; - p1 = ell[-2]; - p2 = ell[-2+lskip1]; - Z31 = ex[-2] - Z31 - p1*Z11 - p2*Z21; - ex[-2] = Z31; - p1 = ell[-3]; - p2 = ell[-3+lskip1]; - p3 = ell[-3+lskip2]; - Z41 = ex[-3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; - ex[-3] = Z41; - /* end of outer loop */ - } - /* compute rows at end that are not a multiple of block size */ - for (; i < n; i++) { - /* compute all 1 x 1 block of X, from rows i..i+1-1 */ - /* set the Z matrix to 0 */ - Z11=0; - ell = L - i; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-4; j >= 0; j -= 4) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - Z11 += m11; - /* load p and q values */ - p1=ell[0]; - q1=ex[-1]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - Z11 += m11; - /* load p and q values */ - p1=ell[0]; - q1=ex[-2]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - Z11 += m11; - /* load p and q values */ - p1=ell[0]; - q1=ex[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - ex -= 4; - Z11 += m11; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 4; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - ex -= 1; - Z11 += m11; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - } -} diff --git a/Extras/ode/ode/src/joint.cpp b/Extras/ode/ode/src/joint.cpp deleted file mode 100644 index 906208101..000000000 --- a/Extras/ode/ode/src/joint.cpp +++ /dev/null @@ -1,2791 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -design note: the general principle for giving a joint the option of connecting -to the static environment (i.e. the absolute frame) is to check the second -body (joint->node[1].body), and if it is zero then behave as if its body -transform is the identity. - -*/ - -#include -#include -#include -#include "joint.h" - -//**************************************************************************** -// externs - -extern "C" void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); -extern "C" void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); - -//**************************************************************************** -// utility - -// set three "ball-and-socket" rows in the constraint equation, and the -// corresponding right hand side. - -static inline void setBall (dxJoint *joint, dxJoint::Info2 *info, - dVector3 anchor1, dVector3 anchor2) -{ - // anchor points in global coordinates with respect to body PORs. - dVector3 a1,a2; - - int s = info->rowskip; - - // set jacobian - info->J1l[0] = 1; - info->J1l[s+1] = 1; - info->J1l[2*s+2] = 1; - dMULTIPLY0_331 (a1,joint->node[0].body->R,anchor1); - dCROSSMAT (info->J1a,a1,s,-,+); - if (joint->node[1].body) { - info->J2l[0] = -1; - info->J2l[s+1] = -1; - info->J2l[2*s+2] = -1; - dMULTIPLY0_331 (a2,joint->node[1].body->R,anchor2); - dCROSSMAT (info->J2a,a2,s,+,-); - } - - // set right hand side - dReal k = info->fps * info->erp; - if (joint->node[1].body) { - for (int j=0; j<3; j++) { - info->c[j] = k * (a2[j] + joint->node[1].body->pos[j] - - a1[j] - joint->node[0].body->pos[j]); - } - } - else { - for (int j=0; j<3; j++) { - info->c[j] = k * (anchor2[j] - a1[j] - - joint->node[0].body->pos[j]); - } - } -} - - -// this is like setBall(), except that `axis' is a unit length vector -// (in global coordinates) that should be used for the first jacobian -// position row (the other two row vectors will be derived from this). -// `erp1' is the erp value to use along the axis. - -static inline void setBall2 (dxJoint *joint, dxJoint::Info2 *info, - dVector3 anchor1, dVector3 anchor2, - dVector3 axis, dReal erp1) -{ - // anchor points in global coordinates with respect to body PORs. - dVector3 a1,a2; - - int i,s = info->rowskip; - - // get vectors normal to the axis. in setBall() axis,q1,q2 is [1 0 0], - // [0 1 0] and [0 0 1], which makes everything much easier. - dVector3 q1,q2; - dPlaneSpace (axis,q1,q2); - - // set jacobian - for (i=0; i<3; i++) info->J1l[i] = axis[i]; - for (i=0; i<3; i++) info->J1l[s+i] = q1[i]; - for (i=0; i<3; i++) info->J1l[2*s+i] = q2[i]; - dMULTIPLY0_331 (a1,joint->node[0].body->R,anchor1); - dCROSS (info->J1a,=,a1,axis); - dCROSS (info->J1a+s,=,a1,q1); - dCROSS (info->J1a+2*s,=,a1,q2); - if (joint->node[1].body) { - for (i=0; i<3; i++) info->J2l[i] = -axis[i]; - for (i=0; i<3; i++) info->J2l[s+i] = -q1[i]; - for (i=0; i<3; i++) info->J2l[2*s+i] = -q2[i]; - dMULTIPLY0_331 (a2,joint->node[1].body->R,anchor2); - dCROSS (info->J2a,= -,a2,axis); - dCROSS (info->J2a+s,= -,a2,q1); - dCROSS (info->J2a+2*s,= -,a2,q2); - } - - // set right hand side - measure error along (axis,q1,q2) - dReal k1 = info->fps * erp1; - dReal k = info->fps * info->erp; - - for (i=0; i<3; i++) a1[i] += joint->node[0].body->pos[i]; - if (joint->node[1].body) { - for (i=0; i<3; i++) a2[i] += joint->node[1].body->pos[i]; - info->c[0] = k1 * (dDOT(axis,a2) - dDOT(axis,a1)); - info->c[1] = k * (dDOT(q1,a2) - dDOT(q1,a1)); - info->c[2] = k * (dDOT(q2,a2) - dDOT(q2,a1)); - } - else { - info->c[0] = k1 * (dDOT(axis,anchor2) - dDOT(axis,a1)); - info->c[1] = k * (dDOT(q1,anchor2) - dDOT(q1,a1)); - info->c[2] = k * (dDOT(q2,anchor2) - dDOT(q2,a1)); - } -} - - -// set three orientation rows in the constraint equation, and the -// corresponding right hand side. - -static void setFixedOrientation(dxJoint *joint, dxJoint::Info2 *info, dQuaternion qrel, int start_row) -{ - int s = info->rowskip; - int start_index = start_row * s; - - // 3 rows to make body rotations equal - info->J1a[start_index] = 1; - info->J1a[start_index + s + 1] = 1; - info->J1a[start_index + s*2+2] = 1; - if (joint->node[1].body) { - info->J2a[start_index] = -1; - info->J2a[start_index + s+1] = -1; - info->J2a[start_index + s*2+2] = -1; - } - - // compute the right hand side. the first three elements will result in - // relative angular velocity of the two bodies - this is set to bring them - // back into alignment. the correcting angular velocity is - // |angular_velocity| = angle/time = erp*theta / stepsize - // = (erp*fps) * theta - // angular_velocity = |angular_velocity| * u - // = (erp*fps) * theta * u - // where rotation along unit length axis u by theta brings body 2's frame - // to qrel with respect to body 1's frame. using a small angle approximation - // for sin(), this gives - // angular_velocity = (erp*fps) * 2 * v - // where the quaternion of the relative rotation between the two bodies is - // q = [cos(theta/2) sin(theta/2)*u] = [s v] - - // get qerr = relative rotation (rotation error) between two bodies - dQuaternion qerr,e; - if (joint->node[1].body) { - dQuaternion qq; - dQMultiply1 (qq,joint->node[0].body->q,joint->node[1].body->q); - dQMultiply2 (qerr,qq,qrel); - } - else { - dQMultiply3 (qerr,joint->node[0].body->q,qrel); - } - if (qerr[0] < 0) { - qerr[1] = -qerr[1]; // adjust sign of qerr to make theta small - qerr[2] = -qerr[2]; - qerr[3] = -qerr[3]; - } - dMULTIPLY0_331 (e,joint->node[0].body->R,qerr+1); // @@@ bad SIMD padding! - dReal k = info->fps * info->erp; - info->c[start_row] = 2*k * e[0]; - info->c[start_row+1] = 2*k * e[1]; - info->c[start_row+2] = 2*k * e[2]; -} - - -// compute anchor points relative to bodies - -static void setAnchors (dxJoint *j, dReal x, dReal y, dReal z, - dVector3 anchor1, dVector3 anchor2) -{ - if (j->node[0].body) { - dReal q[4]; - q[0] = x - j->node[0].body->pos[0]; - q[1] = y - j->node[0].body->pos[1]; - q[2] = z - j->node[0].body->pos[2]; - q[3] = 0; - dMULTIPLY1_331 (anchor1,j->node[0].body->R,q); - if (j->node[1].body) { - q[0] = x - j->node[1].body->pos[0]; - q[1] = y - j->node[1].body->pos[1]; - q[2] = z - j->node[1].body->pos[2]; - q[3] = 0; - dMULTIPLY1_331 (anchor2,j->node[1].body->R,q); - } - else { - anchor2[0] = x; - anchor2[1] = y; - anchor2[2] = z; - } - } - anchor1[3] = 0; - anchor2[3] = 0; -} - - -// compute axes relative to bodies. either axis1 or axis2 can be 0. - -static void setAxes (dxJoint *j, dReal x, dReal y, dReal z, - dVector3 axis1, dVector3 axis2) -{ - if (j->node[0].body) { - dReal q[4]; - q[0] = x; - q[1] = y; - q[2] = z; - q[3] = 0; - dNormalize3 (q); - if (axis1) { - dMULTIPLY1_331 (axis1,j->node[0].body->R,q); - axis1[3] = 0; - } - if (axis2) { - if (j->node[1].body) { - dMULTIPLY1_331 (axis2,j->node[1].body->R,q); - } - else { - axis2[0] = x; - axis2[1] = y; - axis2[2] = z; - } - axis2[3] = 0; - } - } -} - - -static void getAnchor (dxJoint *j, dVector3 result, dVector3 anchor1) -{ - if (j->node[0].body) { - dMULTIPLY0_331 (result,j->node[0].body->R,anchor1); - result[0] += j->node[0].body->pos[0]; - result[1] += j->node[0].body->pos[1]; - result[2] += j->node[0].body->pos[2]; - } -} - - -static void getAnchor2 (dxJoint *j, dVector3 result, dVector3 anchor2) -{ - if (j->node[1].body) { - dMULTIPLY0_331 (result,j->node[1].body->R,anchor2); - result[0] += j->node[1].body->pos[0]; - result[1] += j->node[1].body->pos[1]; - result[2] += j->node[1].body->pos[2]; - } - else { - result[0] = anchor2[0]; - result[1] = anchor2[1]; - result[2] = anchor2[2]; - } -} - - -static void getAxis (dxJoint *j, dVector3 result, dVector3 axis1) -{ - if (j->node[0].body) { - dMULTIPLY0_331 (result,j->node[0].body->R,axis1); - } -} - - -static void getAxis2 (dxJoint *j, dVector3 result, dVector3 axis2) -{ - if (j->node[1].body) { - dMULTIPLY0_331 (result,j->node[1].body->R,axis2); - } - else { - result[0] = axis2[0]; - result[1] = axis2[1]; - result[2] = axis2[2]; - } -} - - -static dReal getHingeAngleFromRelativeQuat (dQuaternion qrel, dVector3 axis) -{ - // the angle between the two bodies is extracted from the quaternion that - // represents the relative rotation between them. recall that a quaternion - // q is: - // [s,v] = [ cos(theta/2) , sin(theta/2) * u ] - // where s is a scalar and v is a 3-vector. u is a unit length axis and - // theta is a rotation along that axis. we can get theta/2 by: - // theta/2 = atan2 ( sin(theta/2) , cos(theta/2) ) - // but we can't get sin(theta/2) directly, only its absolute value, i.e.: - // |v| = |sin(theta/2)| * |u| - // = |sin(theta/2)| - // using this value will have a strange effect. recall that there are two - // quaternion representations of a given rotation, q and -q. typically as - // a body rotates along the axis it will go through a complete cycle using - // one representation and then the next cycle will use the other - // representation. this corresponds to u pointing in the direction of the - // hinge axis and then in the opposite direction. the result is that theta - // will appear to go "backwards" every other cycle. here is a fix: if u - // points "away" from the direction of the hinge (motor) axis (i.e. more - // than 90 degrees) then use -q instead of q. this represents the same - // rotation, but results in the cos(theta/2) value being sign inverted. - - // extract the angle from the quaternion. cost2 = cos(theta/2), - // sint2 = |sin(theta/2)| - dReal cost2 = qrel[0]; - dReal sint2 = dSqrt (qrel[1]*qrel[1]+qrel[2]*qrel[2]+qrel[3]*qrel[3]); - dReal theta = (dDOT(qrel+1,axis) >= 0) ? // @@@ padding assumptions - (2 * dAtan2(sint2,cost2)) : // if u points in direction of axis - (2 * dAtan2(sint2,-cost2)); // if u points in opposite direction - - // the angle we get will be between 0..2*pi, but we want to return angles - // between -pi..pi - if (theta > M_PI) theta -= 2*M_PI; - - // the angle we've just extracted has the wrong sign - theta = -theta; - - return theta; -} - - -// given two bodies (body1,body2), the hinge axis that they are connected by -// w.r.t. body1 (axis), and the initial relative orientation between them -// (q_initial), return the relative rotation angle. the initial relative -// orientation corresponds to an angle of zero. if body2 is 0 then measure the -// angle between body1 and the static frame. -// -// this will not return the correct angle if the bodies rotate along any axis -// other than the given hinge axis. - -static dReal getHingeAngle (dxBody *body1, dxBody *body2, dVector3 axis, - dQuaternion q_initial) -{ - // get qrel = relative rotation between the two bodies - dQuaternion qrel; - if (body2) { - dQuaternion qq; - dQMultiply1 (qq,body1->q,body2->q); - dQMultiply2 (qrel,qq,q_initial); - } - else { - // pretend body2->q is the identity - dQMultiply3 (qrel,body1->q,q_initial); - } - - return getHingeAngleFromRelativeQuat (qrel,axis); -} - -//**************************************************************************** -// dxJointLimitMotor - -void dxJointLimitMotor::init (dxWorld *world) -{ - vel = 0; - fmax = 0; - lostop = -dInfinity; - histop = dInfinity; - fudge_factor = 1; - normal_cfm = world->global_cfm; - stop_erp = world->global_erp; - stop_cfm = world->global_cfm; - bounce = 0; - limit = 0; - limit_err = 0; -} - - -void dxJointLimitMotor::set (int num, dReal value) -{ - switch (num) { - case dParamLoStop: - if (value <= histop) lostop = value; - break; - case dParamHiStop: - if (value >= lostop) histop = value; - break; - case dParamVel: - vel = value; - break; - case dParamFMax: - if (value >= 0) fmax = value; - break; - case dParamFudgeFactor: - if (value >= 0 && value <= 1) fudge_factor = value; - break; - case dParamBounce: - bounce = value; - break; - case dParamCFM: - normal_cfm = value; - break; - case dParamStopERP: - stop_erp = value; - break; - case dParamStopCFM: - stop_cfm = value; - break; - } -} - - -dReal dxJointLimitMotor::get (int num) -{ - switch (num) { - case dParamLoStop: return lostop; - case dParamHiStop: return histop; - case dParamVel: return vel; - case dParamFMax: return fmax; - case dParamFudgeFactor: return fudge_factor; - case dParamBounce: return bounce; - case dParamCFM: return normal_cfm; - case dParamStopERP: return stop_erp; - case dParamStopCFM: return stop_cfm; - default: return 0; - } -} - - -int dxJointLimitMotor::testRotationalLimit (dReal angle) -{ - if (angle <= lostop) { - limit = 1; - limit_err = angle - lostop; - return 1; - } - else if (angle >= histop) { - limit = 2; - limit_err = angle - histop; - return 1; - } - else { - limit = 0; - return 0; - } -} - - -int dxJointLimitMotor::addLimot (dxJoint *joint, - dxJoint::Info2 *info, int row, - dVector3 ax1, int rotational) -{ - int srow = row * info->rowskip; - - // if the joint is powered, or has joint limits, add in the extra row - int powered = fmax > 0; - if (powered || limit) { - dReal *J1 = rotational ? info->J1a : info->J1l; - dReal *J2 = rotational ? info->J2a : info->J2l; - - J1[srow+0] = ax1[0]; - J1[srow+1] = ax1[1]; - J1[srow+2] = ax1[2]; - if (joint->node[1].body) { - J2[srow+0] = -ax1[0]; - J2[srow+1] = -ax1[1]; - J2[srow+2] = -ax1[2]; - } - - // linear limot torque decoupling step: - // - // if this is a linear limot (e.g. from a slider), we have to be careful - // that the linear constraint forces (+/- ax1) applied to the two bodies - // do not create a torque couple. in other words, the points that the - // constraint force is applied at must lie along the same ax1 axis. - // a torque couple will result in powered or limited slider-jointed free - // bodies from gaining angular momentum. - // the solution used here is to apply the constraint forces at the point - // halfway between the body centers. there is no penalty (other than an - // extra tiny bit of computation) in doing this adjustment. note that we - // only need to do this if the constraint connects two bodies. - - dVector3 ltd; // Linear Torque Decoupling vector (a torque) - if (!rotational && joint->node[1].body) { - dVector3 c; - c[0]=REAL(0.5)*(joint->node[1].body->pos[0]-joint->node[0].body->pos[0]); - c[1]=REAL(0.5)*(joint->node[1].body->pos[1]-joint->node[0].body->pos[1]); - c[2]=REAL(0.5)*(joint->node[1].body->pos[2]-joint->node[0].body->pos[2]); - dCROSS (ltd,=,c,ax1); - info->J1a[srow+0] = ltd[0]; - info->J1a[srow+1] = ltd[1]; - info->J1a[srow+2] = ltd[2]; - info->J2a[srow+0] = ltd[0]; - info->J2a[srow+1] = ltd[1]; - info->J2a[srow+2] = ltd[2]; - } - - // if we're limited low and high simultaneously, the joint motor is - // ineffective - if (limit && (lostop == histop)) powered = 0; - - if (powered) { - info->cfm[row] = normal_cfm; - if (! limit) { - info->c[row] = vel; - info->lo[row] = -fmax; - info->hi[row] = fmax; - } - else { - // the joint is at a limit, AND is being powered. if the joint is - // being powered into the limit then we apply the maximum motor force - // in that direction, because the motor is working against the - // immovable limit. if the joint is being powered away from the limit - // then we have problems because actually we need *two* lcp - // constraints to handle this case. so we fake it and apply some - // fraction of the maximum force. the fraction to use can be set as - // a fudge factor. - - dReal fm = fmax; - if (vel > 0) fm = -fm; - - // if we're powering away from the limit, apply the fudge factor - if ((limit==1 && vel > 0) || (limit==2 && vel < 0)) fm *= fudge_factor; - - if (rotational) { - dBodyAddTorque (joint->node[0].body,-fm*ax1[0],-fm*ax1[1], - -fm*ax1[2]); - if (joint->node[1].body) - dBodyAddTorque (joint->node[1].body,fm*ax1[0],fm*ax1[1],fm*ax1[2]); - } - else { - dBodyAddForce (joint->node[0].body,-fm*ax1[0],-fm*ax1[1],-fm*ax1[2]); - if (joint->node[1].body) { - dBodyAddForce (joint->node[1].body,fm*ax1[0],fm*ax1[1],fm*ax1[2]); - - // linear limot torque decoupling step: refer to above discussion - dBodyAddTorque (joint->node[0].body,-fm*ltd[0],-fm*ltd[1], - -fm*ltd[2]); - dBodyAddTorque (joint->node[1].body,-fm*ltd[0],-fm*ltd[1], - -fm*ltd[2]); - } - } - } - } - - if (limit) { - dReal k = info->fps * stop_erp; - info->c[row] = -k * limit_err; - info->cfm[row] = stop_cfm; - - if (lostop == histop) { - // limited low and high simultaneously - info->lo[row] = -dInfinity; - info->hi[row] = dInfinity; - } - else { - if (limit == 1) { - // low limit - info->lo[row] = 0; - info->hi[row] = dInfinity; - } - else { - // high limit - info->lo[row] = -dInfinity; - info->hi[row] = 0; - } - - // deal with bounce - if (bounce > 0) { - // calculate joint velocity - dReal vel; - if (rotational) { - vel = dDOT(joint->node[0].body->avel,ax1); - if (joint->node[1].body) - vel -= dDOT(joint->node[1].body->avel,ax1); - } - else { - vel = dDOT(joint->node[0].body->lvel,ax1); - if (joint->node[1].body) - vel -= dDOT(joint->node[1].body->lvel,ax1); - } - - // only apply bounce if the velocity is incoming, and if the - // resulting c[] exceeds what we already have. - if (limit == 1) { - // low limit - if (vel < 0) { - dReal newc = -bounce * vel; - if (newc > info->c[row]) info->c[row] = newc; - } - } - else { - // high limit - all those computations are reversed - if (vel > 0) { - dReal newc = -bounce * vel; - if (newc < info->c[row]) info->c[row] = newc; - } - } - } - } - } - return 1; - } - else return 0; -} - -//**************************************************************************** -// ball and socket - -static void ballInit (dxJointBall *j) -{ - dSetZero (j->anchor1,4); - dSetZero (j->anchor2,4); -} - - -static void ballGetInfo1 (dxJointBall *j, dxJoint::Info1 *info) -{ - info->m = 3; - info->nub = 3; -} - - -static void ballGetInfo2 (dxJointBall *joint, dxJoint::Info2 *info) -{ - setBall (joint,info,joint->anchor1,joint->anchor2); -} - - -extern "C" void dJointSetBallAnchor (dxJointBall *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); - setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); -} - - -extern "C" void dJointSetBallAnchor2 (dxJointBall *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); - joint->anchor2[0] = x; - joint->anchor2[1] = y; - joint->anchor2[2] = z; - joint->anchor2[3] = 0; - -} - -extern "C" void dJointGetBallAnchor (dxJointBall *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); - if (joint->flags & dJOINT_REVERSE) - getAnchor2 (joint,result,joint->anchor2); - else - getAnchor (joint,result,joint->anchor1); -} - - -extern "C" void dJointGetBallAnchor2 (dxJointBall *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); - if (joint->flags & dJOINT_REVERSE) - getAnchor (joint,result,joint->anchor1); - else - getAnchor2 (joint,result,joint->anchor2); -} - - -dxJoint::Vtable __dball_vtable = { - sizeof(dxJointBall), - (dxJoint::init_fn*) ballInit, - (dxJoint::getInfo1_fn*) ballGetInfo1, - (dxJoint::getInfo2_fn*) ballGetInfo2, - dJointTypeBall}; - -//**************************************************************************** -// hinge - -static void hingeInit (dxJointHinge *j) -{ - dSetZero (j->anchor1,4); - dSetZero (j->anchor2,4); - dSetZero (j->axis1,4); - j->axis1[0] = 1; - dSetZero (j->axis2,4); - j->axis2[0] = 1; - dSetZero (j->qrel,4); - j->limot.init (j->world); -} - - -static void hingeGetInfo1 (dxJointHinge *j, dxJoint::Info1 *info) -{ - info->nub = 5; - - // see if joint is powered - if (j->limot.fmax > 0) - info->m = 6; // powered hinge needs an extra constraint row - else info->m = 5; - - // see if we're at a joint limit. - if ((j->limot.lostop >= -M_PI || j->limot.histop <= M_PI) && - j->limot.lostop <= j->limot.histop) { - dReal angle = getHingeAngle (j->node[0].body,j->node[1].body,j->axis1, - j->qrel); - if (j->limot.testRotationalLimit (angle)) info->m = 6; - } -} - - -static void hingeGetInfo2 (dxJointHinge *joint, dxJoint::Info2 *info) -{ - // set the three ball-and-socket rows - setBall (joint,info,joint->anchor1,joint->anchor2); - - // set the two hinge rows. the hinge axis should be the only unconstrained - // rotational axis, the angular velocity of the two bodies perpendicular to - // the hinge axis should be equal. thus the constraint equations are - // p*w1 - p*w2 = 0 - // q*w1 - q*w2 = 0 - // where p and q are unit vectors normal to the hinge axis, and w1 and w2 - // are the angular velocity vectors of the two bodies. - - dVector3 ax1; // length 1 joint axis in global coordinates, from 1st body - dVector3 p,q; // plane space vectors for ax1 - dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); - dPlaneSpace (ax1,p,q); - - int s3=3*info->rowskip; - int s4=4*info->rowskip; - - info->J1a[s3+0] = p[0]; - info->J1a[s3+1] = p[1]; - info->J1a[s3+2] = p[2]; - info->J1a[s4+0] = q[0]; - info->J1a[s4+1] = q[1]; - info->J1a[s4+2] = q[2]; - - if (joint->node[1].body) { - info->J2a[s3+0] = -p[0]; - info->J2a[s3+1] = -p[1]; - info->J2a[s3+2] = -p[2]; - info->J2a[s4+0] = -q[0]; - info->J2a[s4+1] = -q[1]; - info->J2a[s4+2] = -q[2]; - } - - // compute the right hand side of the constraint equation. set relative - // body velocities along p and q to bring the hinge back into alignment. - // if ax1,ax2 are the unit length hinge axes as computed from body1 and - // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). - // if `theta' is the angle between ax1 and ax2, we need an angular velocity - // along u to cover angle erp*theta in one step : - // |angular_velocity| = angle/time = erp*theta / stepsize - // = (erp*fps) * theta - // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| - // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) - // ...as ax1 and ax2 are unit length. if theta is smallish, - // theta ~= sin(theta), so - // angular_velocity = (erp*fps) * (ax1 x ax2) - // ax1 x ax2 is in the plane space of ax1, so we project the angular - // velocity to p and q to find the right hand side. - - dVector3 ax2,b; - if (joint->node[1].body) { - dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); - } - else { - ax2[0] = joint->axis2[0]; - ax2[1] = joint->axis2[1]; - ax2[2] = joint->axis2[2]; - } - dCROSS (b,=,ax1,ax2); - dReal k = info->fps * info->erp; - info->c[3] = k * dDOT(b,p); - info->c[4] = k * dDOT(b,q); - - // if the hinge is powered, or has joint limits, add in the stuff - joint->limot.addLimot (joint,info,5,ax1,1); -} - - -// compute initial relative rotation body1 -> body2, or env -> body1 - -static void hingeComputeInitialRelativeRotation (dxJointHinge *joint) -{ - if (joint->node[0].body) { - if (joint->node[1].body) { - dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); - } - else { - // set joint->qrel to the transpose of the first body q - joint->qrel[0] = joint->node[0].body->q[0]; - for (int i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i]; - } - } -} - - -extern "C" void dJointSetHingeAnchor (dxJointHinge *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); - hingeComputeInitialRelativeRotation (joint); -} - - -extern "C" void dJointSetHingeAnchorDelta (dxJointHinge *joint, - dReal x, dReal y, dReal z, - dReal dx, dReal dy, dReal dz) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - - if (joint->node[0].body) { - dReal q[4]; - q[0] = x - joint->node[0].body->pos[0]; - q[1] = y - joint->node[0].body->pos[1]; - q[2] = z - joint->node[0].body->pos[2]; - q[3] = 0; - dMULTIPLY1_331 (joint->anchor1,joint->node[0].body->R,q); - - if (joint->node[1].body) { - q[0] = x - joint->node[1].body->pos[0]; - q[1] = y - joint->node[1].body->pos[1]; - q[2] = z - joint->node[1].body->pos[2]; - q[3] = 0; - dMULTIPLY1_331 (joint->anchor2,joint->node[1].body->R,q); - } - else { - // Move the relative displacement between the passive body and the - // anchor in the same direction as the passive body has just moved - joint->anchor2[0] = x + dx; - joint->anchor2[1] = y + dy; - joint->anchor2[2] = z + dz; - } - } - joint->anchor1[3] = 0; - joint->anchor2[3] = 0; - - hingeComputeInitialRelativeRotation (joint); -} - - - -extern "C" void dJointSetHingeAxis (dxJointHinge *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - setAxes (joint,x,y,z,joint->axis1,joint->axis2); - hingeComputeInitialRelativeRotation (joint); -} - - -extern "C" void dJointGetHingeAnchor (dxJointHinge *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - if (joint->flags & dJOINT_REVERSE) - getAnchor2 (joint,result,joint->anchor2); - else - getAnchor (joint,result,joint->anchor1); -} - - -extern "C" void dJointGetHingeAnchor2 (dxJointHinge *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - if (joint->flags & dJOINT_REVERSE) - getAnchor (joint,result,joint->anchor1); - else - getAnchor2 (joint,result,joint->anchor2); -} - - -extern "C" void dJointGetHingeAxis (dxJointHinge *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - getAxis (joint,result,joint->axis1); -} - - -extern "C" void dJointSetHingeParam (dxJointHinge *joint, - int parameter, dReal value) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - joint->limot.set (parameter,value); -} - - -extern "C" dReal dJointGetHingeParam (dxJointHinge *joint, int parameter) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - return joint->limot.get (parameter); -} - - -extern "C" dReal dJointGetHingeAngle (dxJointHinge *joint) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); - if (joint->node[0].body) { - dReal ang = getHingeAngle (joint->node[0].body,joint->node[1].body,joint->axis1, - joint->qrel); - if (joint->flags & dJOINT_REVERSE) - return -ang; - else - return ang; - } - else return 0; -} - - -extern "C" dReal dJointGetHingeAngleRate (dxJointHinge *joint) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a Hinge"); - if (joint->node[0].body) { - dVector3 axis; - dMULTIPLY0_331 (axis,joint->node[0].body->R,joint->axis1); - dReal rate = dDOT(axis,joint->node[0].body->avel); - if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel); - if (joint->flags & dJOINT_REVERSE) rate = - rate; - return rate; - } - else return 0; -} - - -extern "C" void dJointAddHingeTorque (dxJointHinge *joint, dReal torque) -{ - dVector3 axis; - dAASSERT(joint); - dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a Hinge"); - - if (joint->flags & dJOINT_REVERSE) - torque = -torque; - - getAxis (joint,axis,joint->axis1); - axis[0] *= torque; - axis[1] *= torque; - axis[2] *= torque; - - if (joint->node[0].body != 0) - dBodyAddTorque (joint->node[0].body, axis[0], axis[1], axis[2]); - if (joint->node[1].body != 0) - dBodyAddTorque(joint->node[1].body, -axis[0], -axis[1], -axis[2]); -} - - -dxJoint::Vtable __dhinge_vtable = { - sizeof(dxJointHinge), - (dxJoint::init_fn*) hingeInit, - (dxJoint::getInfo1_fn*) hingeGetInfo1, - (dxJoint::getInfo2_fn*) hingeGetInfo2, - dJointTypeHinge}; - -//**************************************************************************** -// slider - -static void sliderInit (dxJointSlider *j) -{ - dSetZero (j->axis1,4); - j->axis1[0] = 1; - dSetZero (j->qrel,4); - dSetZero (j->offset,4); - j->limot.init (j->world); -} - - -extern "C" dReal dJointGetSliderPosition (dxJointSlider *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - - // get axis1 in global coordinates - dVector3 ax1,q; - dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); - - if (joint->node[1].body) { - // get body2 + offset point in global coordinates - dMULTIPLY0_331 (q,joint->node[1].body->R,joint->offset); - for (int i=0; i<3; i++) q[i] = joint->node[0].body->pos[i] - q[i] - - joint->node[1].body->pos[i]; - } - else { - for (int i=0; i<3; i++) q[i] = joint->node[0].body->pos[i] - - joint->offset[i]; - - } - return dDOT(ax1,q); -} - - -extern "C" dReal dJointGetSliderPositionRate (dxJointSlider *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - - // get axis1 in global coordinates - dVector3 ax1; - dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); - - if (joint->node[1].body) { - return dDOT(ax1,joint->node[0].body->lvel) - - dDOT(ax1,joint->node[1].body->lvel); - } - else { - return dDOT(ax1,joint->node[0].body->lvel); - } -} - - -static void sliderGetInfo1 (dxJointSlider *j, dxJoint::Info1 *info) -{ - info->nub = 5; - - // see if joint is powered - if (j->limot.fmax > 0) - info->m = 6; // powered slider needs an extra constraint row - else info->m = 5; - - // see if we're at a joint limit. - j->limot.limit = 0; - if ((j->limot.lostop > -dInfinity || j->limot.histop < dInfinity) && - j->limot.lostop <= j->limot.histop) { - // measure joint position - dReal pos = dJointGetSliderPosition (j); - if (pos <= j->limot.lostop) { - j->limot.limit = 1; - j->limot.limit_err = pos - j->limot.lostop; - info->m = 6; - } - else if (pos >= j->limot.histop) { - j->limot.limit = 2; - j->limot.limit_err = pos - j->limot.histop; - info->m = 6; - } - } -} - - -static void sliderGetInfo2 (dxJointSlider *joint, dxJoint::Info2 *info) -{ - int i,s = info->rowskip; - int s3=3*s,s4=4*s; - - // pull out pos and R for both bodies. also get the `connection' - // vector pos2-pos1. - - dReal *pos1,*pos2,*R1,*R2; - dVector3 c; - pos1 = joint->node[0].body->pos; - R1 = joint->node[0].body->R; - if (joint->node[1].body) { - pos2 = joint->node[1].body->pos; - R2 = joint->node[1].body->R; - for (i=0; i<3; i++) c[i] = pos2[i] - pos1[i]; - } - else { - pos2 = 0; - R2 = 0; - } - - // 3 rows to make body rotations equal - setFixedOrientation(joint, info, joint->qrel, 0); - - // remaining two rows. we want: vel2 = vel1 + w1 x c ... but this would - // result in three equations, so we project along the planespace vectors - // so that sliding along the slider axis is disregarded. for symmetry we - // also substitute (w1+w2)/2 for w1, as w1 is supposed to equal w2. - - dVector3 ax1; // joint axis in global coordinates (unit length) - dVector3 p,q; // plane space of ax1 - dMULTIPLY0_331 (ax1,R1,joint->axis1); - dPlaneSpace (ax1,p,q); - if (joint->node[1].body) { - dVector3 tmp; - dCROSS (tmp, = REAL(0.5) * ,c,p); - for (i=0; i<3; i++) info->J2a[s3+i] = tmp[i]; - for (i=0; i<3; i++) info->J2a[s3+i] = tmp[i]; - dCROSS (tmp, = REAL(0.5) * ,c,q); - for (i=0; i<3; i++) info->J2a[s4+i] = tmp[i]; - for (i=0; i<3; i++) info->J2a[s4+i] = tmp[i]; - for (i=0; i<3; i++) info->J2l[s3+i] = -p[i]; - for (i=0; i<3; i++) info->J2l[s4+i] = -q[i]; - } - for (i=0; i<3; i++) info->J1l[s3+i] = p[i]; - for (i=0; i<3; i++) info->J1l[s4+i] = q[i]; - - // compute last two elements of right hand side. we want to align the offset - // point (in body 2's frame) with the center of body 1. - dReal k = info->fps * info->erp; - if (joint->node[1].body) { - dVector3 ofs; // offset point in global coordinates - dMULTIPLY0_331 (ofs,R2,joint->offset); - for (i=0; i<3; i++) c[i] += ofs[i]; - info->c[3] = k * dDOT(p,c); - info->c[4] = k * dDOT(q,c); - } - else { - dVector3 ofs; // offset point in global coordinates - for (i=0; i<3; i++) ofs[i] = joint->offset[i] - pos1[i]; - info->c[3] = k * dDOT(p,ofs); - info->c[4] = k * dDOT(q,ofs); - } - - // if the slider is powered, or has joint limits, add in the extra row - joint->limot.addLimot (joint,info,5,ax1,0); -} - - -extern "C" void dJointSetSliderAxis (dxJointSlider *joint, - dReal x, dReal y, dReal z) -{ - int i; - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - setAxes (joint,x,y,z,joint->axis1,0); - - // compute initial relative rotation body1 -> body2, or env -> body1 - // also compute center of body1 w.r.t body 2 - if (joint->node[1].body) { - dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); - dVector3 c; - for (i=0; i<3; i++) - c[i] = joint->node[0].body->pos[i] - joint->node[1].body->pos[i]; - dMULTIPLY1_331 (joint->offset,joint->node[1].body->R,c); - } - else { - // set joint->qrel to the transpose of the first body's q - joint->qrel[0] = joint->node[0].body->q[0]; - for (i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i]; - for (i=0; i<3; i++) joint->offset[i] = joint->node[0].body->pos[i]; - } -} - - -extern "C" void dJointSetSliderAxisDelta (dxJointSlider *joint, - dReal x, dReal y, dReal z, - dReal dx, dReal dy, dReal dz) -{ - int i; - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - setAxes (joint,x,y,z,joint->axis1,0); - - // compute initial relative rotation body1 -> body2, or env -> body1 - // also compute center of body1 w.r.t body 2 - if (joint->node[1].body) { - dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); - dVector3 c; - for (i=0; i<3; i++) - c[i] = joint->node[0].body->pos[i] - joint->node[1].body->pos[i]; - dMULTIPLY1_331 (joint->offset,joint->node[1].body->R,c); - } - else { - // set joint->qrel to the transpose of the first body's q - joint->qrel[0] = joint->node[0].body->q[0]; - - for (i=1; i<4; i++) - joint->qrel[i] = -joint->node[0].body->q[i]; - - joint->offset[0] = joint->node[0].body->pos[0] + dx; - joint->offset[1] = joint->node[0].body->pos[1] + dy; - joint->offset[2] = joint->node[0].body->pos[2] + dz; - } -} - - - -extern "C" void dJointGetSliderAxis (dxJointSlider *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - getAxis (joint,result,joint->axis1); -} - - -extern "C" void dJointSetSliderParam (dxJointSlider *joint, - int parameter, dReal value) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - joint->limot.set (parameter,value); -} - - -extern "C" dReal dJointGetSliderParam (dxJointSlider *joint, int parameter) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - return joint->limot.get (parameter); -} - - -extern "C" void dJointAddSliderForce (dxJointSlider *joint, dReal force) -{ - dVector3 axis; - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); - - if (joint->flags & dJOINT_REVERSE) - force -= force; - - getAxis (joint,axis,joint->axis1); - axis[0] *= force; - axis[1] *= force; - axis[2] *= force; - - if (joint->node[0].body != 0) - dBodyAddForce (joint->node[0].body,axis[0],axis[1],axis[2]); - if (joint->node[1].body != 0) - dBodyAddForce(joint->node[1].body, -axis[0], -axis[1], -axis[2]); -} - - -dxJoint::Vtable __dslider_vtable = { - sizeof(dxJointSlider), - (dxJoint::init_fn*) sliderInit, - (dxJoint::getInfo1_fn*) sliderGetInfo1, - (dxJoint::getInfo2_fn*) sliderGetInfo2, - dJointTypeSlider}; - -//**************************************************************************** -// contact - -static void contactInit (dxJointContact *j) -{ - // default frictionless contact. hmmm, this info gets overwritten straight - // away anyway, so why bother? -#if 0 /* so don't bother ;) */ - j->contact.surface.mode = 0; - j->contact.surface.mu = 0; - dSetZero (j->contact.geom.pos,4); - dSetZero (j->contact.geom.normal,4); - j->contact.geom.depth = 0; -#endif -} - - -static void contactGetInfo1 (dxJointContact *j, dxJoint::Info1 *info) -{ - // make sure mu's >= 0, then calculate number of constraint rows and number - // of unbounded rows. - int m = 1, nub=0; - if (j->contact.surface.mu < 0) j->contact.surface.mu = 0; - if (j->contact.surface.mode & dContactMu2) { - if (j->contact.surface.mu > 0) m++; - if (j->contact.surface.mu2 < 0) j->contact.surface.mu2 = 0; - if (j->contact.surface.mu2 > 0) m++; - if (j->contact.surface.mu == dInfinity) nub ++; - if (j->contact.surface.mu2 == dInfinity) nub ++; - } - else { - if (j->contact.surface.mu > 0) m += 2; - if (j->contact.surface.mu == dInfinity) nub += 2; - } - - j->the_m = m; - info->m = m; - info->nub = nub; -} - - -static void contactGetInfo2 (dxJointContact *j, dxJoint::Info2 *info) -{ - int i,s = info->rowskip; - int s2 = 2*s; - - // get normal, with sign adjusted for body1/body2 polarity - dVector3 normal; - if (j->flags & dJOINT_REVERSE) { - normal[0] = - j->contact.geom.normal[0]; - normal[1] = - j->contact.geom.normal[1]; - normal[2] = - j->contact.geom.normal[2]; - } - else { - normal[0] = j->contact.geom.normal[0]; - normal[1] = j->contact.geom.normal[1]; - normal[2] = j->contact.geom.normal[2]; - } - normal[3] = 0; // @@@ hmmm - - // c1,c2 = contact points with respect to body PORs - dVector3 c1,c2; - for (i=0; i<3; i++) c1[i] = j->contact.geom.pos[i] - j->node[0].body->pos[i]; - - // set jacobian for normal - info->J1l[0] = normal[0]; - info->J1l[1] = normal[1]; - info->J1l[2] = normal[2]; - dCROSS (info->J1a,=,c1,normal); - if (j->node[1].body) { - for (i=0; i<3; i++) c2[i] = j->contact.geom.pos[i] - - j->node[1].body->pos[i]; - info->J2l[0] = -normal[0]; - info->J2l[1] = -normal[1]; - info->J2l[2] = -normal[2]; - dCROSS (info->J2a,= -,c2,normal); - } - - // set right hand side and cfm value for normal - dReal erp = info->erp; - if (j->contact.surface.mode & dContactSoftERP) - erp = j->contact.surface.soft_erp; - dReal k = info->fps * erp; - dReal depth = j->contact.geom.depth - j->world->contactp.min_depth; - if (depth < 0) depth = 0; - dReal maxvel = j->world->contactp.max_vel; - if (k*depth > maxvel) info->c[0] = maxvel; else info->c[0] = k*depth; - if (j->contact.surface.mode & dContactSoftCFM) - info->cfm[0] = j->contact.surface.soft_cfm; - - // deal with bounce - if (j->contact.surface.mode & dContactBounce) { - // calculate outgoing velocity (-ve for incoming contact) - dReal outgoing = dDOT(info->J1l,j->node[0].body->lvel) + - dDOT(info->J1a,j->node[0].body->avel); - if (j->node[1].body) { - outgoing += dDOT(info->J2l,j->node[1].body->lvel) + - dDOT(info->J2a,j->node[1].body->avel); - } - // only apply bounce if the outgoing velocity is greater than the - // threshold, and if the resulting c[0] exceeds what we already have. - if (j->contact.surface.bounce_vel >= 0 && - (-outgoing) > j->contact.surface.bounce_vel) { - dReal newc = - j->contact.surface.bounce * outgoing; - if (newc > info->c[0]) info->c[0] = newc; - } - } - - // set LCP limits for normal - info->lo[0] = 0; - info->hi[0] = dInfinity; - - // now do jacobian for tangential forces - dVector3 t1,t2; // two vectors tangential to normal - - // first friction direction - if (j->the_m >= 2) { - if (j->contact.surface.mode & dContactFDir1) { // use fdir1 ? - t1[0] = j->contact.fdir1[0]; - t1[1] = j->contact.fdir1[1]; - t1[2] = j->contact.fdir1[2]; - dCROSS (t2,=,normal,t1); - } - else { - dPlaneSpace (normal,t1,t2); - } - info->J1l[s+0] = t1[0]; - info->J1l[s+1] = t1[1]; - info->J1l[s+2] = t1[2]; - dCROSS (info->J1a+s,=,c1,t1); - if (j->node[1].body) { - info->J2l[s+0] = -t1[0]; - info->J2l[s+1] = -t1[1]; - info->J2l[s+2] = -t1[2]; - dCROSS (info->J2a+s,= -,c2,t1); - } - // set right hand side - if (j->contact.surface.mode & dContactMotion1) { - info->c[1] = j->contact.surface.motion1; - } - // set LCP bounds and friction index. this depends on the approximation - // mode - info->lo[1] = -j->contact.surface.mu; - info->hi[1] = j->contact.surface.mu; - if (j->contact.surface.mode & dContactApprox1_1) info->findex[1] = 0; - - // set slip (constraint force mixing) - if (j->contact.surface.mode & dContactSlip1) - info->cfm[1] = j->contact.surface.slip1; - } - - // second friction direction - if (j->the_m >= 3) { - info->J1l[s2+0] = t2[0]; - info->J1l[s2+1] = t2[1]; - info->J1l[s2+2] = t2[2]; - dCROSS (info->J1a+s2,=,c1,t2); - if (j->node[1].body) { - info->J2l[s2+0] = -t2[0]; - info->J2l[s2+1] = -t2[1]; - info->J2l[s2+2] = -t2[2]; - dCROSS (info->J2a+s2,= -,c2,t2); - } - // set right hand side - if (j->contact.surface.mode & dContactMotion2) { - info->c[2] = j->contact.surface.motion2; - } - // set LCP bounds and friction index. this depends on the approximation - // mode - if (j->contact.surface.mode & dContactMu2) { - info->lo[2] = -j->contact.surface.mu2; - info->hi[2] = j->contact.surface.mu2; - } - else { - info->lo[2] = -j->contact.surface.mu; - info->hi[2] = j->contact.surface.mu; - } - if (j->contact.surface.mode & dContactApprox1_2) info->findex[2] = 0; - - // set slip (constraint force mixing) - if (j->contact.surface.mode & dContactSlip2) - info->cfm[2] = j->contact.surface.slip2; - } -} - - -dxJoint::Vtable __dcontact_vtable = { - sizeof(dxJointContact), - (dxJoint::init_fn*) contactInit, - (dxJoint::getInfo1_fn*) contactGetInfo1, - (dxJoint::getInfo2_fn*) contactGetInfo2, - dJointTypeContact}; - -//**************************************************************************** -// hinge 2. note that this joint must be attached to two bodies for it to work - -static dReal measureHinge2Angle (dxJointHinge2 *joint) -{ - dVector3 a1,a2; - dMULTIPLY0_331 (a1,joint->node[1].body->R,joint->axis2); - dMULTIPLY1_331 (a2,joint->node[0].body->R,a1); - dReal x = dDOT(joint->v1,a2); - dReal y = dDOT(joint->v2,a2); - return -dAtan2 (y,x); -} - - -static void hinge2Init (dxJointHinge2 *j) -{ - dSetZero (j->anchor1,4); - dSetZero (j->anchor2,4); - dSetZero (j->axis1,4); - j->axis1[0] = 1; - dSetZero (j->axis2,4); - j->axis2[1] = 1; - j->c0 = 0; - j->s0 = 0; - - dSetZero (j->v1,4); - j->v1[0] = 1; - dSetZero (j->v2,4); - j->v2[1] = 1; - - j->limot1.init (j->world); - j->limot2.init (j->world); - - j->susp_erp = j->world->global_erp; - j->susp_cfm = j->world->global_cfm; - - j->flags |= dJOINT_TWOBODIES; -} - - -static void hinge2GetInfo1 (dxJointHinge2 *j, dxJoint::Info1 *info) -{ - info->m = 4; - info->nub = 4; - - // see if we're powered or at a joint limit for axis 1 - int atlimit=0; - if ((j->limot1.lostop >= -M_PI || j->limot1.histop <= M_PI) && - j->limot1.lostop <= j->limot1.histop) { - dReal angle = measureHinge2Angle (j); - if (j->limot1.testRotationalLimit (angle)) atlimit = 1; - } - if (atlimit || j->limot1.fmax > 0) info->m++; - - // see if we're powering axis 2 (we currently never limit this axis) - j->limot2.limit = 0; - if (j->limot2.fmax > 0) info->m++; -} - - -// macro that computes ax1,ax2 = axis 1 and 2 in global coordinates (they are -// relative to body 1 and 2 initially) and then computes the constrained -// rotational axis as the cross product of ax1 and ax2. -// the sin and cos of the angle between axis 1 and 2 is computed, this comes -// from dot and cross product rules. - -#define HINGE2_GET_AXIS_INFO(axis,sin_angle,cos_angle) \ - dVector3 ax1,ax2; \ - dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); \ - dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); \ - dCROSS (axis,=,ax1,ax2); \ - sin_angle = dSqrt (axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); \ - cos_angle = dDOT (ax1,ax2); - - -static void hinge2GetInfo2 (dxJointHinge2 *joint, dxJoint::Info2 *info) -{ - // get information we need to set the hinge row - dReal s,c; - dVector3 q; - HINGE2_GET_AXIS_INFO (q,s,c); - dNormalize3 (q); // @@@ quicker: divide q by s ? - - // set the three ball-and-socket rows (aligned to the suspension axis ax1) - setBall2 (joint,info,joint->anchor1,joint->anchor2,ax1,joint->susp_erp); - - // set the hinge row - int s3=3*info->rowskip; - info->J1a[s3+0] = q[0]; - info->J1a[s3+1] = q[1]; - info->J1a[s3+2] = q[2]; - if (joint->node[1].body) { - info->J2a[s3+0] = -q[0]; - info->J2a[s3+1] = -q[1]; - info->J2a[s3+2] = -q[2]; - } - - // compute the right hand side for the constrained rotational DOF. - // axis 1 and axis 2 are separated by an angle `theta'. the desired - // separation angle is theta0. sin(theta0) and cos(theta0) are recorded - // in the joint structure. the correcting angular velocity is: - // |angular_velocity| = angle/time = erp*(theta0-theta) / stepsize - // = (erp*fps) * (theta0-theta) - // (theta0-theta) can be computed using the following small-angle-difference - // approximation: - // theta0-theta ~= tan(theta0-theta) - // = sin(theta0-theta)/cos(theta0-theta) - // = (c*s0 - s*c0) / (c*c0 + s*s0) - // = c*s0 - s*c0 assuming c*c0 + s*s0 ~= 1 - // where c = cos(theta), s = sin(theta) - // c0 = cos(theta0), s0 = sin(theta0) - - dReal k = info->fps * info->erp; - info->c[3] = k * (joint->c0 * s - joint->s0 * c); - - // if the axis1 hinge is powered, or has joint limits, add in more stuff - int row = 4 + joint->limot1.addLimot (joint,info,4,ax1,1); - - // if the axis2 hinge is powered, add in more stuff - joint->limot2.addLimot (joint,info,row,ax2,1); - - // set parameter for the suspension - info->cfm[0] = joint->susp_cfm; -} - - -// compute vectors v1 and v2 (embedded in body1), used to measure angle -// between body 1 and body 2 - -static void makeHinge2V1andV2 (dxJointHinge2 *joint) -{ - if (joint->node[0].body) { - // get axis 1 and 2 in global coords - dVector3 ax1,ax2,v; - dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); - dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); - - // don't do anything if the axis1 or axis2 vectors are zero or the same - if ((ax1[0]==0 && ax1[1]==0 && ax1[2]==0) || - (ax2[0]==0 && ax2[1]==0 && ax2[2]==0) || - (ax1[0]==ax2[0] && ax1[1]==ax2[1] && ax1[2]==ax2[2])) return; - - // modify axis 2 so it's perpendicular to axis 1 - dReal k = dDOT(ax1,ax2); - for (int i=0; i<3; i++) ax2[i] -= k*ax1[i]; - dNormalize3 (ax2); - - // make v1 = modified axis2, v2 = axis1 x (modified axis2) - dCROSS (v,=,ax1,ax2); - dMULTIPLY1_331 (joint->v1,joint->node[0].body->R,ax2); - dMULTIPLY1_331 (joint->v2,joint->node[0].body->R,v); - } -} - - -extern "C" void dJointSetHinge2Anchor (dxJointHinge2 *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); - makeHinge2V1andV2 (joint); -} - - -extern "C" void dJointSetHinge2Axis1 (dxJointHinge2 *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[0].body) { - dReal q[4]; - q[0] = x; - q[1] = y; - q[2] = z; - q[3] = 0; - dNormalize3 (q); - dMULTIPLY1_331 (joint->axis1,joint->node[0].body->R,q); - joint->axis1[3] = 0; - - // compute the sin and cos of the angle between axis 1 and axis 2 - dVector3 ax; - HINGE2_GET_AXIS_INFO(ax,joint->s0,joint->c0); - } - makeHinge2V1andV2 (joint); -} - - -extern "C" void dJointSetHinge2Axis2 (dxJointHinge2 *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[1].body) { - dReal q[4]; - q[0] = x; - q[1] = y; - q[2] = z; - q[3] = 0; - dNormalize3 (q); - dMULTIPLY1_331 (joint->axis2,joint->node[1].body->R,q); - joint->axis1[3] = 0; - - // compute the sin and cos of the angle between axis 1 and axis 2 - dVector3 ax; - HINGE2_GET_AXIS_INFO(ax,joint->s0,joint->c0); - } - makeHinge2V1andV2 (joint); -} - - -extern "C" void dJointSetHinge2Param (dxJointHinge2 *joint, - int parameter, dReal value) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if ((parameter & 0xff00) == 0x100) { - joint->limot2.set (parameter & 0xff,value); - } - else { - if (parameter == dParamSuspensionERP) joint->susp_erp = value; - else if (parameter == dParamSuspensionCFM) joint->susp_cfm = value; - else joint->limot1.set (parameter,value); - } -} - - -extern "C" void dJointGetHinge2Anchor (dxJointHinge2 *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->flags & dJOINT_REVERSE) - getAnchor2 (joint,result,joint->anchor2); - else - getAnchor (joint,result,joint->anchor1); -} - - -extern "C" void dJointGetHinge2Anchor2 (dxJointHinge2 *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->flags & dJOINT_REVERSE) - getAnchor (joint,result,joint->anchor1); - else - getAnchor2 (joint,result,joint->anchor2); -} - - -extern "C" void dJointGetHinge2Axis1 (dxJointHinge2 *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[0].body) { - dMULTIPLY0_331 (result,joint->node[0].body->R,joint->axis1); - } -} - - -extern "C" void dJointGetHinge2Axis2 (dxJointHinge2 *joint, dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[1].body) { - dMULTIPLY0_331 (result,joint->node[1].body->R,joint->axis2); - } -} - - -extern "C" dReal dJointGetHinge2Param (dxJointHinge2 *joint, int parameter) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if ((parameter & 0xff00) == 0x100) { - return joint->limot2.get (parameter & 0xff); - } - else { - if (parameter == dParamSuspensionERP) return joint->susp_erp; - else if (parameter == dParamSuspensionCFM) return joint->susp_cfm; - else return joint->limot1.get (parameter); - } -} - - -extern "C" dReal dJointGetHinge2Angle1 (dxJointHinge2 *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[0].body) return measureHinge2Angle (joint); - else return 0; -} - - -extern "C" dReal dJointGetHinge2Angle1Rate (dxJointHinge2 *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[0].body) { - dVector3 axis; - dMULTIPLY0_331 (axis,joint->node[0].body->R,joint->axis1); - dReal rate = dDOT(axis,joint->node[0].body->avel); - if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel); - return rate; - } - else return 0; -} - - -extern "C" dReal dJointGetHinge2Angle2Rate (dxJointHinge2 *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - if (joint->node[0].body && joint->node[1].body) { - dVector3 axis; - dMULTIPLY0_331 (axis,joint->node[1].body->R,joint->axis2); - dReal rate = dDOT(axis,joint->node[0].body->avel); - if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel); - return rate; - } - else return 0; -} - - -extern "C" void dJointAddHinge2Torques (dxJointHinge2 *joint, dReal torque1, dReal torque2) -{ - dVector3 axis1, axis2; - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); - - if (joint->node[0].body && joint->node[1].body) { - dMULTIPLY0_331 (axis1,joint->node[0].body->R,joint->axis1); - dMULTIPLY0_331 (axis2,joint->node[1].body->R,joint->axis2); - axis1[0] = axis1[0] * torque1 + axis2[0] * torque2; - axis1[1] = axis1[1] * torque1 + axis2[1] * torque2; - axis1[2] = axis1[2] * torque1 + axis2[2] * torque2; - dBodyAddTorque (joint->node[0].body,axis1[0],axis1[1],axis1[2]); - dBodyAddTorque(joint->node[1].body, -axis1[0], -axis1[1], -axis1[2]); - } -} - - -dxJoint::Vtable __dhinge2_vtable = { - sizeof(dxJointHinge2), - (dxJoint::init_fn*) hinge2Init, - (dxJoint::getInfo1_fn*) hinge2GetInfo1, - (dxJoint::getInfo2_fn*) hinge2GetInfo2, - dJointTypeHinge2}; - -//**************************************************************************** -// universal - -// I just realized that the universal joint is equivalent to a hinge 2 joint with -// perfectly stiff suspension. By comparing the hinge 2 implementation to -// the universal implementation, you may be able to improve this -// implementation (or, less likely, the hinge2 implementation). - -static void universalInit (dxJointUniversal *j) -{ - dSetZero (j->anchor1,4); - dSetZero (j->anchor2,4); - dSetZero (j->axis1,4); - j->axis1[0] = 1; - dSetZero (j->axis2,4); - j->axis2[1] = 1; - dSetZero(j->qrel1,4); - dSetZero(j->qrel2,4); - j->limot1.init (j->world); - j->limot2.init (j->world); -} - - -static void getUniversalAxes(dxJointUniversal *joint, dVector3 ax1, dVector3 ax2) -{ - // This says "ax1 = joint->node[0].body->R * joint->axis1" - dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); - - if (joint->node[1].body) { - dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); - } - else { - ax2[0] = joint->axis2[0]; - ax2[1] = joint->axis2[1]; - ax2[2] = joint->axis2[2]; - } -} - - -static dReal getUniversalAngle1(dxJointUniversal *joint) -{ - if (joint->node[0].body) { - // length 1 joint axis in global coordinates, from each body - dVector3 ax1, ax2; - dMatrix3 R; - dQuaternion qcross, qq, qrel; - - getUniversalAxes (joint,ax1,ax2); - - // It should be possible to get both angles without explicitly - // constructing the rotation matrix of the cross. Basically, - // orientation of the cross about axis1 comes from body 2, - // about axis 2 comes from body 1, and the perpendicular - // axis can come from the two bodies somehow. (We don't really - // want to assume it's 90 degrees, because in general the - // constraints won't be perfectly satisfied, or even very well - // satisfied.) - // - // However, we'd need a version of getHingeAngleFromRElativeQuat() - // that CAN handle when its relative quat is rotated along a direction - // other than the given axis. What I have here works, - // although it's probably much slower than need be. - - dRFrom2Axes(R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2]); - dRtoQ (R,qcross); - - // This code is essential the same as getHingeAngle(), see the comments - // there for details. - - // get qrel = relative rotation between node[0] and the cross - dQMultiply1 (qq,joint->node[0].body->q,qcross); - dQMultiply2 (qrel,qq,joint->qrel1); - - return getHingeAngleFromRelativeQuat(qrel, joint->axis1); - } - return 0; -} - - -static dReal getUniversalAngle2(dxJointUniversal *joint) -{ - if (joint->node[0].body) { - // length 1 joint axis in global coordinates, from each body - dVector3 ax1, ax2; - dMatrix3 R; - dQuaternion qcross, qq, qrel; - - getUniversalAxes (joint,ax1,ax2); - - // It should be possible to get both angles without explicitly - // constructing the rotation matrix of the cross. Basically, - // orientation of the cross about axis1 comes from body 2, - // about axis 2 comes from body 1, and the perpendicular - // axis can come from the two bodies somehow. (We don't really - // want to assume it's 90 degrees, because in general the - // constraints won't be perfectly satisfied, or even very well - // satisfied.) - // - // However, we'd need a version of getHingeAngleFromRElativeQuat() - // that CAN handle when its relative quat is rotated along a direction - // other than the given axis. What I have here works, - // although it's probably much slower than need be. - - dRFrom2Axes(R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2]); - dRtoQ(R, qcross); - - if (joint->node[1].body) { - dQMultiply1 (qq, joint->node[1].body->q, qcross); - dQMultiply2 (qrel,qq,joint->qrel2); - } - else { - // pretend joint->node[1].body->q is the identity - dQMultiply2 (qrel,qcross, joint->qrel2); - } - - return - getHingeAngleFromRelativeQuat(qrel, joint->axis2); - } - return 0; -} - - -static void universalGetInfo1 (dxJointUniversal *j, dxJoint::Info1 *info) -{ - info->nub = 4; - info->m = 4; - - // see if we're powered or at a joint limit. - bool constraint1 = j->limot1.fmax > 0; - bool constraint2 = j->limot2.fmax > 0; - - bool limiting1 = (j->limot1.lostop >= -M_PI || j->limot1.histop <= M_PI) && - j->limot1.lostop <= j->limot1.histop; - bool limiting2 = (j->limot2.lostop >= -M_PI || j->limot2.histop <= M_PI) && - j->limot2.lostop <= j->limot2.histop; - - // We need to call testRotationLimit() even if we're motored, since it - // records the result. - if (limiting1 || limiting2) { - dReal angle1, angle2; - angle1 = getUniversalAngle1(j); - angle2 = getUniversalAngle2(j); - if (limiting1 && j->limot1.testRotationalLimit (angle1)) constraint1 = true; - if (limiting2 && j->limot2.testRotationalLimit (angle2)) constraint2 = true; - } - if (constraint1) - info->m++; - if (constraint2) - info->m++; -} - - -static void universalGetInfo2 (dxJointUniversal *joint, dxJoint::Info2 *info) -{ - // set the three ball-and-socket rows - setBall (joint,info,joint->anchor1,joint->anchor2); - - // set the universal joint row. the angular velocity about an axis - // perpendicular to both joint axes should be equal. thus the constraint - // equation is - // p*w1 - p*w2 = 0 - // where p is a vector normal to both joint axes, and w1 and w2 - // are the angular velocity vectors of the two bodies. - - // length 1 joint axis in global coordinates, from each body - dVector3 ax1, ax2; - dVector3 ax2_temp; - // length 1 vector perpendicular to ax1 and ax2. Neither body can rotate - // about this. - dVector3 p; - dReal k; - - getUniversalAxes(joint, ax1, ax2); - k = dDOT(ax1, ax2); - ax2_temp[0] = ax2[0] - k*ax1[0]; - ax2_temp[1] = ax2[1] - k*ax1[1]; - ax2_temp[2] = ax2[2] - k*ax1[2]; - dCROSS(p, =, ax1, ax2_temp); - dNormalize3(p); - - int s3=3*info->rowskip; - - info->J1a[s3+0] = p[0]; - info->J1a[s3+1] = p[1]; - info->J1a[s3+2] = p[2]; - - if (joint->node[1].body) { - info->J2a[s3+0] = -p[0]; - info->J2a[s3+1] = -p[1]; - info->J2a[s3+2] = -p[2]; - } - - // compute the right hand side of the constraint equation. set relative - // body velocities along p to bring the axes back to perpendicular. - // If ax1, ax2 are unit length joint axes as computed from body1 and - // body2, we need to rotate both bodies along the axis p. If theta - // is the angle between ax1 and ax2, we need an angular velocity - // along p to cover the angle erp * (theta - Pi/2) in one step: - // - // |angular_velocity| = angle/time = erp*(theta - Pi/2) / stepsize - // = (erp*fps) * (theta - Pi/2) - // - // if theta is close to Pi/2, - // theta - Pi/2 ~= cos(theta), so - // |angular_velocity| ~= (erp*fps) * (ax1 dot ax2) - - info->c[3] = info->fps * info->erp * - dDOT(ax1, ax2); - - // if the first angle is powered, or has joint limits, add in the stuff - int row = 4 + joint->limot1.addLimot (joint,info,4,ax1,1); - - // if the second angle is powered, or has joint limits, add in more stuff - joint->limot2.addLimot (joint,info,row,ax2,1); -} - - -static void universalComputeInitialRelativeRotations (dxJointUniversal *joint) -{ - if (joint->node[0].body) { - dVector3 ax1, ax2; - dMatrix3 R; - dQuaternion qcross; - - getUniversalAxes(joint, ax1, ax2); - - // Axis 1. - dRFrom2Axes(R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2]); - dRtoQ(R, qcross); - dQMultiply1 (joint->qrel1, joint->node[0].body->q, qcross); - - // Axis 2. - dRFrom2Axes(R, ax2[0], ax2[1], ax2[2], ax1[0], ax1[1], ax1[2]); - dRtoQ(R, qcross); - if (joint->node[1].body) { - dQMultiply1 (joint->qrel2, joint->node[1].body->q, qcross); - } - else { - // set joint->qrel to qcross - for (int i=0; i<4; i++) joint->qrel2[i] = qcross[i]; - } - } -} - - -extern "C" void dJointSetUniversalAnchor (dxJointUniversal *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); - universalComputeInitialRelativeRotations(joint); -} - - -extern "C" void dJointSetUniversalAxis1 (dxJointUniversal *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - setAxes (joint,x,y,z,NULL,joint->axis2); - else - setAxes (joint,x,y,z,joint->axis1,NULL); - universalComputeInitialRelativeRotations(joint); -} - - -extern "C" void dJointSetUniversalAxis2 (dxJointUniversal *joint, - dReal x, dReal y, dReal z) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - setAxes (joint,x,y,z,joint->axis1,NULL); - else - setAxes (joint,x,y,z,NULL,joint->axis2); - universalComputeInitialRelativeRotations(joint); -} - - -extern "C" void dJointGetUniversalAnchor (dxJointUniversal *joint, - dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - getAnchor2 (joint,result,joint->anchor2); - else - getAnchor (joint,result,joint->anchor1); -} - - -extern "C" void dJointGetUniversalAnchor2 (dxJointUniversal *joint, - dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - getAnchor (joint,result,joint->anchor1); - else - getAnchor2 (joint,result,joint->anchor2); -} - - -extern "C" void dJointGetUniversalAxis1 (dxJointUniversal *joint, - dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - getAxis2 (joint,result,joint->axis2); - else - getAxis (joint,result,joint->axis1); -} - - -extern "C" void dJointGetUniversalAxis2 (dxJointUniversal *joint, - dVector3 result) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(result,"bad result argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - getAxis (joint,result,joint->axis1); - else - getAxis2 (joint,result,joint->axis2); -} - - -extern "C" void dJointSetUniversalParam (dxJointUniversal *joint, - int parameter, dReal value) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if ((parameter & 0xff00) == 0x100) { - joint->limot2.set (parameter & 0xff,value); - } - else { - joint->limot1.set (parameter,value); - } -} - - -extern "C" dReal dJointGetUniversalParam (dxJointUniversal *joint, int parameter) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if ((parameter & 0xff00) == 0x100) { - return joint->limot2.get (parameter & 0xff); - } - else { - return joint->limot1.get (parameter); - } -} - - -extern "C" dReal dJointGetUniversalAngle1 (dxJointUniversal *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - return getUniversalAngle2 (joint); - else - return getUniversalAngle1 (joint); -} - - -extern "C" dReal dJointGetUniversalAngle2 (dxJointUniversal *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - if (joint->flags & dJOINT_REVERSE) - return getUniversalAngle1 (joint); - else - return getUniversalAngle2 (joint); -} - - -extern "C" dReal dJointGetUniversalAngle1Rate (dxJointUniversal *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - - if (joint->node[0].body) { - dVector3 axis; - - if (joint->flags & dJOINT_REVERSE) - getAxis2 (joint,axis,joint->axis2); - else - getAxis (joint,axis,joint->axis1); - - dReal rate = dDOT(axis, joint->node[0].body->avel); - if (joint->node[1].body) rate -= dDOT(axis, joint->node[1].body->avel); - return rate; - } - return 0; -} - - -extern "C" dReal dJointGetUniversalAngle2Rate (dxJointUniversal *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - - if (joint->node[0].body) { - dVector3 axis; - - if (joint->flags & dJOINT_REVERSE) - getAxis (joint,axis,joint->axis1); - else - getAxis2 (joint,axis,joint->axis2); - - dReal rate = dDOT(axis, joint->node[0].body->avel); - if (joint->node[1].body) rate -= dDOT(axis, joint->node[1].body->avel); - return rate; - } - return 0; -} - - -extern "C" void dJointAddUniversalTorques (dxJointUniversal *joint, dReal torque1, dReal torque2) -{ - dVector3 axis1, axis2; - dAASSERT(joint); - dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); - - if (joint->flags & dJOINT_REVERSE) { - dReal temp = torque1; - torque1 = - torque2; - torque2 = - temp; - } - - getAxis (joint,axis1,joint->axis1); - getAxis2 (joint,axis2,joint->axis2); - axis1[0] = axis1[0] * torque1 + axis2[0] * torque2; - axis1[1] = axis1[1] * torque1 + axis2[1] * torque2; - axis1[2] = axis1[2] * torque1 + axis2[2] * torque2; - - if (joint->node[0].body != 0) - dBodyAddTorque (joint->node[0].body,axis1[0],axis1[1],axis1[2]); - if (joint->node[1].body != 0) - dBodyAddTorque(joint->node[1].body, -axis1[0], -axis1[1], -axis1[2]); -} - - - - - -dxJoint::Vtable __duniversal_vtable = { - sizeof(dxJointUniversal), - (dxJoint::init_fn*) universalInit, - (dxJoint::getInfo1_fn*) universalGetInfo1, - (dxJoint::getInfo2_fn*) universalGetInfo2, - dJointTypeUniversal}; - -//**************************************************************************** -// angular motor - -static void amotorInit (dxJointAMotor *j) -{ - int i; - j->num = 0; - j->mode = dAMotorUser; - for (i=0; i<3; i++) { - j->rel[i] = 0; - dSetZero (j->axis[i],4); - j->limot[i].init (j->world); - j->angle[i] = 0; - } - dSetZero (j->reference1,4); - dSetZero (j->reference2,4); -} - - -// compute the 3 axes in global coordinates - -static void amotorComputeGlobalAxes (dxJointAMotor *joint, dVector3 ax[3]) -{ - if (joint->mode == dAMotorEuler) { - // special handling for euler mode - dMULTIPLY0_331 (ax[0],joint->node[0].body->R,joint->axis[0]); - if (joint->node[1].body) { - dMULTIPLY0_331 (ax[2],joint->node[1].body->R,joint->axis[2]); - } - else { - ax[2][0] = joint->axis[2][0]; - ax[2][1] = joint->axis[2][1]; - ax[2][2] = joint->axis[2][2]; - } - dCROSS (ax[1],=,ax[2],ax[0]); - dNormalize3 (ax[1]); - } - else { - for (int i=0; i < joint->num; i++) { - if (joint->rel[i] == 1) { - // relative to b1 - dMULTIPLY0_331 (ax[i],joint->node[0].body->R,joint->axis[i]); - } - else if (joint->rel[i] == 2) { - // relative to b2 - if (joint->node[1].body) { // jds: don't assert, just ignore - dMULTIPLY0_331 (ax[i],joint->node[1].body->R,joint->axis[i]); - } - } - else { - // global - just copy it - ax[i][0] = joint->axis[i][0]; - ax[i][1] = joint->axis[i][1]; - ax[i][2] = joint->axis[i][2]; - } - } - } -} - - -static void amotorComputeEulerAngles (dxJointAMotor *joint, dVector3 ax[3]) -{ - // assumptions: - // global axes already calculated --> ax - // axis[0] is relative to body 1 --> global ax[0] - // axis[2] is relative to body 2 --> global ax[2] - // ax[1] = ax[2] x ax[0] - // original ax[0] and ax[2] are perpendicular - // reference1 is perpendicular to ax[0] (in body 1 frame) - // reference2 is perpendicular to ax[2] (in body 2 frame) - // all ax[] and reference vectors are unit length - - // calculate references in global frame - dVector3 ref1,ref2; - dMULTIPLY0_331 (ref1,joint->node[0].body->R,joint->reference1); - if (joint->node[1].body) { - dMULTIPLY0_331 (ref2,joint->node[1].body->R,joint->reference2); - } - else { - ref2[0] = joint->reference2[0]; - ref2[1] = joint->reference2[1]; - ref2[2] = joint->reference2[2]; - } - - // get q perpendicular to both ax[0] and ref1, get first euler angle - dVector3 q; - dCROSS (q,=,ax[0],ref1); - joint->angle[0] = -dAtan2 (dDOT(ax[2],q),dDOT(ax[2],ref1)); - - // get q perpendicular to both ax[0] and ax[1], get second euler angle - dCROSS (q,=,ax[0],ax[1]); - joint->angle[1] = -dAtan2 (dDOT(ax[2],ax[0]),dDOT(ax[2],q)); - - // get q perpendicular to both ax[1] and ax[2], get third euler angle - dCROSS (q,=,ax[1],ax[2]); - joint->angle[2] = -dAtan2 (dDOT(ref2,ax[1]), dDOT(ref2,q)); -} - - -// set the reference vectors as follows: -// * reference1 = current axis[2] relative to body 1 -// * reference2 = current axis[0] relative to body 2 -// this assumes that: -// * axis[0] is relative to body 1 -// * axis[2] is relative to body 2 - -static void amotorSetEulerReferenceVectors (dxJointAMotor *j) -{ - if (j->node[0].body && j->node[1].body) { - dVector3 r; // axis[2] and axis[0] in global coordinates - dMULTIPLY0_331 (r,j->node[1].body->R,j->axis[2]); - dMULTIPLY1_331 (j->reference1,j->node[0].body->R,r); - dMULTIPLY0_331 (r,j->node[0].body->R,j->axis[0]); - dMULTIPLY1_331 (j->reference2,j->node[1].body->R,r); - } - - else { // jds - // else if (j->node[0].body) { - // dMULTIPLY1_331 (j->reference1,j->node[0].body->R,j->axis[2]); - // dMULTIPLY0_331 (j->reference2,j->node[0].body->R,j->axis[0]); - - // We want to handle angular motors attached to passive geoms - dVector3 r; // axis[2] and axis[0] in global coordinates - r[0] = j->axis[2][0]; r[1] = j->axis[2][1]; r[2] = j->axis[2][2]; r[3] = j->axis[2][3]; - dMULTIPLY1_331 (j->reference1,j->node[0].body->R,r); - dMULTIPLY0_331 (r,j->node[0].body->R,j->axis[0]); - j->reference2[0] += r[0]; j->reference2[1] += r[1]; - j->reference2[2] += r[2]; j->reference2[3] += r[3]; - } -} - - -static void amotorGetInfo1 (dxJointAMotor *j, dxJoint::Info1 *info) -{ - info->m = 0; - info->nub = 0; - - // compute the axes and angles, if in euler mode - if (j->mode == dAMotorEuler) { - dVector3 ax[3]; - amotorComputeGlobalAxes (j,ax); - amotorComputeEulerAngles (j,ax); - } - - // see if we're powered or at a joint limit for each axis - for (int i=0; i < j->num; i++) { - if (j->limot[i].testRotationalLimit (j->angle[i]) || - j->limot[i].fmax > 0) { - info->m++; - } - } -} - - -static void amotorGetInfo2 (dxJointAMotor *joint, dxJoint::Info2 *info) -{ - int i; - - // compute the axes (if not global) - dVector3 ax[3]; - amotorComputeGlobalAxes (joint,ax); - - // in euler angle mode we do not actually constrain the angular velocity - // along the axes axis[0] and axis[2] (although we do use axis[1]) : - // - // to get constrain w2-w1 along ...not - // ------ --------------------- ------ - // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0] - // d(angle[1])/dt = 0 ax[1] - // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2] - // - // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0. - // to prove the result for angle[0], write the expression for angle[0] from - // GetInfo1 then take the derivative. to prove this for angle[2] it is - // easier to take the euler rate expression for d(angle[2])/dt with respect - // to the components of w and set that to 0. - - dVector3 *axptr[3]; - axptr[0] = &ax[0]; - axptr[1] = &ax[1]; - axptr[2] = &ax[2]; - - dVector3 ax0_cross_ax1; - dVector3 ax1_cross_ax2; - if (joint->mode == dAMotorEuler) { - dCROSS (ax0_cross_ax1,=,ax[0],ax[1]); - axptr[2] = &ax0_cross_ax1; - dCROSS (ax1_cross_ax2,=,ax[1],ax[2]); - axptr[0] = &ax1_cross_ax2; - } - - int row=0; - for (i=0; i < joint->num; i++) { - row += joint->limot[i].addLimot (joint,info,row,*(axptr[i]),1); - } -} - - -extern "C" void dJointSetAMotorNumAxes (dxJointAMotor *joint, int num) -{ - dAASSERT(joint && num >= 0 && num <= 3); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - if (joint->mode == dAMotorEuler) { - joint->num = 3; - } - else { - if (num < 0) num = 0; - if (num > 3) num = 3; - joint->num = num; - } -} - - -extern "C" void dJointSetAMotorAxis (dxJointAMotor *joint, int anum, int rel, - dReal x, dReal y, dReal z) -{ - dAASSERT(joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - dUASSERT(!(!joint->node[1].body && (joint->flags & dJOINT_REVERSE) && rel == 1),"no first body, can't set axis rel=1"); - dUASSERT(!(!joint->node[1].body && !(joint->flags & dJOINT_REVERSE) && rel == 2),"no second body, can't set axis rel=2"); - if (anum < 0) anum = 0; - if (anum > 2) anum = 2; - - // adjust rel to match the internal body order - if (!joint->node[1].body && rel==2) rel = 1; - - joint->rel[anum] = rel; - - // x,y,z is always in global coordinates regardless of rel, so we may have - // to convert it to be relative to a body - dVector3 r; - r[0] = x; - r[1] = y; - r[2] = z; - r[3] = 0; - if (rel > 0) { - if (rel==1) { - dMULTIPLY1_331 (joint->axis[anum],joint->node[0].body->R,r); - } - else { - // don't assert; handle the case of attachment to a bodiless geom - if (joint->node[1].body) { // jds - dMULTIPLY1_331 (joint->axis[anum],joint->node[1].body->R,r); - } - else { - joint->axis[anum][0] = r[0]; joint->axis[anum][1] = r[1]; - joint->axis[anum][2] = r[2]; joint->axis[anum][3] = r[3]; - } - } - } - else { - joint->axis[anum][0] = r[0]; - joint->axis[anum][1] = r[1]; - joint->axis[anum][2] = r[2]; - } - dNormalize3 (joint->axis[anum]); - if (joint->mode == dAMotorEuler) amotorSetEulerReferenceVectors (joint); -} - - -extern "C" void dJointSetAMotorAngle (dxJointAMotor *joint, int anum, - dReal angle) -{ - dAASSERT(joint && anum >= 0 && anum < 3); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - if (joint->mode == dAMotorUser) { - if (anum < 0) anum = 0; - if (anum > 3) anum = 3; - joint->angle[anum] = angle; - } -} - - -extern "C" void dJointSetAMotorParam (dxJointAMotor *joint, int parameter, - dReal value) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - int anum = parameter >> 8; - if (anum < 0) anum = 0; - if (anum > 2) anum = 2; - parameter &= 0xff; - joint->limot[anum].set (parameter, value); -} - - -extern "C" void dJointSetAMotorMode (dxJointAMotor *joint, int mode) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - joint->mode = mode; - if (joint->mode == dAMotorEuler) { - joint->num = 3; - amotorSetEulerReferenceVectors (joint); - } -} - - -extern "C" int dJointGetAMotorNumAxes (dxJointAMotor *joint) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - return joint->num; -} - - -extern "C" void dJointGetAMotorAxis (dxJointAMotor *joint, int anum, - dVector3 result) -{ - dAASSERT(joint && anum >= 0 && anum < 3); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - if (anum < 0) anum = 0; - if (anum > 2) anum = 2; - if (joint->rel[anum] > 0) { - if (joint->rel[anum]==1) { - dMULTIPLY0_331 (result,joint->node[0].body->R,joint->axis[anum]); - } - else { - if (joint->node[1].body) { // jds - dMULTIPLY0_331 (result,joint->node[1].body->R,joint->axis[anum]); - } - else { - result[0] = joint->axis[anum][0]; result[1] = joint->axis[anum][1]; - result[2] = joint->axis[anum][2]; result[3] = joint->axis[anum][3]; - } - } - } - else { - result[0] = joint->axis[anum][0]; - result[1] = joint->axis[anum][1]; - result[2] = joint->axis[anum][2]; - } -} - - -extern "C" int dJointGetAMotorAxisRel (dxJointAMotor *joint, int anum) -{ - dAASSERT(joint && anum >= 0 && anum < 3); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - if (anum < 0) anum = 0; - if (anum > 2) anum = 2; - return joint->rel[anum]; -} - - -extern "C" dReal dJointGetAMotorAngle (dxJointAMotor *joint, int anum) -{ - dAASSERT(joint && anum >= 0 && anum < 3); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - if (anum < 0) anum = 0; - if (anum > 3) anum = 3; - return joint->angle[anum]; -} - - -extern "C" dReal dJointGetAMotorAngleRate (dxJointAMotor *joint, int anum) -{ - // @@@ - dDebug (0,"not yet implemented"); - return 0; -} - - -extern "C" dReal dJointGetAMotorParam (dxJointAMotor *joint, int parameter) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - int anum = parameter >> 8; - if (anum < 0) anum = 0; - if (anum > 2) anum = 2; - parameter &= 0xff; - return joint->limot[anum].get (parameter); -} - - -extern "C" int dJointGetAMotorMode (dxJointAMotor *joint) -{ - dAASSERT(joint); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - return joint->mode; -} - - -extern "C" void dJointAddAMotorTorques (dxJointAMotor *joint, dReal torque1, dReal torque2, dReal torque3) -{ - dVector3 axes[3]; - dAASSERT(joint); - dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); - - if (joint->num == 0) - return; - dUASSERT((joint->flags & dJOINT_REVERSE) == 0, "dJointAddAMotorTorques not yet implemented for reverse AMotor joints"); - - amotorComputeGlobalAxes (joint,axes); - axes[0][0] *= torque1; - axes[0][1] *= torque1; - axes[0][2] *= torque1; - if (joint->num >= 2) { - axes[0][0] += axes[1][0] * torque2; - axes[0][1] += axes[1][1] * torque2; - axes[0][2] += axes[1][2] * torque2; - if (joint->num >= 3) { - axes[0][0] += axes[2][0] * torque3; - axes[0][1] += axes[2][1] * torque3; - axes[0][2] += axes[2][2] * torque3; - } - } - - if (joint->node[0].body != 0) - dBodyAddTorque (joint->node[0].body,axes[0][0],axes[0][1],axes[0][2]); - if (joint->node[1].body != 0) - dBodyAddTorque(joint->node[1].body, -axes[0][0], -axes[0][1], -axes[0][2]); -} - - -dxJoint::Vtable __damotor_vtable = { - sizeof(dxJointAMotor), - (dxJoint::init_fn*) amotorInit, - (dxJoint::getInfo1_fn*) amotorGetInfo1, - (dxJoint::getInfo2_fn*) amotorGetInfo2, - dJointTypeAMotor}; - -//**************************************************************************** -// fixed joint - -static void fixedInit (dxJointFixed *j) -{ - dSetZero (j->offset,4); - dSetZero (j->qrel,4); -} - - -static void fixedGetInfo1 (dxJointFixed *j, dxJoint::Info1 *info) -{ - info->m = 6; - info->nub = 6; -} - - -static void fixedGetInfo2 (dxJointFixed *joint, dxJoint::Info2 *info) -{ - int s = info->rowskip; - - // Three rows for orientation - setFixedOrientation(joint, info, joint->qrel, 3); - - // Three rows for position. - // set jacobian - info->J1l[0] = 1; - info->J1l[s+1] = 1; - info->J1l[2*s+2] = 1; - - dVector3 ofs; - dMULTIPLY0_331 (ofs,joint->node[0].body->R,joint->offset); - if (joint->node[1].body) { - dCROSSMAT (info->J1a,ofs,s,+,-); - info->J2l[0] = -1; - info->J2l[s+1] = -1; - info->J2l[2*s+2] = -1; - } - - // set right hand side for the first three rows (linear) - dReal k = info->fps * info->erp; - if (joint->node[1].body) { - for (int j=0; j<3; j++) - info->c[j] = k * (joint->node[1].body->pos[j] - - joint->node[0].body->pos[j] + ofs[j]); - } - else { - for (int j=0; j<3; j++) - info->c[j] = k * (joint->offset[j] - joint->node[0].body->pos[j]); - } -} - - -extern "C" void dJointSetFixed (dxJointFixed *joint) -{ - dUASSERT(joint,"bad joint argument"); - dUASSERT(joint->vtable == &__dfixed_vtable,"joint is not fixed"); - int i; - - // This code is taken from sJointSetSliderAxis(), we should really put the - // common code in its own function. - // compute the offset between the bodies - if (joint->node[0].body) { - if (joint->node[1].body) { - dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); - dReal ofs[4]; - for (i=0; i<4; i++) ofs[i] = joint->node[0].body->pos[i]; - for (i=0; i<4; i++) ofs[i] -= joint->node[1].body->pos[i]; - dMULTIPLY1_331 (joint->offset,joint->node[0].body->R,ofs); - } - else { - // set joint->qrel to the transpose of the first body's q - joint->qrel[0] = joint->node[0].body->q[0]; - for (i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i]; - for (i=0; i<4; i++) joint->offset[i] = joint->node[0].body->pos[i]; - } - } -} - - -dxJoint::Vtable __dfixed_vtable = { - sizeof(dxJointFixed), - (dxJoint::init_fn*) fixedInit, - (dxJoint::getInfo1_fn*) fixedGetInfo1, - (dxJoint::getInfo2_fn*) fixedGetInfo2, - dJointTypeFixed}; - -//**************************************************************************** -// null joint - -static void nullGetInfo1 (dxJointNull *j, dxJoint::Info1 *info) -{ - info->m = 0; - info->nub = 0; -} - - -static void nullGetInfo2 (dxJointNull *joint, dxJoint::Info2 *info) -{ - dDebug (0,"this should never get called"); -} - - -dxJoint::Vtable __dnull_vtable = { - sizeof(dxJointNull), - (dxJoint::init_fn*) 0, - (dxJoint::getInfo1_fn*) nullGetInfo1, - (dxJoint::getInfo2_fn*) nullGetInfo2, - dJointTypeNull}; diff --git a/Extras/ode/ode/src/joint.h b/Extras/ode/ode/src/joint.h deleted file mode 100644 index dbc7c5f47..000000000 --- a/Extras/ode/ode/src/joint.h +++ /dev/null @@ -1,267 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_JOINT_H_ -#define _ODE_JOINT_H_ - - -#include "objects.h" -#include -#include "obstack.h" - - -// joint flags -enum { - // if this flag is set, the joint was allocated in a joint group - dJOINT_INGROUP = 1, - - // if this flag is set, the joint was attached with arguments (0,body). - // our convention is to treat all attaches as (body,0), i.e. so node[0].body - // is always nonzero, so this flag records the fact that the arguments were - // swapped. - dJOINT_REVERSE = 2, - - // if this flag is set, the joint can not have just one body attached to it, - // it must have either zero or two bodies attached. - dJOINT_TWOBODIES = 4 -}; - - -// there are two of these nodes in the joint, one for each connection to a -// body. these are node of a linked list kept by each body of it's connecting -// joints. but note that the body pointer in each node points to the body that -// makes use of the *other* node, not this node. this trick makes it a bit -// easier to traverse the body/joint graph. - -struct dxJointNode { - dxJoint *joint; // pointer to enclosing dxJoint object - dxBody *body; // *other* body this joint is connected to - dxJointNode *next; // next node in body's list of connected joints -}; - - -struct dxJoint : public dObject { - // naming convention: the "first" body this is connected to is node[0].body, - // and the "second" body is node[1].body. if this joint is only connected - // to one body then the second body is 0. - - // info returned by getInfo1 function. the constraint dimension is m (<=6). - // i.e. that is the total number of rows in the jacobian. `nub' is the - // number of unbounded variables (which have lo,hi = -/+ infinity). - - struct Info1 { - int m,nub; - }; - - // info returned by getInfo2 function - - struct Info2 { - // integrator parameters: frames per second (1/stepsize), default error - // reduction parameter (0..1). - dReal fps,erp; - - // for the first and second body, pointers to two (linear and angular) - // n*3 jacobian sub matrices, stored by rows. these matrices will have - // been initialized to 0 on entry. if the second body is zero then the - // J2xx pointers may be 0. - dReal *J1l,*J1a,*J2l,*J2a; - - // elements to jump from one row to the next in J's - int rowskip; - - // right hand sides of the equation J*v = c + cfm * lambda. cfm is the - // "constraint force mixing" vector. c is set to zero on entry, cfm is - // set to a constant value (typically very small or zero) value on entry. - dReal *c,*cfm; - - // lo and hi limits for variables (set to -/+ infinity on entry). - dReal *lo,*hi; - - // findex vector for variables. see the LCP solver interface for a - // description of what this does. this is set to -1 on entry. - // note that the returned indexes are relative to the first index of - // the constraint. - int *findex; - }; - - // virtual function table: size of the joint structure, function pointers. - // we do it this way instead of using C++ virtual functions because - // sometimes we need to allocate joints ourself within a memory pool. - - typedef void init_fn (dxJoint *joint); - typedef void getInfo1_fn (dxJoint *joint, Info1 *info); - typedef void getInfo2_fn (dxJoint *joint, Info2 *info); - struct Vtable { - int size; - init_fn *init; - getInfo1_fn *getInfo1; - getInfo2_fn *getInfo2; - int typenum; // a dJointTypeXXX type number - }; - - Vtable *vtable; // virtual function table - int flags; // dJOINT_xxx flags - dxJointNode node[2]; // connections to bodies. node[1].body can be 0 - dJointFeedback *feedback; // optional feedback structure - dReal lambda[6]; // lambda generated by last step -}; - - -// joint group. NOTE: any joints in the group that have their world destroyed -// will have their world pointer set to 0. - -struct dxJointGroup : public dBase { - int num; // number of joints on the stack - dObStack stack; // a stack of (possibly differently sized) dxJoint -}; // objects. - - -// common limit and motor information for a single joint axis of movement -struct dxJointLimitMotor { - dReal vel,fmax; // powered joint: velocity, max force - dReal lostop,histop; // joint limits, relative to initial position - dReal fudge_factor; // when powering away from joint limits - dReal normal_cfm; // cfm to use when not at a stop - dReal stop_erp,stop_cfm; // erp and cfm for when at joint limit - dReal bounce; // restitution factor - // variables used between getInfo1() and getInfo2() - int limit; // 0=free, 1=at lo limit, 2=at hi limit - dReal limit_err; // if at limit, amount over limit - - void init (dxWorld *); - void set (int num, dReal value); - dReal get (int num); - int testRotationalLimit (dReal angle); - int addLimot (dxJoint *joint, dxJoint::Info2 *info, int row, - dVector3 ax1, int rotational); -}; - - -// ball and socket - -struct dxJointBall : public dxJoint { - dVector3 anchor1; // anchor w.r.t first body - dVector3 anchor2; // anchor w.r.t second body -}; -extern struct dxJoint::Vtable __dball_vtable; - - -// hinge - -struct dxJointHinge : public dxJoint { - dVector3 anchor1; // anchor w.r.t first body - dVector3 anchor2; // anchor w.r.t second body - dVector3 axis1; // axis w.r.t first body - dVector3 axis2; // axis w.r.t second body - dQuaternion qrel; // initial relative rotation body1 -> body2 - dxJointLimitMotor limot; // limit and motor information -}; -extern struct dxJoint::Vtable __dhinge_vtable; - - -// universal - -struct dxJointUniversal : public dxJoint { - dVector3 anchor1; // anchor w.r.t first body - dVector3 anchor2; // anchor w.r.t second body - dVector3 axis1; // axis w.r.t first body - dVector3 axis2; // axis w.r.t second body - dQuaternion qrel1; // initial relative rotation body1 -> virtual cross piece - dQuaternion qrel2; // initial relative rotation virtual cross piece -> body2 - dxJointLimitMotor limot1; // limit and motor information for axis1 - dxJointLimitMotor limot2; // limit and motor information for axis2 -}; -extern struct dxJoint::Vtable __duniversal_vtable; - - -// slider. if body2 is 0 then qrel is the absolute rotation of body1 and -// offset is the position of body1 center along axis1. - -struct dxJointSlider : public dxJoint { - dVector3 axis1; // axis w.r.t first body - dQuaternion qrel; // initial relative rotation body1 -> body2 - dVector3 offset; // point relative to body2 that should be - // aligned with body1 center along axis1 - dxJointLimitMotor limot; // limit and motor information -}; -extern struct dxJoint::Vtable __dslider_vtable; - - -// contact - -struct dxJointContact : public dxJoint { - int the_m; // number of rows computed by getInfo1 - dContact contact; -}; -extern struct dxJoint::Vtable __dcontact_vtable; - - -// hinge 2 - -struct dxJointHinge2 : public dxJoint { - dVector3 anchor1; // anchor w.r.t first body - dVector3 anchor2; // anchor w.r.t second body - dVector3 axis1; // axis 1 w.r.t first body - dVector3 axis2; // axis 2 w.r.t second body - dReal c0,s0; // cos,sin of desired angle between axis 1,2 - dVector3 v1,v2; // angle ref vectors embedded in first body - dxJointLimitMotor limot1; // limit+motor info for axis 1 - dxJointLimitMotor limot2; // limit+motor info for axis 2 - dReal susp_erp,susp_cfm; // suspension parameters (erp,cfm) -}; -extern struct dxJoint::Vtable __dhinge2_vtable; - - -// angular motor - -struct dxJointAMotor : public dxJoint { - int num; // number of axes (0..3) - int mode; // a dAMotorXXX constant - int rel[3]; // what the axes are relative to (global,b1,b2) - dVector3 axis[3]; // three axes - dxJointLimitMotor limot[3]; // limit+motor info for axes - dReal angle[3]; // user-supplied angles for axes - // these vectors are used for calculating euler angles - dVector3 reference1; // original axis[2], relative to body 1 - dVector3 reference2; // original axis[0], relative to body 2 -}; -extern struct dxJoint::Vtable __damotor_vtable; - - -// fixed - -struct dxJointFixed : public dxJoint { - dQuaternion qrel; // initial relative rotation body1 -> body2 - dVector3 offset; // relative offset between the bodies -}; -extern struct dxJoint::Vtable __dfixed_vtable; - - -// null joint, for testing only - -struct dxJointNull : public dxJoint { -}; -extern struct dxJoint::Vtable __dnull_vtable; - - - -#endif diff --git a/Extras/ode/ode/src/lcp.cpp b/Extras/ode/ode/src/lcp.cpp deleted file mode 100644 index 1ff325d88..000000000 --- a/Extras/ode/ode/src/lcp.cpp +++ /dev/null @@ -1,2018 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - - -THE ALGORITHM -------------- - -solve A*x = b+w, with x and w subject to certain LCP conditions. -each x(i),w(i) must lie on one of the three line segments in the following -diagram. each line segment corresponds to one index set : - - w(i) - /|\ | : - | | : - | |i in N : - w>0 | |state[i]=0 : - | | : - | | : i in C - w=0 + +-----------------------+ - | : | - | : | - w<0 | : |i in N - | : |state[i]=1 - | : | - | : | - +-------|-----------|-----------|----------> x(i) - lo 0 hi - -the Dantzig algorithm proceeds as follows: - for i=1:n - * if (x(i),w(i)) is not on the line, push x(i) and w(i) positive or - negative towards the line. as this is done, the other (x(j),w(j)) - for j= 0. this makes the algorithm a bit -simpler, because the starting point for x(i),w(i) is always on the dotted -line x=0 and x will only ever increase in one direction, so it can only hit -two out of the three line segments. - - -NOTES ------ - -this is an implementation of "lcp_dantzig2_ldlt.m" and "lcp_dantzig_lohi.m". -the implementation is split into an LCP problem object (dLCP) and an LCP -driver function. most optimization occurs in the dLCP object. - -a naive implementation of the algorithm requires either a lot of data motion -or a lot of permutation-array lookup, because we are constantly re-ordering -rows and columns. to avoid this and make a more optimized algorithm, a -non-trivial data structure is used to represent the matrix A (this is -implemented in the fast version of the dLCP object). - -during execution of this algorithm, some indexes in A are clamped (set C), -some are non-clamped (set N), and some are "don't care" (where x=0). -A,x,b,w (and other problem vectors) are permuted such that the clamped -indexes are first, the unclamped indexes are next, and the don't-care -indexes are last. this permutation is recorded in the array `p'. -initially p = 0..n-1, and as the rows and columns of A,x,b,w are swapped, -the corresponding elements of p are swapped. - -because the C and N elements are grouped together in the rows of A, we can do -lots of work with a fast dot product function. if A,x,etc were not permuted -and we only had a permutation array, then those dot products would be much -slower as we would have a permutation array lookup in some inner loops. - -A is accessed through an array of row pointers, so that element (i,j) of the -permuted matrix is A[i][j]. this makes row swapping fast. for column swapping -we still have to actually move the data. - -during execution of this algorithm we maintain an L*D*L' factorization of -the clamped submatrix of A (call it `AC') which is the top left nC*nC -submatrix of A. there are two ways we could arrange the rows/columns in AC. - -(1) AC is always permuted such that L*D*L' = AC. this causes a problem - when a row/column is removed from C, because then all the rows/columns of A - between the deleted index and the end of C need to be rotated downward. - this results in a lot of data motion and slows things down. -(2) L*D*L' is actually a factorization of a *permutation* of AC (which is - itself a permutation of the underlying A). this is what we do - the - permutation is recorded in the vector C. call this permutation A[C,C]. - when a row/column is removed from C, all we have to do is swap two - rows/columns and manipulate C. - -*/ - -#include -#include "lcp.h" -#include -#include -#include "mat.h" // for testing -#include // for testing - -//*************************************************************************** -// code generation parameters - -// LCP debugging (mosty for fast dLCP) - this slows things down a lot -//#define DEBUG_LCP - -//#define dLCP_SLOW // use slow dLCP object -#define dLCP_FAST // use fast dLCP object - -// option 1 : matrix row pointers (less data copying) -#define ROWPTRS -#define ATYPE dReal ** -#define AROW(i) (A[i]) - -// option 2 : no matrix row pointers (slightly faster inner loops) -//#define NOROWPTRS -//#define ATYPE dReal * -//#define AROW(i) (A+(i)*nskip) - -// use protected, non-stack memory allocation system - -#ifdef dUSE_MALLOC_FOR_ALLOCA -extern unsigned int dMemoryFlag; - -#define ALLOCA(t,v,s) t* v = (t*) malloc(s) -#define UNALLOCA(t) free(t) - -#else - -#define ALLOCA(t,v,s) t* v =(t*)dALLOCA16(s) -#define UNALLOCA(t) /* nothing */ - -#endif - -//#define dDot myDot -#define NUB_OPTIMIZATIONS - -//*************************************************************************** - -// an alternative inline dot product, for speed comparisons - -static inline dReal myDot (dReal *a, dReal *b, int n) -{ - dReal sum=0; - while (n > 0) { - sum += (*a) * (*b); - a++; - b++; - n--; - } - return sum; -} - - -// swap row/column i1 with i2 in the n*n matrix A. the leading dimension of -// A is nskip. this only references and swaps the lower triangle. -// if `do_fast_row_swaps' is nonzero and row pointers are being used, then -// rows will be swapped by exchanging row pointers. otherwise the data will -// be copied. - -static void swapRowsAndCols (ATYPE A, int n, int i1, int i2, int nskip, - int do_fast_row_swaps) -{ - int i; - dAASSERT (A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n && - nskip >= n && i1 < i2); - -# ifdef ROWPTRS - for (i=i1+1; i 0) { - memcpy (tmprow,A+i1*nskip,i1*sizeof(dReal)); - memcpy (A+i1*nskip,A+i2*nskip,i1*sizeof(dReal)); - memcpy (A+i2*nskip,tmprow,i1*sizeof(dReal)); - } - for (i=i1+1; i0 && i1 >=0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && - i1 <= i2); - if (i1==i2) return; - swapRowsAndCols (A,n,i1,i2,nskip,do_fast_row_swaps); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) - return; -#endif - tmp = x[i1]; - x[i1] = x[i2]; - x[i2] = tmp; - tmp = b[i1]; - b[i1] = b[i2]; - b[i2] = tmp; - tmp = w[i1]; - w[i1] = w[i2]; - w[i2] = tmp; - tmp = lo[i1]; - lo[i1] = lo[i2]; - lo[i2] = tmp; - tmp = hi[i1]; - hi[i1] = hi[i2]; - hi[i2] = tmp; - tmpi = p[i1]; - p[i1] = p[i2]; - p[i2] = tmpi; - tmpi = state[i1]; - state[i1] = state[i2]; - state[i2] = tmpi; - if (findex) { - tmpi = findex[i1]; - findex[i1] = findex[i2]; - findex[i2] = tmpi; - } -} - - -// for debugging - check that L,d is the factorization of A[C,C]. -// A[C,C] has size nC*nC and leading dimension nskip. -// L has size nC*nC and leading dimension nskip. -// d has size nC. - -#ifdef DEBUG_LCP - -static void checkFactorization (ATYPE A, dReal *_L, dReal *_d, - int nC, int *C, int nskip) -{ - int i,j; - if (nC==0) return; - - // get A1=A, copy the lower triangle to the upper triangle, get A2=A[C,C] - dMatrix A1 (nC,nC); - for (i=0; i 1e-8) - dDebug (0,"L*D*L' check, maximum difference = %.6e\n",diff); -} - -#endif - - -// for debugging - -#ifdef DEBUG_LCP - -static void checkPermutations (int i, int n, int nC, int nN, int *p, int *C) -{ - int j,k; - dIASSERT (nC>=0 && nN>=0 && (nC+nN)==i && i < n); - for (k=0; k= 0 && p[k] < i); - for (k=i; k C,N; // index sets - int last_i_for_solve1; // last i value given to solve1 - - dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w, - dReal *_lo, dReal *_hi, dReal *_L, dReal *_d, - dReal *_Dell, dReal *_ell, dReal *_tmp, - int *_state, int *_findex, int *_p, int *_C, dReal **Arows); - // the constructor is given an initial problem description (A,x,b,w) and - // space for other working data (which the caller may allocate on the stack). - // some of this data is specific to the fast dLCP implementation. - // the matrices A and L have size n*n, vectors have size n*1. - // A represents a symmetric matrix but only the lower triangle is valid. - // `nub' is the number of unbounded indexes at the start. all the indexes - // 0..nub-1 will be put into C. - - ~dLCP(); - - int getNub() { return nub; } - // return the value of `nub'. the constructor may want to change it, - // so the caller should find out its new value. - - // transfer functions: transfer index i to the given set (C or N). indexes - // less than `nub' can never be given. A,x,b,w,etc may be permuted by these - // functions, the caller must be robust to this. - - void transfer_i_to_C (int i); - // this assumes C and N span 1:i-1. this also assumes that solve1() has - // been recently called for the same i without any other transfer - // functions in between (thereby allowing some data reuse for the fast - // implementation). - void transfer_i_to_N (int i); - // this assumes C and N span 1:i-1. - void transfer_i_from_N_to_C (int i); - void transfer_i_from_C_to_N (int i); - - int numC(); - int numN(); - // return the number of indexes in set C/N - - int indexC (int i); - int indexN (int i); - // return index i in set C/N. - - // accessor and arithmetic functions. Aij translates as A(i,j), etc. - // make sure that only the lower triangle of A is ever referenced. - - dReal Aii (int i); - dReal AiC_times_qC (int i, dReal *q); - dReal AiN_times_qN (int i, dReal *q); // for all Nj - void pN_equals_ANC_times_qC (dReal *p, dReal *q); // for all Nj - void pN_plusequals_ANi (dReal *p, int i, int sign=1); - // for all Nj. sign = +1,-1. assumes i > maximum index in N. - void pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q); - void pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q); // for all Nj - void solve1 (dReal *a, int i, int dir=1, int only_transfer=0); - // get a(C) = - dir * A(C,C) \ A(C,i). dir must be +/- 1. - // the fast version of this function computes some data that is needed by - // transfer_i_to_C(). if only_transfer is nonzero then this function - // *only* computes that data, it does not set a(C). - - void unpermute(); - // call this at the end of the LCP function. if the x/w values have been - // permuted then this will unscramble them. -}; - - -dLCP::dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w, - dReal *_lo, dReal *_hi, dReal *_L, dReal *_d, - dReal *_Dell, dReal *_ell, dReal *_tmp, - int *_state, int *_findex, int *_p, int *_C, dReal **Arows) -{ - dUASSERT (_findex==0,"slow dLCP object does not support findex array"); - - n = _n; - nub = _nub; - Adata = _Adata; - A = 0; - x = _x; - b = _b; - w = _w; - lo = _lo; - hi = _hi; - nskip = dPAD(n); - dSetZero (x,n); - last_i_for_solve1 = -1; - - int i,j; - C.setSize (n); - N.setSize (n); - for (int i=0; i0, put all indexes 0..nub-1 into C and solve for x - if (nub > 0) { - for (i=0; i= i) dDebug (0,"N assumption violated"); - if (sign > 0) { - for (k=0; k 0) { - for (ii=0; ii nub - if (nub < n) { - for (k=0; k<100; k++) { - int i1,i2; - do { - i1 = dRandInt(n-nub)+nub; - i2 = dRandInt(n-nub)+nub; - } - while (i1 > i2); - //printf ("--> %d %d\n",i1,i2); - swapProblem (A,x,b,w,lo,hi,p,state,findex,n,i1,i2,nskip,0); - } - } - */ - - // permute the problem so that *all* the unbounded variables are at the - // start, i.e. look for unbounded variables not included in `nub'. we can - // potentially push up `nub' this way and get a bigger initial factorization. - // note that when we swap rows/cols here we must not just swap row pointers, - // as the initial factorization relies on the data being all in one chunk. - // variables that have findex >= 0 are *not* considered to be unbounded even - // if lo=-inf and hi=inf - this is because these limits may change during the - // solution process. - - for (k=nub; k= 0) continue; - if (lo[k]==-dInfinity && hi[k]==dInfinity) { - swapProblem (A,x,b,w,lo,hi,p,state,findex,n,nub,k,nskip,0); - nub++; - } - } - - // if there are unbounded variables at the start, factorize A up to that - // point and solve for x. this puts all indexes 0..nub-1 into C. - if (nub > 0) { - for (k=0; k nub such that all findex variables are at the end - if (findex) { - int num_at_end = 0; - for (k=n-1; k >= nub; k--) { - if (findex[k] >= 0) { - swapProblem (A,x,b,w,lo,hi,p,state,findex,n,k,n-1-num_at_end,nskip,1); - num_at_end++; - } - } - } - - // print info about indexes - /* - for (k=0; k 0) { - // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C)) - for (j=0; j 0) { - dReal *aptr = AROW(i); -# ifdef NUB_OPTIMIZATIONS - // if nub>0, initial part of aptr unpermuted - for (j=0; j 0) { - for (int i=0; i 0) { - dReal *aptr = AROW(i); -# ifdef NUB_OPTIMIZATIONS - // if nub>0, initial part of aptr[] is guaranteed unpermuted - for (j=0; j 0) { - for (j=0; j0 && A && x && b && w && nub == 0); - - int i,k; - int nskip = dPAD(n); - ALLOCA (dReal,L,n*nskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (L == NULL) { - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,d,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (d == NULL) { - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,delta_x,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (delta_x == NULL) { - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,delta_w,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (delta_w == NULL) { - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,Dell,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (Dell == NULL) { - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,ell,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (ell == NULL) { - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,tmp,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (tmp == NULL) { - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal*,Arows,n*sizeof(dReal*)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (Arows == NULL) { - UNALLOCA(tmp); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (int,p,n*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (p == NULL) { - UNALLOCA(Arows); - UNALLOCA(tmp); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (int,C,n*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (C == NULL) { - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(tmp); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (int,dummy,n*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (dummy == NULL) { - UNALLOCA(C); - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(tmp); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - - dLCP lcp (n,0,A,x,b,w,tmp,tmp,L,d,Dell,ell,tmp,dummy,dummy,p,C,Arows); - nub = lcp.getNub(); - - for (i=0; i= 0) { - lcp.transfer_i_to_N (i); - } - else { - for (;;) { - // compute: delta_x(C) = -A(C,C)\A(C,i) - dSetZero (delta_x,n); - lcp.solve1 (delta_x,i); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { - UNALLOCA(dummy); - UNALLOCA(C); - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(tmp); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - return; - } -#endif - delta_x[i] = 1; - - // compute: delta_w = A*delta_x - dSetZero (delta_w,n); - lcp.pN_equals_ANC_times_qC (delta_w,delta_x); - lcp.pN_plusequals_ANi (delta_w,i); - delta_w[i] = lcp.AiC_times_qC (i,delta_x) + lcp.Aii(i); - - // find index to switch - int si = i; // si = switch index - int si_in_N = 0; // set to 1 if si in N - dReal s = -w[i]/delta_w[i]; - - if (s <= 0) { - dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s); - if (i < (n-1)) { - dSetZero (x+i,n-i); - dSetZero (w+i,n-i); - } - goto done; - } - - for (k=0; k < lcp.numN(); k++) { - if (delta_w[lcp.indexN(k)] < 0) { - dReal s2 = -w[lcp.indexN(k)] / delta_w[lcp.indexN(k)]; - if (s2 < s) { - s = s2; - si = lcp.indexN(k); - si_in_N = 1; - } - } - } - for (k=0; k < lcp.numC(); k++) { - if (delta_x[lcp.indexC(k)] < 0) { - dReal s2 = -x[lcp.indexC(k)] / delta_x[lcp.indexC(k)]; - if (s2 < s) { - s = s2; - si = lcp.indexC(k); - si_in_N = 0; - } - } - } - - // apply x = x + s * delta_x - lcp.pC_plusequals_s_times_qC (x,s,delta_x); - x[i] += s; - lcp.pN_plusequals_s_times_qN (w,s,delta_w); - w[i] += s * delta_w[i]; - - // switch indexes between sets if necessary - if (si==i) { - w[i] = 0; - lcp.transfer_i_to_C (i); - break; - } - if (si_in_N) { - w[si] = 0; - lcp.transfer_i_from_N_to_C (si); - } - else { - x[si] = 0; - lcp.transfer_i_from_C_to_N (si); - } - } - } - } - - done: - lcp.unpermute(); - - UNALLOCA (L); - UNALLOCA (d); - UNALLOCA (delta_x); - UNALLOCA (delta_w); - UNALLOCA (Dell); - UNALLOCA (ell); - UNALLOCA (tmp); - UNALLOCA (Arows); - UNALLOCA (p); - UNALLOCA (C); - UNALLOCA (dummy); -} - -//*************************************************************************** -// an optimized Dantzig LCP driver routine for the lo-hi LCP problem. - -void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, - dReal *w, int nub, dReal *lo, dReal *hi, int *findex) -{ - dAASSERT (n>0 && A && x && b && w && lo && hi && nub >= 0 && nub <= n); - - int i,k,hit_first_friction_index = 0; - int nskip = dPAD(n); - - // if all the variables are unbounded then we can just factor, solve, - // and return - if (nub >= n) { - dFactorLDLT (A,w,n,nskip); // use w for d - dSolveLDLT (A,w,b,n,nskip); - memcpy (x,b,n*sizeof(dReal)); - dSetZero (w,n); - - return; - } -# ifndef dNODEBUG - // check restrictions on lo and hi - for (k=0; k= 0); -# endif - ALLOCA (dReal,L,n*nskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (L == NULL) { - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,d,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (d == NULL) { - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,delta_x,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (delta_x == NULL) { - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,delta_w,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (delta_w == NULL) { - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,Dell,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (Dell == NULL) { - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,ell,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (ell == NULL) { - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal*,Arows,n*sizeof(dReal*)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (Arows == NULL) { - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (int,p,n*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (p == NULL) { - UNALLOCA(Arows); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (int,C,n*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (C == NULL) { - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - int dir; - dReal dirf; - - // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i) - ALLOCA (int,state,n*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (state == NULL) { - UNALLOCA(C); - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - // create LCP object. note that tmp is set to delta_w to save space, this - // optimization relies on knowledge of how tmp is used, so be careful! - dLCP *lcp=new dLCP(n,nub,A,x,b,w,lo,hi,L,d,Dell,ell,delta_w,state,findex,p,C,Arows); - nub = lcp->getNub(); - - // loop over all indexes nub..n-1. for index i, if x(i),w(i) satisfy the - // LCP conditions then i is added to the appropriate index set. otherwise - // x(i),w(i) is driven either +ve or -ve to force it to the valid region. - // as we drive x(i), x(C) is also adjusted to keep w(C) at zero. - // while driving x(i) we maintain the LCP conditions on the other variables - // 0..i-1. we do this by watching out for other x(i),w(i) values going - // outside the valid region, and then switching them between index sets - // when that happens. - - for (i=nub; i= 0) { - // un-permute x into delta_w, which is not being used at the moment - for (k=0; kAiC_times_qC (i,x) + lcp->AiN_times_qN (i,x) - b[i]; - - // if lo=hi=0 (which can happen for tangential friction when normals are - // 0) then the index will be assigned to set N with some state. however, - // set C's line has zero size, so the index will always remain in set N. - // with the "normal" switching logic, if w changed sign then the index - // would have to switch to set C and then back to set N with an inverted - // state. this is pointless, and also computationally expensive. to - // prevent this from happening, we use the rule that indexes with lo=hi=0 - // will never be checked for set changes. this means that the state for - // these indexes may be incorrect, but that doesn't matter. - - // see if x(i),w(i) is in a valid region - if (lo[i]==0 && w[i] >= 0) { - lcp->transfer_i_to_N (i); - state[i] = 0; - } - else if (hi[i]==0 && w[i] <= 0) { - lcp->transfer_i_to_N (i); - state[i] = 1; - } - else if (w[i]==0) { - // this is a degenerate case. by the time we get to this test we know - // that lo != 0, which means that lo < 0 as lo is not allowed to be +ve, - // and similarly that hi > 0. this means that the line segment - // corresponding to set C is at least finite in extent, and we are on it. - // NOTE: we must call lcp->solve1() before lcp->transfer_i_to_C() - lcp->solve1 (delta_x,i,0,1); - -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { - UNALLOCA(state); - UNALLOCA(C); - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - return; - } -#endif - - lcp->transfer_i_to_C (i); - } - else { - // we must push x(i) and w(i) - for (;;) { - // find direction to push on x(i) - if (w[i] <= 0) { - dir = 1; - dirf = REAL(1.0); - } - else { - dir = -1; - dirf = REAL(-1.0); - } - - // compute: delta_x(C) = -dir*A(C,C)\A(C,i) - lcp->solve1 (delta_x,i,dir); - -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { - UNALLOCA(state); - UNALLOCA(C); - UNALLOCA(p); - UNALLOCA(Arows); - UNALLOCA(ell); - UNALLOCA(Dell); - UNALLOCA(delta_w); - UNALLOCA(delta_x); - UNALLOCA(d); - UNALLOCA(L); - return; - } -#endif - - // note that delta_x[i] = dirf, but we wont bother to set it - - // compute: delta_w = A*delta_x ... note we only care about - // delta_w(N) and delta_w(i), the rest is ignored - lcp->pN_equals_ANC_times_qC (delta_w,delta_x); - lcp->pN_plusequals_ANi (delta_w,i,dir); - delta_w[i] = lcp->AiC_times_qC (i,delta_x) + lcp->Aii(i)*dirf; - - // find largest step we can take (size=s), either to drive x(i),w(i) - // to the valid LCP region or to drive an already-valid variable - // outside the valid region. - - int cmd = 1; // index switching command - int si = 0; // si = index to switch if cmd>3 - dReal s = -w[i]/delta_w[i]; - if (dir > 0) { - if (hi[i] < dInfinity) { - dReal s2 = (hi[i]-x[i])/dirf; // step to x(i)=hi(i) - if (s2 < s) { - s = s2; - cmd = 3; - } - } - } - else { - if (lo[i] > -dInfinity) { - dReal s2 = (lo[i]-x[i])/dirf; // step to x(i)=lo(i) - if (s2 < s) { - s = s2; - cmd = 2; - } - } - } - - for (k=0; k < lcp->numN(); k++) { - if ((state[lcp->indexN(k)]==0 && delta_w[lcp->indexN(k)] < 0) || - (state[lcp->indexN(k)]!=0 && delta_w[lcp->indexN(k)] > 0)) { - // don't bother checking if lo=hi=0 - if (lo[lcp->indexN(k)] == 0 && hi[lcp->indexN(k)] == 0) continue; - dReal s2 = -w[lcp->indexN(k)] / delta_w[lcp->indexN(k)]; - if (s2 < s) { - s = s2; - cmd = 4; - si = lcp->indexN(k); - } - } - } - - for (k=nub; k < lcp->numC(); k++) { - if (delta_x[lcp->indexC(k)] < 0 && lo[lcp->indexC(k)] > -dInfinity) { - dReal s2 = (lo[lcp->indexC(k)]-x[lcp->indexC(k)]) / - delta_x[lcp->indexC(k)]; - if (s2 < s) { - s = s2; - cmd = 5; - si = lcp->indexC(k); - } - } - if (delta_x[lcp->indexC(k)] > 0 && hi[lcp->indexC(k)] < dInfinity) { - dReal s2 = (hi[lcp->indexC(k)]-x[lcp->indexC(k)]) / - delta_x[lcp->indexC(k)]; - if (s2 < s) { - s = s2; - cmd = 6; - si = lcp->indexC(k); - } - } - } - - //static char* cmdstring[8] = {0,"->C","->NL","->NH","N->C", - // "C->NL","C->NH"}; - //printf ("cmd=%d (%s), si=%d\n",cmd,cmdstring[cmd],(cmd>3) ? si : i); - - // if s <= 0 then we've got a problem. if we just keep going then - // we're going to get stuck in an infinite loop. instead, just cross - // our fingers and exit with the current solution. - if (s <= 0) { - dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s); - if (i < (n-1)) { - dSetZero (x+i,n-i); - dSetZero (w+i,n-i); - } - goto done; - } - - // apply x = x + s * delta_x - lcp->pC_plusequals_s_times_qC (x,s,delta_x); - x[i] += s * dirf; - - // apply w = w + s * delta_w - lcp->pN_plusequals_s_times_qN (w,s,delta_w); - w[i] += s * delta_w[i]; - - // switch indexes between sets if necessary - switch (cmd) { - case 1: // done - w[i] = 0; - lcp->transfer_i_to_C (i); - break; - case 2: // done - x[i] = lo[i]; - state[i] = 0; - lcp->transfer_i_to_N (i); - break; - case 3: // done - x[i] = hi[i]; - state[i] = 1; - lcp->transfer_i_to_N (i); - break; - case 4: // keep going - w[si] = 0; - lcp->transfer_i_from_N_to_C (si); - break; - case 5: // keep going - x[si] = lo[si]; - state[si] = 0; - lcp->transfer_i_from_C_to_N (si); - break; - case 6: // keep going - x[si] = hi[si]; - state[si] = 1; - lcp->transfer_i_from_C_to_N (si); - break; - } - - if (cmd <= 3) break; - } - } - } - - done: - lcp->unpermute(); - delete lcp; - - UNALLOCA (L); - UNALLOCA (d); - UNALLOCA (delta_x); - UNALLOCA (delta_w); - UNALLOCA (Dell); - UNALLOCA (ell); - UNALLOCA (Arows); - UNALLOCA (p); - UNALLOCA (C); - UNALLOCA (state); -} - -//*************************************************************************** -// accuracy and timing test - -extern "C" void dTestSolveLCP() -{ - int n = 100; - int i,nskip = dPAD(n); - const dReal tol = REAL(1e-9); - printf ("dTestSolveLCP()\n"); - - ALLOCA (dReal,A,n*nskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (A == NULL) { - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,x,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (x == NULL) { - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,b,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (b == NULL) { - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,w,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (w == NULL) { - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,lo,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (lo == NULL) { - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,hi,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (hi == NULL) { - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - ALLOCA (dReal,A2,n*nskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (A2 == NULL) { - UNALLOCA (hi); - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,b2,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (b2 == NULL) { - UNALLOCA (A2); - UNALLOCA (hi); - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,lo2,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (lo2 == NULL) { - UNALLOCA (b2); - UNALLOCA (A2); - UNALLOCA (hi); - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,hi2,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (hi2 == NULL) { - UNALLOCA (lo2); - UNALLOCA (b2); - UNALLOCA (A2); - UNALLOCA (hi); - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,tmp1,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (tmp1 == NULL) { - UNALLOCA (hi2); - UNALLOCA (lo2); - UNALLOCA (b2); - UNALLOCA (A2); - UNALLOCA (hi); - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA (dReal,tmp2,n*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (tmp2 == NULL) { - UNALLOCA (tmp1); - UNALLOCA (hi2); - UNALLOCA (lo2); - UNALLOCA (b2); - UNALLOCA (A2); - UNALLOCA (hi); - UNALLOCA (lo); - UNALLOCA (w); - UNALLOCA (b); - UNALLOCA (x); - UNALLOCA (A); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - double total_time = 0; - for (int count=0; count < 1000; count++) { - - // form (A,b) = a random positive definite LCP problem - dMakeRandomMatrix (A2,n,n,1.0); - dMultiply2 (A,A2,A2,n,n,n); - dMakeRandomMatrix (x,n,1,1.0); - dMultiply0 (b,A,x,n,n,1); - for (i=0; i tol ? "FAILED" : "passed"); - if (diff > tol) dDebug (0,"A*x = b+w, maximum difference = %.6e",diff); - int n1=0,n2=0,n3=0; - for (i=0; i= 0) { - n1++; // ok - } - else if (x[i]==hi[i] && w[i] <= 0) { - n2++; // ok - } - else if (x[i] >= lo[i] && x[i] <= hi[i] && w[i] == 0) { - n3++; // ok - } - else { - dDebug (0,"FAILED: i=%d x=%.4e w=%.4e lo=%.4e hi=%.4e",i, - x[i],w[i],lo[i],hi[i]); - } - } - - // pacifier - printf ("passed: NL=%3d NH=%3d C=%3d ",n1,n2,n3); - printf ("time=%10.3f ms avg=%10.4f\n",time * 1000.0,average); - } - - UNALLOCA (A); - UNALLOCA (x); - UNALLOCA (b); - UNALLOCA (w); - UNALLOCA (lo); - UNALLOCA (hi); - UNALLOCA (A2); - UNALLOCA (b2); - UNALLOCA (lo2); - UNALLOCA (hi2); - UNALLOCA (tmp1); - UNALLOCA (tmp2); -} diff --git a/Extras/ode/ode/src/lcp.h b/Extras/ode/ode/src/lcp.h deleted file mode 100644 index 484902c1e..000000000 --- a/Extras/ode/ode/src/lcp.h +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -given (A,b,lo,hi), solve the LCP problem: A*x = b+w, where each x(i),w(i) -satisfies one of - (1) x = lo, w >= 0 - (2) x = hi, w <= 0 - (3) lo < x < hi, w = 0 -A is a matrix of dimension n*n, everything else is a vector of size n*1. -lo and hi can be +/- dInfinity as needed. the first `nub' variables are -unbounded, i.e. hi and lo are assumed to be +/- dInfinity. - -we restrict lo(i) <= 0 and hi(i) >= 0. - -the original data (A,b) may be modified by this function. - -if the `findex' (friction index) parameter is nonzero, it points to an array -of index values. in this case constraints that have findex[i] >= 0 are -special. all non-special constraints are solved for, then the lo and hi values -for the special constraints are set: - hi[i] = abs( hi[i] * x[findex[i]] ) - lo[i] = -hi[i] -and the solution continues. this mechanism allows a friction approximation -to be implemented. the first `nub' variables are assumed to have findex < 0. - -*/ - - -#ifndef _ODE_LCP_H_ -#define _ODE_LCP_H_ - - -void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w, - int nub, dReal *lo, dReal *hi, int *findex); - - -#endif diff --git a/Extras/ode/ode/src/mass.cpp b/Extras/ode/ode/src/mass.cpp deleted file mode 100644 index 88323051e..000000000 --- a/Extras/ode/ode/src/mass.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include -#include - - -#define _I(i,j) I[(i)*4+(j)] - - -// return 1 if ok, 0 if bad - -static int checkMass (dMass *m) -{ - int i; - - if (m->mass <= 0) { - dDEBUGMSG ("mass must be > 0"); - return 0; - } - if (!dIsPositiveDefinite (m->I,3)) { - dDEBUGMSG ("inertia must be positive definite"); - return 0; - } - - // verify that the center of mass position is consistent with the mass - // and inertia matrix. this is done by checking that the inertia around - // the center of mass is also positive definite. from the comment in - // dMassTranslate(), if the body is translated so that its center of mass - // is at the point of reference, then the new inertia is: - // I + mass*crossmat(c)^2 - // note that requiring this to be positive definite is exactly equivalent - // to requiring that the spatial inertia matrix - // [ mass*eye(3,3) M*crossmat(c)^T ] - // [ M*crossmat(c) I ] - // is positive definite, given that I is PD and mass>0. see the theorem - // about partitioned PD matrices for proof. - - dMatrix3 I2,chat; - dSetZero (chat,12); - dCROSSMAT (chat,m->c,4,+,-); - dMULTIPLY0_333 (I2,chat,chat); - for (i=0; i<3; i++) I2[i] = m->I[i] + m->mass*I2[i]; - for (i=4; i<7; i++) I2[i] = m->I[i] + m->mass*I2[i]; - for (i=8; i<11; i++) I2[i] = m->I[i] + m->mass*I2[i]; - if (!dIsPositiveDefinite (I2,3)) { - dDEBUGMSG ("center of mass inconsistent with mass parameters"); - return 0; - } - return 1; -} - - -void dMassSetZero (dMass *m) -{ - dAASSERT (m); - m->mass = REAL(0.0); - dSetZero (m->c,sizeof(m->c) / sizeof(dReal)); - dSetZero (m->I,sizeof(m->I) / sizeof(dReal)); -} - - -void dMassSetParameters (dMass *m, dReal themass, - dReal cgx, dReal cgy, dReal cgz, - dReal I11, dReal I22, dReal I33, - dReal I12, dReal I13, dReal I23) -{ - dAASSERT (m); - dMassSetZero (m); - m->mass = themass; - m->c[0] = cgx; - m->c[1] = cgy; - m->c[2] = cgz; - m->_I(0,0) = I11; - m->_I(1,1) = I22; - m->_I(2,2) = I33; - m->_I(0,1) = I12; - m->_I(0,2) = I13; - m->_I(1,2) = I23; - m->_I(1,0) = I12; - m->_I(2,0) = I13; - m->_I(2,1) = I23; - checkMass (m); -} - - -void dMassSetSphere (dMass *m, dReal density, dReal radius) -{ - dMassSetSphereTotal (m, (REAL(4.0)/REAL(3.0)) * M_PI * - radius*radius*radius * density, radius); -} - - -void dMassSetSphereTotal (dMass *m, dReal total_mass, dReal radius) -{ - dAASSERT (m); - dMassSetZero (m); - m->mass = total_mass; - dReal II = REAL(0.4) * total_mass * radius*radius; - m->_I(0,0) = II; - m->_I(1,1) = II; - m->_I(2,2) = II; - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassSetCappedCylinder (dMass *m, dReal density, int direction, - dReal radius, dReal length) -{ - dReal M1,M2,Ia,Ib; - dAASSERT (m); - dUASSERT (direction >= 1 && direction <= 3,"bad direction number"); - dMassSetZero (m); - M1 = M_PI*radius*radius*length*density; // cylinder mass - M2 = (REAL(4.0)/REAL(3.0))*M_PI*radius*radius*radius*density; // total cap mass - m->mass = M1+M2; - Ia = M1*(REAL(0.25)*radius*radius + (REAL(1.0)/REAL(12.0))*length*length) + - M2*(REAL(0.4)*radius*radius + REAL(0.375)*radius*length + REAL(0.25)*length*length); - Ib = (M1*REAL(0.5) + M2*REAL(0.4))*radius*radius; - m->_I(0,0) = Ia; - m->_I(1,1) = Ia; - m->_I(2,2) = Ia; - m->_I(direction-1,direction-1) = Ib; - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassSetCappedCylinderTotal (dMass *m, dReal total_mass, int direction, - dReal a, dReal b) -{ - dMassSetCappedCylinder (m, 1.0, direction, a, b); - dMassAdjust (m, total_mass); -} - - -void dMassSetCylinder (dMass *m, dReal density, int direction, - dReal radius, dReal length) -{ - dMassSetCylinderTotal (m, M_PI*radius*radius*length*density, - direction, radius, length); -} - -void dMassSetCylinderTotal (dMass *m, dReal total_mass, int direction, - dReal radius, dReal length) -{ - dReal r2,I; - dAASSERT (m); - dMassSetZero (m); - r2 = radius*radius; - m->mass = total_mass; - I = total_mass*(REAL(0.25)*r2 + (REAL(1.0)/REAL(12.0))*length*length); - m->_I(0,0) = I; - m->_I(1,1) = I; - m->_I(2,2) = I; - m->_I(direction-1,direction-1) = total_mass*REAL(0.5)*r2; - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassSetBox (dMass *m, dReal density, - dReal lx, dReal ly, dReal lz) -{ - dMassSetBoxTotal (m, lx*ly*lz*density, lx, ly, lz); -} - - -void dMassSetBoxTotal (dMass *m, dReal total_mass, - dReal lx, dReal ly, dReal lz) -{ - dAASSERT (m); - dMassSetZero (m); - m->mass = total_mass; - m->_I(0,0) = total_mass/REAL(12.0) * (ly*ly + lz*lz); - m->_I(1,1) = total_mass/REAL(12.0) * (lx*lx + lz*lz); - m->_I(2,2) = total_mass/REAL(12.0) * (lx*lx + ly*ly); - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassAdjust (dMass *m, dReal newmass) -{ - dAASSERT (m); - dReal scale = newmass / m->mass; - m->mass = newmass; - for (int i=0; i<3; i++) for (int j=0; j<3; j++) m->_I(i,j) *= scale; - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassTranslate (dMass *m, dReal x, dReal y, dReal z) -{ - // if the body is translated by `a' relative to its point of reference, - // the new inertia about the point of reference is: - // - // I + mass*(crossmat(c)^2 - crossmat(c+a)^2) - // - // where c is the existing center of mass and I is the old inertia. - - int i,j; - dMatrix3 ahat,chat,t1,t2; - dReal a[3]; - - dAASSERT (m); - - // adjust inertia matrix - dSetZero (chat,12); - dCROSSMAT (chat,m->c,4,+,-); - a[0] = x + m->c[0]; - a[1] = y + m->c[1]; - a[2] = z + m->c[2]; - dSetZero (ahat,12); - dCROSSMAT (ahat,a,4,+,-); - dMULTIPLY0_333 (t1,ahat,ahat); - dMULTIPLY0_333 (t2,chat,chat); - for (i=0; i<3; i++) for (j=0; j<3; j++) - m->_I(i,j) += m->mass * (t2[i*4+j]-t1[i*4+j]); - - // ensure perfect symmetry - m->_I(1,0) = m->_I(0,1); - m->_I(2,0) = m->_I(0,2); - m->_I(2,1) = m->_I(1,2); - - // adjust center of mass - m->c[0] += x; - m->c[1] += y; - m->c[2] += z; - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassRotate (dMass *m, const dMatrix3 R) -{ - // if the body is rotated by `R' relative to its point of reference, - // the new inertia about the point of reference is: - // - // R * I * R' - // - // where I is the old inertia. - - dMatrix3 t1; - dReal t2[3]; - - dAASSERT (m); - - // rotate inertia matrix - dMULTIPLY2_333 (t1,m->I,R); - dMULTIPLY0_333 (m->I,R,t1); - - // ensure perfect symmetry - m->_I(1,0) = m->_I(0,1); - m->_I(2,0) = m->_I(0,2); - m->_I(2,1) = m->_I(1,2); - - // rotate center of mass - dMULTIPLY0_331 (t2,R,m->c); - m->c[0] = t2[0]; - m->c[1] = t2[1]; - m->c[2] = t2[2]; - -# ifndef dNODEBUG - checkMass (m); -# endif -} - - -void dMassAdd (dMass *a, const dMass *b) -{ - int i; - dAASSERT (a && b); - dReal denom = dRecip (a->mass + b->mass); - for (i=0; i<3; i++) a->c[i] = (a->c[i]*a->mass + b->c[i]*b->mass)*denom; - a->mass += b->mass; - for (i=0; i<12; i++) a->I[i] += b->I[i]; -} diff --git a/Extras/ode/ode/src/mat.cpp b/Extras/ode/ode/src/mat.cpp deleted file mode 100644 index 6e635dcc9..000000000 --- a/Extras/ode/ode/src/mat.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include -#include -#include -#include "mat.h" - - -dMatrix::dMatrix() -{ - n = 0; - m = 0; - data = 0; -} - - -dMatrix::dMatrix (int rows, int cols) -{ - if (rows < 1 || cols < 1) dDebug (0,"bad matrix size"); - n = rows; - m = cols; - data = (dReal*) dAlloc (n*m*sizeof(dReal)); - dSetZero (data,n*m); -} - - -dMatrix::dMatrix (const dMatrix &a) -{ - n = a.n; - m = a.m; - data = (dReal*) dAlloc (n*m*sizeof(dReal)); - memcpy (data,a.data,n*m*sizeof(dReal)); -} - - -dMatrix::dMatrix (int rows, int cols, - dReal *_data, int rowskip, int colskip) -{ - if (rows < 1 || cols < 1) dDebug (0,"bad matrix size"); - n = rows; - m = cols; - data = (dReal*) dAlloc (n*m*sizeof(dReal)); - for (int i=0; i= n || j < 0 || j >= m) dDebug (0,"bad matrix (i,j)"); - return data [i*m+j]; -} - - -void dMatrix::operator= (const dMatrix &a) -{ - if (data) dFree (data,n*m*sizeof(dReal)); - n = a.n; - m = a.m; - if (n > 0 && m > 0) { - data = (dReal*) dAlloc (n*m*sizeof(dReal)); - memcpy (data,a.data,n*m*sizeof(dReal)); - } - else data = 0; -} - - -void dMatrix::operator= (dReal a) -{ - for (int i=0; i= n || q[i] < 0 || q[i] >= m) - dDebug (0,"Matrix select, bad index arrays"); - r.data[i*nq+j] = data[p[i]*m+q[j]]; - } - } - return r; -} - - -dMatrix dMatrix::operator + (const dMatrix &a) -{ - if (n != a.n || m != a.m) dDebug (0,"matrix +, mismatched sizes"); - dMatrix r (n,m); - for (int i=0; i max) max = diff; - } - } - return max; -} diff --git a/Extras/ode/ode/src/mat.h b/Extras/ode/ode/src/mat.h deleted file mode 100644 index 2814a01bf..000000000 --- a/Extras/ode/ode/src/mat.h +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// matrix class. this is mostly for convenience in the testing code, it is -// not optimized at all. correctness is much more importance here. - -#ifndef _ODE_MAT_H_ -#define _ODE_MAT_H_ - -#include - - -class dMatrix { - int n,m; // matrix dimension, n,m >= 0 - dReal *data; // if nonzero, n*m elements allocated on the heap - -public: - // constructors, destructors - dMatrix(); // make default 0x0 matrix - dMatrix (int rows, int cols); // construct zero matrix of given size - dMatrix (const dMatrix &); // construct copy of given matrix - // create copy of given data - element (i,j) is data[i*rowskip+j*colskip] - dMatrix (int rows, int cols, dReal *_data, int rowskip, int colskip); - ~dMatrix(); // destructor - - // data movement - dReal & operator () (int i, int j); // reference an element - void operator= (const dMatrix &); // matrix = matrix - void operator= (dReal); // matrix = scalar - dMatrix transpose(); // return transposed matrix - // return a permuted submatrix of this matrix, made up of the rows in p - // and the columns in q. p has np elements, q has nq elements. - dMatrix select (int np, int *p, int nq, int *q); - - // operators - dMatrix operator + (const dMatrix &); - dMatrix operator - (const dMatrix &); - dMatrix operator - (); - dMatrix operator * (const dMatrix &); - void operator += (const dMatrix &); - void operator -= (const dMatrix &); - - // utility - void clearUpperTriangle(); - void clearLowerTriangle(); - void makeRandom (dReal range); - void print (char *fmt = "%10.4f ", FILE *f=stdout); - dReal maxDifference (const dMatrix &); -}; - - -#endif diff --git a/Extras/ode/ode/src/matrix.cpp b/Extras/ode/ode/src/matrix.cpp deleted file mode 100644 index 16afe915d..000000000 --- a/Extras/ode/ode/src/matrix.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include - -// misc defines -#define ALLOCA dALLOCA16 - - -void dSetZero (dReal *a, int n) -{ - dAASSERT (a && n >= 0); - while (n > 0) { - *(a++) = 0; - n--; - } -} - - -void dSetValue (dReal *a, int n, dReal value) -{ - dAASSERT (a && n >= 0); - while (n > 0) { - *(a++) = value; - n--; - } -} - - -void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r) -{ - int i,j,k,qskip,rskip,rpad; - dAASSERT (A && B && C && p>0 && q>0 && r>0); - qskip = dPAD(q); - rskip = dPAD(r); - rpad = rskip - r; - dReal sum; - const dReal *b,*c,*bb; - bb = B; - for (i=p; i; i--) { - for (j=0 ; j0 && q>0 && r>0); - pskip = dPAD(p); - rskip = dPAD(r); - for (i=0; i0 && q>0 && r>0); - rpad = dPAD(r) - r; - qskip = dPAD(q); - bb = B; - for (i=p; i; i--) { - cc = C; - for (j=r; j; j--) { - z = 0; - sum = 0; - for (k=q; k; k--,z++) sum += bb[z] * cc[z]; - *(A++) = sum; - cc += qskip; - } - A += rpad; - bb += qskip; - } -} - - -int dFactorCholesky (dReal *A, int n) -{ - int i,j,k,nskip; - dReal sum,*a,*b,*aa,*bb,*cc,*recip; - dAASSERT (n > 0 && A); - nskip = dPAD (n); - recip = (dReal*) ALLOCA (n * sizeof(dReal)); - aa = A; - for (i=0; i 0 && L && b); - nskip = dPAD (n); - y = (dReal*) ALLOCA (n*sizeof(dReal)); - for (i=0; i= 0; i--) { - sum = 0; - for (k=i+1; k < n; k++) sum += L[k*nskip+i]*b[k]; - b[i] = (y[i]-sum)/L[i*nskip+i]; - } -} - - -int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n) -{ - int i,j,nskip; - dReal *L,*x; - dAASSERT (n > 0 && A && Ainv); - nskip = dPAD (n); - L = (dReal*) ALLOCA (nskip*n*sizeof(dReal)); - memcpy (L,A,nskip*n*sizeof(dReal)); - x = (dReal*) ALLOCA (n*sizeof(dReal)); - if (dFactorCholesky (L,n)==0) return 0; - dSetZero (Ainv,n*nskip); // make sure all padding elements set to 0 - for (i=0; i 0 && A); - int nskip = dPAD (n); - Acopy = (dReal*) ALLOCA (nskip*n * sizeof(dReal)); - memcpy (Acopy,A,nskip*n * sizeof(dReal)); - return dFactorCholesky (Acopy,n); -} - - -/***** this has been replaced by a faster version -void dSolveL1T (const dReal *L, dReal *b, int n, int nskip) -{ - int i,j; - dAASSERT (L && b && n >= 0 && nskip >= n); - dReal sum; - for (i=n-2; i>=0; i--) { - sum = 0; - for (j=i+1; j= 0); - for (int i=0; i 0 && nskip >= n); - dSolveL1 (L,b,n,nskip); - dVectorScale (b,d,n); - dSolveL1T (L,b,n,nskip); -} - - -void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip) -{ - int j,p; - dReal *W1,*W2,W11,W21,alpha1,alpha2,alphanew,gamma1,gamma2,k1,k2,Wp,ell,dee; - dAASSERT (L && d && a && n > 0 && nskip >= n); - - if (n < 2) return; - W1 = (dReal*) ALLOCA (n*sizeof(dReal)); - W2 = (dReal*) ALLOCA (n*sizeof(dReal)); - - W1[0] = 0; - W2[0] = 0; - for (j=1; j j) ? _GETA(i,j) : _GETA(j,i)) - - -void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, - int n1, int n2, int r, int nskip) -{ - int i; - dAASSERT(A && p && L && d && n1 > 0 && n2 > 0 && r >= 0 && r < n2 && - n1 >= n2 && nskip >= n1); - #ifndef dNODEBUG - for (i=0; i= 0 && p[i] < n1); - #endif - - if (r==n2-1) { - return; // deleting last row/col is easy - } - else if (r==0) { - dReal *a = (dReal*) ALLOCA (n2 * sizeof(dReal)); - for (i=0; i 0 && nskip >= n && r >= 0 && r < n); - if (r >= n-1) return; - if (r > 0) { - for (i=0; i -#include -#include - - -static dAllocFunction *allocfn = 0; -static dReallocFunction *reallocfn = 0; -static dFreeFunction *freefn = 0; - - - -void dSetAllocHandler (dAllocFunction *fn) -{ - allocfn = fn; -} - - -void dSetReallocHandler (dReallocFunction *fn) -{ - reallocfn = fn; -} - - -void dSetFreeHandler (dFreeFunction *fn) -{ - freefn = fn; -} - - -dAllocFunction *dGetAllocHandler() -{ - return allocfn; -} - - -dReallocFunction *dGetReallocHandler() -{ - return reallocfn; -} - - -dFreeFunction *dGetFreeHandler() -{ - return freefn; -} - - -void * dAlloc (size_t size) -{ - if (allocfn) return allocfn (size); else return malloc (size); -} - - -void * dRealloc (void *ptr, size_t oldsize, size_t newsize) -{ - if (reallocfn) return reallocfn (ptr,oldsize,newsize); - else return realloc (ptr,newsize); -} - - -void dFree (void *ptr, size_t size) -{ - if (!ptr) return; - if (freefn) freefn (ptr,size); else free (ptr); -} diff --git a/Extras/ode/ode/src/misc.cpp b/Extras/ode/ode/src/misc.cpp deleted file mode 100644 index 1c7d9e8c7..000000000 --- a/Extras/ode/ode/src/misc.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include - -//**************************************************************************** -// random numbers - -static unsigned long seed = 0; - -unsigned long dRand() -{ - seed = (1664525L*seed + 1013904223L) & 0xffffffff; - return seed; -} - - -unsigned long dRandGetSeed() -{ - return seed; -} - - -void dRandSetSeed (unsigned long s) -{ - seed = s; -} - - -int dTestRand() -{ - unsigned long oldseed = seed; - int ret = 1; - seed = 0; - if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 || - dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 || - dRand() != 0x6252e503) ret = 0; - seed = oldseed; - return ret; -} - - -/* adam's all-int straightforward(?) dRandInt (0..n-1) */ -int dRandInt (int n) -{ - /* seems good; xor-fold and modulus */ - const unsigned long un = n; - unsigned long r = dRand(); - - /* note: probably more aggressive than it needs to be -- might be - able to get away without one or two of the innermost branches. */ - if (un <= 0x00010000UL) { - r ^= (r >> 16); - if (un <= 0x00000100UL) { - r ^= (r >> 8); - if (un <= 0x00000010UL) { - r ^= (r >> 4); - if (un <= 0x00000004UL) { - r ^= (r >> 2); - if (un <= 0x00000002UL) { - r ^= (r >> 1); - } - } - } - } - } - - return (int) (r % un); -} - - -dReal dRandReal() -{ - return ((dReal) dRand()) / ((dReal) 0xffffffff); -} - -//**************************************************************************** -// matrix utility stuff - -void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f) -{ - int i,j; - int skip = dPAD(m); - for (i=0; i max) max = diff; - } - } - return max; -} - - -dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n) -{ - int i,j; - int skip = dPAD(n); - dReal diff,max; - max = 0; - for (i=0; i max) max = diff; - } - } - return max; -} diff --git a/Extras/ode/ode/src/objects.h b/Extras/ode/ode/src/objects.h deleted file mode 100644 index 7475ac20d..000000000 --- a/Extras/ode/ode/src/objects.h +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// object, body, and world structs. - - -#ifndef _ODE_OBJECT_H_ -#define _ODE_OBJECT_H_ - -#include -#include -#include -#include "array.h" - - -// some body flags - -enum { - dxBodyFlagFiniteRotation = 1, // use finite rotations - dxBodyFlagFiniteRotationAxis = 2, // use finite rotations only along axis - dxBodyDisabled = 4, // body is disabled - dxBodyNoGravity = 8, // body is not influenced by gravity - dxBodyAutoDisable = 16 // enable auto-disable on body -}; - - -// base class that does correct object allocation / deallocation - -struct dBase { - void *operator new (size_t size) { return dAlloc (size); } - void operator delete (void *ptr, size_t size) { dFree (ptr,size); } - void *operator new[] (size_t size) { return dAlloc (size); } - void operator delete[] (void *ptr, size_t size) { dFree (ptr,size); } -}; - - -// base class for bodies and joints - -struct dObject : public dBase { - dxWorld *world; // world this object is in - dObject *next; // next object of this type in list - dObject **tome; // pointer to previous object's next ptr - void *userdata; // user settable data - int tag; // used by dynamics algorithms -}; - - -// auto disable parameters -struct dxAutoDisable { - dReal linear_threshold; // linear (squared) velocity treshold - dReal angular_threshold; // angular (squared) velocity treshold - dReal idle_time; // time the body needs to be idle to auto-disable it - int idle_steps; // steps the body needs to be idle to auto-disable it -}; - - -// quick-step parameters -struct dxQuickStepParameters { - int num_iterations; // number of SOR iterations to perform - dReal w; // the SOR over-relaxation parameter -}; - - -// contact generation parameters -struct dxContactParameters { - dReal max_vel; // maximum correcting velocity - dReal min_depth; // thickness of 'surface layer' -}; - - -struct dxBody : public dObject { - dxJointNode *firstjoint; // list of attached joints - int flags; // some dxBodyFlagXXX flags - dGeomID geom; // first collision geom associated with body - dMass mass; // mass parameters about POR - dMatrix3 invI; // inverse of mass.I - dReal invMass; // 1 / mass.mass - dVector3 pos; // position of POR (point of reference) - dQuaternion q; // orientation quaternion - dMatrix3 R; // rotation matrix, always corresponds to q - dVector3 lvel,avel; // linear and angular velocity of POR - dVector3 facc,tacc; // force and torque accumulators - dVector3 finite_rot_axis; // finite rotation axis, unit length or 0=none - - // auto-disable information - dxAutoDisable adis; // auto-disable parameters - dReal adis_timeleft; // time left to be idle - int adis_stepsleft; // steps left to be idle -}; - - -struct dxWorld : public dBase { - dxBody *firstbody; // body linked list - dxJoint *firstjoint; // joint linked list - int nb,nj; // number of bodies and joints in lists - dVector3 gravity; // gravity vector (m/s/s) - dReal global_erp; // global error reduction parameter - dReal global_cfm; // global costraint force mixing parameter - dxAutoDisable adis; // auto-disable parameters - int adis_flag; // auto-disable flag for new bodies - dxQuickStepParameters qs; - dxContactParameters contactp; -}; - - -#endif diff --git a/Extras/ode/ode/src/obstack.cpp b/Extras/ode/ode/src/obstack.cpp deleted file mode 100644 index 084039633..000000000 --- a/Extras/ode/ode/src/obstack.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include -#include "obstack.h" - -//**************************************************************************** -// macros and constants - -#define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \ - ofs = (size_t) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) ); - -#define MAX_ALLOC_SIZE \ - ((size_t)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1)) - -//**************************************************************************** -// dObStack - -dObStack::dObStack() -{ - first = 0; - last = 0; - current_arena = 0; - current_ofs = 0; -} - - -dObStack::~dObStack() -{ - // free all arenas - Arena *a,*nexta; - a = first; - while (a) { - nexta = a->next; - dFree (a,dOBSTACK_ARENA_SIZE); - a = nexta; - } -} - - -void *dObStack::alloc (int num_bytes) -{ - if ((size_t)num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large"); - - // allocate or move to a new arena if necessary - if (!first) { - // allocate the first arena if necessary - first = last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); - first->next = 0; - first->used = sizeof (Arena); - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used); - } - else { - // we already have one or more arenas, see if a new arena must be used - if ((last->used + num_bytes) > dOBSTACK_ARENA_SIZE) { - if (!last->next) { - last->next = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); - last->next->next = 0; - } - last = last->next; - last->used = sizeof (Arena); - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used); - } - } - - // allocate an area in the arena - char *c = ((char*) last) + last->used; - last->used += num_bytes; - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used); - return c; -} - - -void dObStack::freeAll() -{ - last = first; - if (first) { - first->used = sizeof(Arena); - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used); - } -} - - -void *dObStack::rewind() -{ - current_arena = first; - current_ofs = sizeof (Arena); - if (current_arena) { - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs) - return ((char*) current_arena) + current_ofs; - } - else return 0; -} - - -void *dObStack::next (int num_bytes) -{ - // this functions like alloc, except that no new storage is ever allocated - if (!current_arena) return 0; - current_ofs += num_bytes; - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs); - if (current_ofs >= current_arena->used) { - current_arena = current_arena->next; - if (!current_arena) return 0; - current_ofs = sizeof (Arena); - ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs); - } - return ((char*) current_arena) + current_ofs; -} diff --git a/Extras/ode/ode/src/obstack.h b/Extras/ode/ode/src/obstack.h deleted file mode 100644 index fd283fed4..000000000 --- a/Extras/ode/ode/src/obstack.h +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_OBSTACK_H_ -#define _ODE_OBSTACK_H_ - -#include "objects.h" - -// each obstack Arena pointer points to a block of this many bytes -#define dOBSTACK_ARENA_SIZE 16384 - - -struct dObStack : public dBase { - struct Arena { - Arena *next; // next arena in linked list - int used; // total number of bytes used in this arena, counting - }; // this header - - Arena *first; // head of the arena linked list. 0 if no arenas yet - Arena *last; // arena where blocks are currently being allocated - - // used for iterator - Arena *current_arena; - int current_ofs; - - dObStack(); - ~dObStack(); - - void *alloc (int num_bytes); - // allocate a block in the last arena, allocating a new arena if necessary. - // it is a runtime error if num_bytes is larger than the arena size. - - void freeAll(); - // free all blocks in all arenas. this does not deallocate the arenas - // themselves, so future alloc()s will reuse them. - - void *rewind(); - // rewind the obstack iterator, and return the address of the first - // allocated block. return 0 if there are no allocated blocks. - - void *next (int num_bytes); - // return the address of the next allocated block. 'num_bytes' is the size - // of the previous block. this returns null if there are no more arenas. - // the sequence of 'num_bytes' parameters passed to next() during a - // traversal of the list must exactly match the parameters passed to alloc(). -}; - - -#endif diff --git a/Extras/ode/ode/src/ode.cpp b/Extras/ode/ode/src/ode.cpp deleted file mode 100644 index a0bbe6775..000000000 --- a/Extras/ode/ode/src/ode.cpp +++ /dev/null @@ -1,1568 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifdef _MSC_VER -#pragma warning(disable:4291) // for VC++, no complaints about "no matching operator delete found" -#endif - -// this source file is mostly concerned with the data structures, not the -// numerics. - -#include "objects.h" -#include -#include "joint.h" -#include -#include -#include "step.h" -#include "quickstep.h" -#include "util.h" -#include -#include - -// misc defines -#define ALLOCA dALLOCA16 - -//**************************************************************************** -// utility - -static inline void initObject (dObject *obj, dxWorld *w) -{ - obj->world = w; - obj->next = 0; - obj->tome = 0; - obj->userdata = 0; - obj->tag = 0; -} - - -// add an object `obj' to the list who's head pointer is pointed to by `first'. - -static inline void addObjectToList (dObject *obj, dObject **first) -{ - obj->next = *first; - obj->tome = first; - if (*first) (*first)->tome = &obj->next; - (*first) = obj; -} - - -// remove the object from the linked list - -static inline void removeObjectFromList (dObject *obj) -{ - if (obj->next) obj->next->tome = obj->tome; - *(obj->tome) = obj->next; - // safeguard - obj->next = 0; - obj->tome = 0; -} - - -// remove the joint from neighbour lists of all connected bodies - -static void removeJointReferencesFromAttachedBodies (dxJoint *j) -{ - for (int i=0; i<2; i++) { - dxBody *body = j->node[i].body; - if (body) { - dxJointNode *n = body->firstjoint; - dxJointNode *last = 0; - while (n) { - if (n->joint == j) { - if (last) last->next = n->next; - else body->firstjoint = n->next; - break; - } - last = n; - n = n->next; - } - } - } - j->node[0].body = 0; - j->node[0].next = 0; - j->node[1].body = 0; - j->node[1].next = 0; -} - -//**************************************************************************** -// debugging - -// see if an object list loops on itself (if so, it's bad). - -static int listHasLoops (dObject *first) -{ - if (first==0 || first->next==0) return 0; - dObject *a=first,*b=first->next; - int skip=0; - while (b) { - if (a==b) return 1; - b = b->next; - if (skip) a = a->next; - skip ^= 1; - } - return 0; -} - - -// check the validity of the world data structures - -static void checkWorld (dxWorld *w) -{ - dxBody *b; - dxJoint *j; - - // check there are no loops - if (listHasLoops (w->firstbody)) dDebug (0,"body list has loops"); - if (listHasLoops (w->firstjoint)) dDebug (0,"joint list has loops"); - - // check lists are well formed (check `tome' pointers) - for (b=w->firstbody; b; b=(dxBody*)b->next) { - if (b->next && b->next->tome != &b->next) - dDebug (0,"bad tome pointer in body list"); - } - for (j=w->firstjoint; j; j=(dxJoint*)j->next) { - if (j->next && j->next->tome != &j->next) - dDebug (0,"bad tome pointer in joint list"); - } - - // check counts - int n = 0; - for (b=w->firstbody; b; b=(dxBody*)b->next) n++; - if (w->nb != n) dDebug (0,"body count incorrect"); - n = 0; - for (j=w->firstjoint; j; j=(dxJoint*)j->next) n++; - if (w->nj != n) dDebug (0,"joint count incorrect"); - - // set all tag values to a known value - static int count = 0; - count++; - for (b=w->firstbody; b; b=(dxBody*)b->next) b->tag = count; - for (j=w->firstjoint; j; j=(dxJoint*)j->next) j->tag = count; - - // check all body/joint world pointers are ok - for (b=w->firstbody; b; b=(dxBody*)b->next) if (b->world != w) - dDebug (0,"bad world pointer in body list"); - for (j=w->firstjoint; j; j=(dxJoint*)j->next) if (j->world != w) - dDebug (0,"bad world pointer in joint list"); - - /* - // check for half-connected joints - actually now these are valid - for (j=w->firstjoint; j; j=(dxJoint*)j->next) { - if (j->node[0].body || j->node[1].body) { - if (!(j->node[0].body && j->node[1].body)) - dDebug (0,"half connected joint found"); - } - } - */ - - // check that every joint node appears in the joint lists of both bodies it - // attaches - for (j=w->firstjoint; j; j=(dxJoint*)j->next) { - for (int i=0; i<2; i++) { - if (j->node[i].body) { - int ok = 0; - for (dxJointNode *n=j->node[i].body->firstjoint; n; n=n->next) { - if (n->joint == j) ok = 1; - } - if (ok==0) dDebug (0,"joint not in joint list of attached body"); - } - } - } - - // check all body joint lists (correct body ptrs) - for (b=w->firstbody; b; b=(dxBody*)b->next) { - for (dxJointNode *n=b->firstjoint; n; n=n->next) { - if (&n->joint->node[0] == n) { - if (n->joint->node[1].body != b) - dDebug (0,"bad body pointer in joint node of body list (1)"); - } - else { - if (n->joint->node[0].body != b) - dDebug (0,"bad body pointer in joint node of body list (2)"); - } - if (n->joint->tag != count) dDebug (0,"bad joint node pointer in body"); - } - } - - // check all body pointers in joints, check they are distinct - for (j=w->firstjoint; j; j=(dxJoint*)j->next) { - if (j->node[0].body && (j->node[0].body == j->node[1].body)) - dDebug (0,"non-distinct body pointers in joint"); - if ((j->node[0].body && j->node[0].body->tag != count) || - (j->node[1].body && j->node[1].body->tag != count)) - dDebug (0,"bad body pointer in joint"); - } -} - - -void dWorldCheck (dxWorld *w) -{ - checkWorld (w); -} - -//**************************************************************************** -// body - -dxBody *dBodyCreate (dxWorld *w) -{ - dAASSERT (w); - dxBody *b = new dxBody; - initObject (b,w); - b->firstjoint = 0; - b->flags = 0; - b->geom = 0; - dMassSetParameters (&b->mass,1,0,0,0,1,1,1,0,0,0); - dSetZero (b->invI,4*3); - b->invI[0] = 1; - b->invI[5] = 1; - b->invI[10] = 1; - b->invMass = 1; - dSetZero (b->pos,4); - dSetZero (b->q,4); - b->q[0] = 1; - dRSetIdentity (b->R); - dSetZero (b->lvel,4); - dSetZero (b->avel,4); - dSetZero (b->facc,4); - dSetZero (b->tacc,4); - dSetZero (b->finite_rot_axis,4); - addObjectToList (b,(dObject **) &w->firstbody); - w->nb++; - - // set auto-disable parameters - dBodySetAutoDisableDefaults (b); // must do this after adding to world - b->adis_stepsleft = b->adis.idle_steps; - b->adis_timeleft = b->adis.idle_time; - - return b; -} - - -void dBodyDestroy (dxBody *b) -{ - dAASSERT (b); - - // all geoms that link to this body must be notified that the body is about - // to disappear. note that the call to dGeomSetBody(geom,0) will result in - // dGeomGetBodyNext() returning 0 for the body, so we must get the next body - // before setting the body to 0. - dxGeom *next_geom = 0; - for (dxGeom *geom = b->geom; geom; geom = next_geom) { - next_geom = dGeomGetBodyNext (geom); - dGeomSetBody (geom,0); - } - - // detach all neighbouring joints, then delete this body. - dxJointNode *n = b->firstjoint; - while (n) { - // sneaky trick to speed up removal of joint references (black magic) - n->joint->node[(n == n->joint->node)].body = 0; - - dxJointNode *next = n->next; - n->next = 0; - removeJointReferencesFromAttachedBodies (n->joint); - n = next; - } - removeObjectFromList (b); - b->world->nb--; - delete b; -} - - -void dBodySetData (dBodyID b, void *data) -{ - dAASSERT (b); - b->userdata = data; -} - - -void *dBodyGetData (dBodyID b) -{ - dAASSERT (b); - return b->userdata; -} - - -void dBodySetPosition (dBodyID b, dReal x, dReal y, dReal z) -{ - dAASSERT (b); - b->pos[0] = x; - b->pos[1] = y; - b->pos[2] = z; - - // notify all attached geoms that this body has moved - for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) - dGeomMoved (geom); -} - - -void dBodySetRotation (dBodyID b, const dMatrix3 R) -{ - dAASSERT (b && R); - dQuaternion q; - dRtoQ (R,q); - dNormalize4 (q); - b->q[0] = q[0]; - b->q[1] = q[1]; - b->q[2] = q[2]; - b->q[3] = q[3]; - dQtoR (b->q,b->R); - - // notify all attached geoms that this body has moved - for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) - dGeomMoved (geom); -} - - -void dBodySetQuaternion (dBodyID b, const dQuaternion q) -{ - dAASSERT (b && q); - b->q[0] = q[0]; - b->q[1] = q[1]; - b->q[2] = q[2]; - b->q[3] = q[3]; - dNormalize4 (b->q); - dQtoR (b->q,b->R); - - // notify all attached geoms that this body has moved - for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) - dGeomMoved (geom); -} - - -void dBodySetLinearVel (dBodyID b, dReal x, dReal y, dReal z) -{ - dAASSERT (b); - b->lvel[0] = x; - b->lvel[1] = y; - b->lvel[2] = z; -} - - -void dBodySetAngularVel (dBodyID b, dReal x, dReal y, dReal z) -{ - dAASSERT (b); - b->avel[0] = x; - b->avel[1] = y; - b->avel[2] = z; -} - - -const dReal * dBodyGetPosition (dBodyID b) -{ - dAASSERT (b); - return b->pos; -} - - -const dReal * dBodyGetRotation (dBodyID b) -{ - dAASSERT (b); - return b->R; -} - - -const dReal * dBodyGetQuaternion (dBodyID b) -{ - dAASSERT (b); - return b->q; -} - - -const dReal * dBodyGetLinearVel (dBodyID b) -{ - dAASSERT (b); - return b->lvel; -} - - -const dReal * dBodyGetAngularVel (dBodyID b) -{ - dAASSERT (b); - return b->avel; -} - - -void dBodySetMass (dBodyID b, const dMass *mass) -{ - dAASSERT (b && mass); - memcpy (&b->mass,mass,sizeof(dMass)); - if (dInvertPDMatrix (b->mass.I,b->invI,3)==0) { - dDEBUGMSG ("inertia must be positive definite"); - dRSetIdentity (b->invI); - } - b->invMass = dRecip(b->mass.mass); -} - - -void dBodyGetMass (dBodyID b, dMass *mass) -{ - dAASSERT (b && mass); - memcpy (mass,&b->mass,sizeof(dMass)); -} - - -void dBodyAddForce (dBodyID b, dReal fx, dReal fy, dReal fz) -{ - dAASSERT (b); - b->facc[0] += fx; - b->facc[1] += fy; - b->facc[2] += fz; -} - - -void dBodyAddTorque (dBodyID b, dReal fx, dReal fy, dReal fz) -{ - dAASSERT (b); - b->tacc[0] += fx; - b->tacc[1] += fy; - b->tacc[2] += fz; -} - - -void dBodyAddRelForce (dBodyID b, dReal fx, dReal fy, dReal fz) -{ - dAASSERT (b); - dVector3 t1,t2; - t1[0] = fx; - t1[1] = fy; - t1[2] = fz; - t1[3] = 0; - dMULTIPLY0_331 (t2,b->R,t1); - b->facc[0] += t2[0]; - b->facc[1] += t2[1]; - b->facc[2] += t2[2]; -} - - -void dBodyAddRelTorque (dBodyID b, dReal fx, dReal fy, dReal fz) -{ - dAASSERT (b); - dVector3 t1,t2; - t1[0] = fx; - t1[1] = fy; - t1[2] = fz; - t1[3] = 0; - dMULTIPLY0_331 (t2,b->R,t1); - b->tacc[0] += t2[0]; - b->tacc[1] += t2[1]; - b->tacc[2] += t2[2]; -} - - -void dBodyAddForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) -{ - dAASSERT (b); - b->facc[0] += fx; - b->facc[1] += fy; - b->facc[2] += fz; - dVector3 f,q; - f[0] = fx; - f[1] = fy; - f[2] = fz; - q[0] = px - b->pos[0]; - q[1] = py - b->pos[1]; - q[2] = pz - b->pos[2]; - dCROSS (b->tacc,+=,q,f); -} - - -void dBodyAddForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) -{ - dAASSERT (b); - dVector3 prel,f,p; - f[0] = fx; - f[1] = fy; - f[2] = fz; - f[3] = 0; - prel[0] = px; - prel[1] = py; - prel[2] = pz; - prel[3] = 0; - dMULTIPLY0_331 (p,b->R,prel); - b->facc[0] += f[0]; - b->facc[1] += f[1]; - b->facc[2] += f[2]; - dCROSS (b->tacc,+=,p,f); -} - - -void dBodyAddRelForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) -{ - dAASSERT (b); - dVector3 frel,f; - frel[0] = fx; - frel[1] = fy; - frel[2] = fz; - frel[3] = 0; - dMULTIPLY0_331 (f,b->R,frel); - b->facc[0] += f[0]; - b->facc[1] += f[1]; - b->facc[2] += f[2]; - dVector3 q; - q[0] = px - b->pos[0]; - q[1] = py - b->pos[1]; - q[2] = pz - b->pos[2]; - dCROSS (b->tacc,+=,q,f); -} - - -void dBodyAddRelForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz, - dReal px, dReal py, dReal pz) -{ - dAASSERT (b); - dVector3 frel,prel,f,p; - frel[0] = fx; - frel[1] = fy; - frel[2] = fz; - frel[3] = 0; - prel[0] = px; - prel[1] = py; - prel[2] = pz; - prel[3] = 0; - dMULTIPLY0_331 (f,b->R,frel); - dMULTIPLY0_331 (p,b->R,prel); - b->facc[0] += f[0]; - b->facc[1] += f[1]; - b->facc[2] += f[2]; - dCROSS (b->tacc,+=,p,f); -} - - -const dReal * dBodyGetForce (dBodyID b) -{ - dAASSERT (b); - return b->facc; -} - - -const dReal * dBodyGetTorque (dBodyID b) -{ - dAASSERT (b); - return b->tacc; -} - - -void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z) -{ - dAASSERT (b); - b->facc[0] = x; - b->facc[1] = y; - b->facc[2] = z; -} - - -void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z) -{ - dAASSERT (b); - b->tacc[0] = x; - b->tacc[1] = y; - b->tacc[2] = z; -} - - -void dBodyGetRelPointPos (dBodyID b, dReal px, dReal py, dReal pz, - dVector3 result) -{ - dAASSERT (b); - dVector3 prel,p; - prel[0] = px; - prel[1] = py; - prel[2] = pz; - prel[3] = 0; - dMULTIPLY0_331 (p,b->R,prel); - result[0] = p[0] + b->pos[0]; - result[1] = p[1] + b->pos[1]; - result[2] = p[2] + b->pos[2]; -} - - -void dBodyGetRelPointVel (dBodyID b, dReal px, dReal py, dReal pz, - dVector3 result) -{ - dAASSERT (b); - dVector3 prel,p; - prel[0] = px; - prel[1] = py; - prel[2] = pz; - prel[3] = 0; - dMULTIPLY0_331 (p,b->R,prel); - result[0] = b->lvel[0]; - result[1] = b->lvel[1]; - result[2] = b->lvel[2]; - dCROSS (result,+=,b->avel,p); -} - - -void dBodyGetPointVel (dBodyID b, dReal px, dReal py, dReal pz, - dVector3 result) -{ - dAASSERT (b); - dVector3 p; - p[0] = px - b->pos[0]; - p[1] = py - b->pos[1]; - p[2] = pz - b->pos[2]; - p[3] = 0; - result[0] = b->lvel[0]; - result[1] = b->lvel[1]; - result[2] = b->lvel[2]; - dCROSS (result,+=,b->avel,p); -} - - -void dBodyGetPosRelPoint (dBodyID b, dReal px, dReal py, dReal pz, - dVector3 result) -{ - dAASSERT (b); - dVector3 prel; - prel[0] = px - b->pos[0]; - prel[1] = py - b->pos[1]; - prel[2] = pz - b->pos[2]; - prel[3] = 0; - dMULTIPLY1_331 (result,b->R,prel); -} - - -void dBodyVectorToWorld (dBodyID b, dReal px, dReal py, dReal pz, - dVector3 result) -{ - dAASSERT (b); - dVector3 p; - p[0] = px; - p[1] = py; - p[2] = pz; - p[3] = 0; - dMULTIPLY0_331 (result,b->R,p); -} - - -void dBodyVectorFromWorld (dBodyID b, dReal px, dReal py, dReal pz, - dVector3 result) -{ - dAASSERT (b); - dVector3 p; - p[0] = px; - p[1] = py; - p[2] = pz; - p[3] = 0; - dMULTIPLY1_331 (result,b->R,p); -} - - -void dBodySetFiniteRotationMode (dBodyID b, int mode) -{ - dAASSERT (b); - b->flags &= ~(dxBodyFlagFiniteRotation | dxBodyFlagFiniteRotationAxis); - if (mode) { - b->flags |= dxBodyFlagFiniteRotation; - if (b->finite_rot_axis[0] != 0 || b->finite_rot_axis[1] != 0 || - b->finite_rot_axis[2] != 0) { - b->flags |= dxBodyFlagFiniteRotationAxis; - } - } -} - - -void dBodySetFiniteRotationAxis (dBodyID b, dReal x, dReal y, dReal z) -{ - dAASSERT (b); - b->finite_rot_axis[0] = x; - b->finite_rot_axis[1] = y; - b->finite_rot_axis[2] = z; - if (x != 0 || y != 0 || z != 0) { - dNormalize3 (b->finite_rot_axis); - b->flags |= dxBodyFlagFiniteRotationAxis; - } - else { - b->flags &= ~dxBodyFlagFiniteRotationAxis; - } -} - - -int dBodyGetFiniteRotationMode (dBodyID b) -{ - dAASSERT (b); - return ((b->flags & dxBodyFlagFiniteRotation) != 0); -} - - -void dBodyGetFiniteRotationAxis (dBodyID b, dVector3 result) -{ - dAASSERT (b); - result[0] = b->finite_rot_axis[0]; - result[1] = b->finite_rot_axis[1]; - result[2] = b->finite_rot_axis[2]; -} - - -int dBodyGetNumJoints (dBodyID b) -{ - dAASSERT (b); - int count=0; - for (dxJointNode *n=b->firstjoint; n; n=n->next, count++); - return count; -} - - -dJointID dBodyGetJoint (dBodyID b, int index) -{ - dAASSERT (b); - int i=0; - for (dxJointNode *n=b->firstjoint; n; n=n->next, i++) { - if (i == index) return n->joint; - } - return 0; -} - - -void dBodyEnable (dBodyID b) -{ - dAASSERT (b); - b->flags &= ~dxBodyDisabled; - b->adis_stepsleft = b->adis.idle_steps; - b->adis_timeleft = b->adis.idle_time; -} - - -void dBodyDisable (dBodyID b) -{ - dAASSERT (b); - b->flags |= dxBodyDisabled; -} - - -int dBodyIsEnabled (dBodyID b) -{ - dAASSERT (b); - return ((b->flags & dxBodyDisabled) == 0); -} - - -void dBodySetGravityMode (dBodyID b, int mode) -{ - dAASSERT (b); - if (mode) b->flags &= ~dxBodyNoGravity; - else b->flags |= dxBodyNoGravity; -} - - -int dBodyGetGravityMode (dBodyID b) -{ - dAASSERT (b); - return ((b->flags & dxBodyNoGravity) == 0); -} - - -// body auto-disable functions - -dReal dBodyGetAutoDisableLinearThreshold (dBodyID b) -{ - dAASSERT(b); - return dSqrt (b->adis.linear_threshold); -} - - -void dBodySetAutoDisableLinearThreshold (dBodyID b, dReal linear_threshold) -{ - dAASSERT(b); - b->adis.linear_threshold = linear_threshold * linear_threshold; -} - - -dReal dBodyGetAutoDisableAngularThreshold (dBodyID b) -{ - dAASSERT(b); - return dSqrt (b->adis.angular_threshold); -} - - -void dBodySetAutoDisableAngularThreshold (dBodyID b, dReal angular_threshold) -{ - dAASSERT(b); - b->adis.angular_threshold = angular_threshold * angular_threshold; -} - - -int dBodyGetAutoDisableSteps (dBodyID b) -{ - dAASSERT(b); - return b->adis.idle_steps; -} - - -void dBodySetAutoDisableSteps (dBodyID b, int steps) -{ - dAASSERT(b); - b->adis.idle_steps = steps; -} - - -dReal dBodyGetAutoDisableTime (dBodyID b) -{ - dAASSERT(b); - return b->adis.idle_time; -} - - -void dBodySetAutoDisableTime (dBodyID b, dReal time) -{ - dAASSERT(b); - b->adis.idle_time = time; -} - - -int dBodyGetAutoDisableFlag (dBodyID b) -{ - dAASSERT(b); - return ((b->flags & dxBodyAutoDisable) != 0); -} - - -void dBodySetAutoDisableFlag (dBodyID b, int do_auto_disable) -{ - dAASSERT(b); - if (!do_auto_disable) b->flags &= ~dxBodyAutoDisable; - else b->flags |= dxBodyAutoDisable; -} - - -void dBodySetAutoDisableDefaults (dBodyID b) -{ - dAASSERT(b); - dWorldID w = b->world; - dAASSERT(w); - b->adis = w->adis; - dBodySetAutoDisableFlag (b, w->adis_flag); -} - -//**************************************************************************** -// joints - -static void dJointInit (dxWorld *w, dxJoint *j) -{ - dIASSERT (w && j); - initObject (j,w); - j->vtable = 0; - j->flags = 0; - j->node[0].joint = j; - j->node[0].body = 0; - j->node[0].next = 0; - j->node[1].joint = j; - j->node[1].body = 0; - j->node[1].next = 0; - dSetZero (j->lambda,6); - addObjectToList (j,(dObject **) &w->firstjoint); - w->nj++; -} - - -static dxJoint *createJoint (dWorldID w, dJointGroupID group, - dxJoint::Vtable *vtable) -{ - dIASSERT (w && vtable); - dxJoint *j; - if (group) { - j = (dxJoint*) group->stack.alloc (vtable->size); - group->num++; - } - else j = (dxJoint*) dAlloc (vtable->size); - dJointInit (w,j); - j->vtable = vtable; - if (group) j->flags |= dJOINT_INGROUP; - if (vtable->init) vtable->init (j); - j->feedback = 0; - return j; -} - - -dxJoint * dJointCreateBall (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__dball_vtable); -} - - -dxJoint * dJointCreateHinge (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__dhinge_vtable); -} - - -dxJoint * dJointCreateSlider (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__dslider_vtable); -} - - -dxJoint * dJointCreateContact (dWorldID w, dJointGroupID group, - const dContact *c) -{ - dAASSERT (w && c); - dxJointContact *j = (dxJointContact *) - createJoint (w,group,&__dcontact_vtable); - j->contact = *c; - return j; -} - - -dxJoint * dJointCreateHinge2 (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__dhinge2_vtable); -} - - -dxJoint * dJointCreateUniversal (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__duniversal_vtable); -} - - -dxJoint * dJointCreateFixed (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__dfixed_vtable); -} - - -dxJoint * dJointCreateNull (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__dnull_vtable); -} - - -dxJoint * dJointCreateAMotor (dWorldID w, dJointGroupID group) -{ - dAASSERT (w); - return createJoint (w,group,&__damotor_vtable); -} - - -void dJointDestroy (dxJoint *j) -{ - dAASSERT (j); - if (j->flags & dJOINT_INGROUP) return; - removeJointReferencesFromAttachedBodies (j); - removeObjectFromList (j); - j->world->nj--; - dFree (j,j->vtable->size); -} - - -dJointGroupID dJointGroupCreate (int max_size) -{ - // not any more ... dUASSERT (max_size > 0,"max size must be > 0"); - dxJointGroup *group = new dxJointGroup; - group->num = 0; - return group; -} - - -void dJointGroupDestroy (dJointGroupID group) -{ - dAASSERT (group); - dJointGroupEmpty (group); - delete group; -} - - -void dJointGroupEmpty (dJointGroupID group) -{ - // the joints in this group are detached starting from the most recently - // added (at the top of the stack). this helps ensure that the various - // linked lists are not traversed too much, as the joints will hopefully - // be at the start of those lists. - // if any group joints have their world pointer set to 0, their world was - // previously destroyed. no special handling is required for these joints. - - dAASSERT (group); - int i; - dxJoint **jlist = (dxJoint**) ALLOCA (group->num * sizeof(dxJoint*)); - dxJoint *j = (dxJoint*) group->stack.rewind(); - for (i=0; i < group->num; i++) { - jlist[i] = j; - j = (dxJoint*) (group->stack.next (j->vtable->size)); - } - for (i=group->num-1; i >= 0; i--) { - if (jlist[i]->world) { - removeJointReferencesFromAttachedBodies (jlist[i]); - removeObjectFromList (jlist[i]); - jlist[i]->world->nj--; - } - } - group->num = 0; - group->stack.freeAll(); -} - - -void dJointAttach (dxJoint *joint, dxBody *body1, dxBody *body2) -{ - // check arguments - dUASSERT (joint,"bad joint argument"); - dUASSERT (body1 == 0 || body1 != body2,"can't have body1==body2"); - dxWorld *world = joint->world; - dUASSERT ( (!body1 || body1->world == world) && - (!body2 || body2->world == world), - "joint and bodies must be in same world"); - - // check if the joint can not be attached to just one body - dUASSERT (!((joint->flags & dJOINT_TWOBODIES) && - ((body1 != 0) ^ (body2 != 0))), - "joint can not be attached to just one body"); - - // remove any existing body attachments - if (joint->node[0].body || joint->node[1].body) { - removeJointReferencesFromAttachedBodies (joint); - } - - // if a body is zero, make sure that it is body2, so 0 --> node[1].body - if (body1==0) { - body1 = body2; - body2 = 0; - joint->flags |= dJOINT_REVERSE; - } - else { - joint->flags &= (~dJOINT_REVERSE); - } - - // attach to new bodies - joint->node[0].body = body1; - joint->node[1].body = body2; - if (body1) { - joint->node[1].next = body1->firstjoint; - body1->firstjoint = &joint->node[1]; - } - else joint->node[1].next = 0; - if (body2) { - joint->node[0].next = body2->firstjoint; - body2->firstjoint = &joint->node[0]; - } - else { - joint->node[0].next = 0; - } -} - - -void dJointSetData (dxJoint *joint, void *data) -{ - dAASSERT (joint); - joint->userdata = data; -} - - -void *dJointGetData (dxJoint *joint) -{ - dAASSERT (joint); - return joint->userdata; -} - - -int dJointGetType (dxJoint *joint) -{ - dAASSERT (joint); - return joint->vtable->typenum; -} - - -dBodyID dJointGetBody (dxJoint *joint, int index) -{ - dAASSERT (joint); - if (index == 0 || index == 1) { - if (joint->flags & dJOINT_REVERSE) return joint->node[1-index].body; - else return joint->node[index].body; - } - else return 0; -} - - -void dJointSetFeedback (dxJoint *joint, dJointFeedback *f) -{ - dAASSERT (joint); - joint->feedback = f; -} - - -dJointFeedback *dJointGetFeedback (dxJoint *joint) -{ - dAASSERT (joint); - return joint->feedback; -} - - - -dJointID dConnectingJoint (dBodyID in_b1, dBodyID in_b2) -{ - dAASSERT (in_b1 || in_b2); - - dBodyID b1, b2; - - if (in_b1 == 0) { - b1 = in_b2; - b2 = in_b1; - } - else { - b1 = in_b1; - b2 = in_b2; - } - - // look through b1's neighbour list for b2 - for (dxJointNode *n=b1->firstjoint; n; n=n->next) { - if (n->body == b2) return n->joint; - } - - return 0; -} - - - -int dConnectingJointList (dBodyID in_b1, dBodyID in_b2, dJointID* out_list) -{ - dAASSERT (in_b1 || in_b2); - - - dBodyID b1, b2; - - if (in_b1 == 0) { - b1 = in_b2; - b2 = in_b1; - } - else { - b1 = in_b1; - b2 = in_b2; - } - - // look through b1's neighbour list for b2 - int numConnectingJoints = 0; - for (dxJointNode *n=b1->firstjoint; n; n=n->next) { - if (n->body == b2) - out_list[numConnectingJoints++] = n->joint; - } - - return numConnectingJoints; -} - - -int dAreConnected (dBodyID b1, dBodyID b2) -{ - dAASSERT (b1 && b2); - // look through b1's neighbour list for b2 - for (dxJointNode *n=b1->firstjoint; n; n=n->next) { - if (n->body == b2) return 1; - } - return 0; -} - - -int dAreConnectedExcluding (dBodyID b1, dBodyID b2, int joint_type) -{ - dAASSERT (b1 && b2); - // look through b1's neighbour list for b2 - for (dxJointNode *n=b1->firstjoint; n; n=n->next) { - if (dJointGetType (n->joint) != joint_type && n->body == b2) return 1; - } - return 0; -} - -//**************************************************************************** -// world - -dxWorld * dWorldCreate() -{ - dxWorld *w = new dxWorld; - w->firstbody = 0; - w->firstjoint = 0; - w->nb = 0; - w->nj = 0; - dSetZero (w->gravity,4); - w->global_erp = REAL(0.2); -#if defined(dSINGLE) - w->global_cfm = 1e-5f; -#elif defined(dDOUBLE) - w->global_cfm = 1e-10; -#else - #error dSINGLE or dDOUBLE must be defined -#endif - - w->adis.linear_threshold = REAL(0.001)*REAL(0.001); // (magnitude squared) - w->adis.angular_threshold = REAL(0.001)*REAL(0.001); // (magnitude squared) - w->adis.idle_steps = 10; - w->adis.idle_time = 0; - w->adis_flag = 0; - - w->qs.num_iterations = 20; - w->qs.w = REAL(1.3); - - w->contactp.max_vel = dInfinity; - w->contactp.min_depth = 0; - - return w; -} - - -void dWorldDestroy (dxWorld *w) -{ - // delete all bodies and joints - dAASSERT (w); - dxBody *nextb, *b = w->firstbody; - while (b) { - nextb = (dxBody*) b->next; - delete b; - b = nextb; - } - dxJoint *nextj, *j = w->firstjoint; - while (j) { - nextj = (dxJoint*)j->next; - if (j->flags & dJOINT_INGROUP) { - // the joint is part of a group, so "deactivate" it instead - j->world = 0; - j->node[0].body = 0; - j->node[0].next = 0; - j->node[1].body = 0; - j->node[1].next = 0; - dMessage (0,"warning: destroying world containing grouped joints"); - } - else { - dFree (j,j->vtable->size); - } - j = nextj; - } - delete w; -} - - -void dWorldSetGravity (dWorldID w, dReal x, dReal y, dReal z) -{ - dAASSERT (w); - w->gravity[0] = x; - w->gravity[1] = y; - w->gravity[2] = z; -} - - -void dWorldGetGravity (dWorldID w, dVector3 g) -{ - dAASSERT (w); - g[0] = w->gravity[0]; - g[1] = w->gravity[1]; - g[2] = w->gravity[2]; -} - - -void dWorldSetERP (dWorldID w, dReal erp) -{ - dAASSERT (w); - w->global_erp = erp; -} - - -dReal dWorldGetERP (dWorldID w) -{ - dAASSERT (w); - return w->global_erp; -} - - -void dWorldSetCFM (dWorldID w, dReal cfm) -{ - dAASSERT (w); - w->global_cfm = cfm; -} - - -dReal dWorldGetCFM (dWorldID w) -{ - dAASSERT (w); - return w->global_cfm; -} - - -void dWorldStep (dWorldID w, dReal stepsize) -{ - dUASSERT (w,"bad world argument"); - dUASSERT (stepsize > 0,"stepsize must be > 0"); - dxProcessIslands (w,stepsize,&dInternalStepIsland); -} - - -void dWorldQuickStep (dWorldID w, dReal stepsize) -{ - dUASSERT (w,"bad world argument"); - dUASSERT (stepsize > 0,"stepsize must be > 0"); - dxProcessIslands (w,stepsize,&dxQuickStepper); -} - - -void dWorldImpulseToForce (dWorldID w, dReal stepsize, - dReal ix, dReal iy, dReal iz, - dVector3 force) -{ - dAASSERT (w); - stepsize = dRecip(stepsize); - force[0] = stepsize * ix; - force[1] = stepsize * iy; - force[2] = stepsize * iz; - // @@@ force[3] = 0; -} - - -// world auto-disable functions - -dReal dWorldGetAutoDisableLinearThreshold (dWorldID w) -{ - dAASSERT(w); - return dSqrt (w->adis.linear_threshold); -} - - -void dWorldSetAutoDisableLinearThreshold (dWorldID w, dReal linear_threshold) -{ - dAASSERT(w); - w->adis.linear_threshold = linear_threshold * linear_threshold; -} - - -dReal dWorldGetAutoDisableAngularThreshold (dWorldID w) -{ - dAASSERT(w); - return dSqrt (w->adis.angular_threshold); -} - - -void dWorldSetAutoDisableAngularThreshold (dWorldID w, dReal angular_threshold) -{ - dAASSERT(w); - w->adis.angular_threshold = angular_threshold * angular_threshold; -} - - -int dWorldGetAutoDisableSteps (dWorldID w) -{ - dAASSERT(w); - return w->adis.idle_steps; -} - - -void dWorldSetAutoDisableSteps (dWorldID w, int steps) -{ - dAASSERT(w); - w->adis.idle_steps = steps; -} - - -dReal dWorldGetAutoDisableTime (dWorldID w) -{ - dAASSERT(w); - return w->adis.idle_time; -} - - -void dWorldSetAutoDisableTime (dWorldID w, dReal time) -{ - dAASSERT(w); - w->adis.idle_time = time; -} - - -int dWorldGetAutoDisableFlag (dWorldID w) -{ - dAASSERT(w); - return w->adis_flag; -} - - -void dWorldSetAutoDisableFlag (dWorldID w, int do_auto_disable) -{ - dAASSERT(w); - w->adis_flag = (do_auto_disable != 0); -} - - -void dWorldSetQuickStepNumIterations (dWorldID w, int num) -{ - dAASSERT(w); - w->qs.num_iterations = num; -} - - -int dWorldGetQuickStepNumIterations (dWorldID w) -{ - dAASSERT(w); - return w->qs.num_iterations; -} - - -void dWorldSetQuickStepW (dWorldID w, dReal param) -{ - dAASSERT(w); - w->qs.w = param; -} - - -dReal dWorldGetQuickStepW (dWorldID w) -{ - dAASSERT(w); - return w->qs.w; -} - - -void dWorldSetContactMaxCorrectingVel (dWorldID w, dReal vel) -{ - dAASSERT(w); - w->contactp.max_vel = vel; -} - - -dReal dWorldGetContactMaxCorrectingVel (dWorldID w) -{ - dAASSERT(w); - return w->contactp.max_vel; -} - - -void dWorldSetContactSurfaceLayer (dWorldID w, dReal depth) -{ - dAASSERT(w); - w->contactp.min_depth = depth; -} - - -dReal dWorldGetContactSurfaceLayer (dWorldID w) -{ - dAASSERT(w); - return w->contactp.min_depth; -} - -//**************************************************************************** -// testing - -#define NUM 100 - -#define DO(x) - - -extern "C" void dTestDataStructures() -{ - int i; - DO(printf ("testDynamicsStuff()\n")); - - dBodyID body [NUM]; - int nb = 0; - dJointID joint [NUM]; - int nj = 0; - - for (i=0; i 0.5) { - DO(printf ("creating body\n")); - body[nb] = dBodyCreate (w); - DO(printf ("\t--> %p\n",body[nb])); - nb++; - checkWorld (w); - DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); - } - if (nj < NUM && nb > 2 && dRandReal() > 0.5) { - dBodyID b1 = body [dRand() % nb]; - dBodyID b2 = body [dRand() % nb]; - if (b1 != b2) { - DO(printf ("creating joint, attaching to %p,%p\n",b1,b2)); - joint[nj] = dJointCreateBall (w,0); - DO(printf ("\t-->%p\n",joint[nj])); - checkWorld (w); - dJointAttach (joint[nj],b1,b2); - nj++; - checkWorld (w); - DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); - } - } - if (nj > 0 && nb > 2 && dRandReal() > 0.5) { - dBodyID b1 = body [dRand() % nb]; - dBodyID b2 = body [dRand() % nb]; - if (b1 != b2) { - int k = dRand() % nj; - DO(printf ("reattaching joint %p\n",joint[k])); - dJointAttach (joint[k],b1,b2); - checkWorld (w); - DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); - } - } - if (nb > 0 && dRandReal() > 0.5) { - int k = dRand() % nb; - DO(printf ("destroying body %p\n",body[k])); - dBodyDestroy (body[k]); - checkWorld (w); - for (; k < (NUM-1); k++) body[k] = body[k+1]; - nb--; - DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); - } - if (nj > 0 && dRandReal() > 0.5) { - int k = dRand() % nj; - DO(printf ("destroying joint %p\n",joint[k])); - dJointDestroy (joint[k]); - checkWorld (w); - for (; k < (NUM-1); k++) joint[k] = joint[k+1]; - nj--; - DO(printf ("%d BODIES, %d JOINTS\n",nb,nj)); - } - } - - /* - printf ("creating world\n"); - dWorldID w = dWorldCreate(); - checkWorld (w); - printf ("creating body\n"); - dBodyID b1 = dBodyCreate (w); - checkWorld (w); - printf ("creating body\n"); - dBodyID b2 = dBodyCreate (w); - checkWorld (w); - printf ("creating joint\n"); - dJointID j = dJointCreateBall (w); - checkWorld (w); - printf ("attaching joint\n"); - dJointAttach (j,b1,b2); - checkWorld (w); - printf ("destroying joint\n"); - dJointDestroy (j); - checkWorld (w); - printf ("destroying body\n"); - dBodyDestroy (b1); - checkWorld (w); - printf ("destroying body\n"); - dBodyDestroy (b2); - checkWorld (w); - printf ("destroying world\n"); - dWorldDestroy (w); - */ -} diff --git a/Extras/ode/ode/src/odemath.cpp b/Extras/ode/ode/src/odemath.cpp deleted file mode 100644 index a75749a9c..000000000 --- a/Extras/ode/ode/src/odemath.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include - -// get some math functions under windows -#ifdef WIN32 -#include -#ifndef CYGWIN // added by andy for cygwin -#define copysign(a,b) ((dReal)_copysign(a,b)) -#endif // added by andy for cygwin -#endif - - -// this may be called for vectors `a' with extremely small magnitude, for -// example the result of a cross product on two nearly perpendicular vectors. -// we must be robust to these small vectors. to prevent numerical error, -// first find the component a[i] with the largest magnitude and then scale -// all the components by 1/a[i]. then we can compute the length of `a' and -// scale the components by 1/l. this has been verified to work with vectors -// containing the smallest representable numbers. - -void dNormalize3 (dVector3 a) -{ - dReal a0,a1,a2,aa0,aa1,aa2,l; - dAASSERT (a); - a0 = a[0]; - a1 = a[1]; - a2 = a[2]; - aa0 = dFabs(a0); - aa1 = dFabs(a1); - aa2 = dFabs(a2); - if (aa1 > aa0) { - if (aa2 > aa1) { - goto aa2_largest; - } - else { // aa1 is largest - a0 /= aa1; - a2 /= aa1; - l = dRecipSqrt (a0*a0 + a2*a2 + 1); - a[0] = a0*l; - a[1] = dCopySign(l,a1); - a[2] = a2*l; - } - } - else { - if (aa2 > aa0) { - aa2_largest: // aa2 is largest - a0 /= aa2; - a1 /= aa2; - l = dRecipSqrt (a0*a0 + a1*a1 + 1); - a[0] = a0*l; - a[1] = a1*l; - a[2] = dCopySign(l,a2); - } - else { // aa0 is largest - if (aa0 <= 0) { - // dDEBUGMSG ("vector has zero size"); ... this messace is annoying - a[0] = 1; // if all a's are zero, this is where we'll end up. - a[1] = 0; // return a default unit length vector. - a[2] = 0; - return; - } - a1 /= aa0; - a2 /= aa0; - l = dRecipSqrt (a1*a1 + a2*a2 + 1); - a[0] = dCopySign(l,a0); - a[1] = a1*l; - a[2] = a2*l; - } - } -} - - -/* OLD VERSION */ -/* -void dNormalize3 (dVector3 a) -{ - dASSERT (a); - dReal l = dDOT(a,a); - if (l > 0) { - l = dRecipSqrt(l); - a[0] *= l; - a[1] *= l; - a[2] *= l; - } - else { - a[0] = 1; - a[1] = 0; - a[2] = 0; - } -} -*/ - - -void dNormalize4 (dVector4 a) -{ - dAASSERT (a); - dReal l = dDOT(a,a)+a[3]*a[3]; - if (l > 0) { - l = dRecipSqrt(l); - a[0] *= l; - a[1] *= l; - a[2] *= l; - a[3] *= l; - } - else { - dDEBUGMSG ("vector has zero size"); - a[0] = 1; - a[1] = 0; - a[2] = 0; - a[3] = 0; - } -} - - -void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q) -{ - dAASSERT (n && p && q); - if (dFabs(n[2]) > M_SQRT1_2) { - // choose p in y-z plane - dReal a = n[1]*n[1] + n[2]*n[2]; - dReal k = dRecipSqrt (a); - p[0] = 0; - p[1] = -n[2]*k; - p[2] = n[1]*k; - // set q = n x p - q[0] = a*k; - q[1] = -n[0]*p[2]; - q[2] = n[0]*p[1]; - } - else { - // choose p in x-y plane - dReal a = n[0]*n[0] + n[1]*n[1]; - dReal k = dRecipSqrt (a); - p[0] = -n[1]*k; - p[1] = n[0]*k; - p[2] = 0; - // set q = n x p - q[0] = -n[2]*p[1]; - q[1] = n[2]*p[0]; - q[2] = a*k; - } -} diff --git a/Extras/ode/ode/src/quickstep.cpp b/Extras/ode/ode/src/quickstep.cpp deleted file mode 100644 index 6a9807b01..000000000 --- a/Extras/ode/ode/src/quickstep.cpp +++ /dev/null @@ -1,789 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include "objects.h" -#include "joint.h" -#include -#include -#include -#include -#include -#include -#include -#include "lcp.h" -#include "util.h" - -#define ALLOCA dALLOCA16 - -typedef const dReal *dRealPtr; -typedef dReal *dRealMutablePtr; -#define dRealArray(name,n) dReal name[n]; -#define dRealAllocaArray(name,n) dReal *name = (dReal*) ALLOCA ((n)*sizeof(dReal)); - -//*************************************************************************** -// configuration - -// for the SOR and CG methods: -// uncomment the following line to use warm starting. this definitely -// help for motor-driven joints. unfortunately it appears to hurt -// with high-friction contacts using the SOR method. use with care - -#define WARM_STARTING 1 - - -// for the SOR method: -// uncomment the following line to determine a new constraint-solving -// order for each iteration. however, the qsort per iteration is expensive, -// and the optimal order is somewhat problem dependent. -// @@@ try the leaf->root ordering. - -//#define REORDER_CONSTRAINTS 1 - - -// for the SOR method: -// uncomment the following line to randomly reorder constraint rows -// during the solution. depending on the situation, this can help a lot -// or hardly at all, but it doesn't seem to hurt. - -#define RANDOMLY_REORDER_CONSTRAINTS 1 - -//*************************************************************************** -// testing stuff - -#ifdef TIMING -#define IFTIMING(x) x -#else -#define IFTIMING(x) /* */ -#endif - -//*************************************************************************** -// various common computations involving the matrix J - -// compute iMJ = inv(M)*J' - -static void compute_invM_JT (int m, dRealMutablePtr J, dRealMutablePtr iMJ, int *jb, - dxBody * const *body, dRealPtr invI) -{ - int i,j; - dRealMutablePtr iMJ_ptr = iMJ; - dRealMutablePtr J_ptr = J; - for (i=0; iinvMass; - for (j=0; j<3; j++) iMJ_ptr[j] = k*J_ptr[j]; - dMULTIPLY0_331 (iMJ_ptr + 3, invI + 12*b1, J_ptr + 3); - if (b2 >= 0) { - k = body[b2]->invMass; - for (j=0; j<3; j++) iMJ_ptr[j+6] = k*J_ptr[j+6]; - dMULTIPLY0_331 (iMJ_ptr + 9, invI + 12*b2, J_ptr + 9); - } - J_ptr += 12; - iMJ_ptr += 12; - } -} - - -// compute out = inv(M)*J'*in. - -static void multiply_invM_JT (int m, int nb, dRealMutablePtr iMJ, int *jb, - dRealMutablePtr in, dRealMutablePtr out) -{ - int i,j; - dSetZero (out,6*nb); - dRealPtr iMJ_ptr = iMJ; - for (i=0; i= 0) { - out_ptr = out + b2*6; - for (j=0; j<6; j++) out_ptr[j] += iMJ_ptr[j] * in[i]; - } - iMJ_ptr += 6; - } -} - - -// compute out = J*in. - -static void multiply_J (int m, dRealMutablePtr J, int *jb, - dRealMutablePtr in, dRealMutablePtr out) -{ - int i,j; - dRealPtr J_ptr = J; - for (i=0; i= 0) { - in_ptr = in + b2*6; - for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j]; - } - J_ptr += 6; - out[i] = sum; - } -} - - -// compute out = (J*inv(M)*J' + cfm)*in. -// use z as an nb*6 temporary. - -static void multiply_J_invM_JT (int m, int nb, dRealMutablePtr J, dRealMutablePtr iMJ, int *jb, - dRealPtr cfm, dRealMutablePtr z, dRealMutablePtr in, dRealMutablePtr out) -{ - multiply_invM_JT (m,nb,iMJ,jb,in,z); - multiply_J (m,J,jb,z,out); - - // add cfm - for (int i=0; inum_iterations; - - // precompute iMJ = inv(M)*J' - dRealAllocaArray (iMJ,m*12); - compute_invM_JT (m,J,iMJ,jb,body,invI); - - dReal last_rho = 0; - dRealAllocaArray (r,m); - dRealAllocaArray (z,m); - dRealAllocaArray (p,m); - dRealAllocaArray (q,m); - - // precompute 1 / diagonals of A - dRealAllocaArray (Ad,m); - dRealPtr iMJ_ptr = iMJ; - dRealPtr J_ptr = J; - for (i=0; i= 0) { - for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; - } - iMJ_ptr += 12; - J_ptr += 12; - Ad[i] = REAL(1.0) / (sum + cfm[i]); - } - -#ifdef WARM_STARTING - // compute residual r = b - A*lambda - multiply_J_invM_JT (m,nb,J,iMJ,jb,cfm,fc,lambda,r); - for (i=0; ifindex < 0 && i2->findex >= 0) return -1; - if (i1->findex >= 0 && i2->findex < 0) return 1; - if (i1->error < i2->error) return -1; - if (i1->error > i2->error) return 1; - return 0; -} - -#endif - - -static void SOR_LCP (int m, int nb, dRealMutablePtr J, int *jb, dxBody * const *body, - dRealPtr invI, dRealMutablePtr lambda, dRealMutablePtr fc, dRealMutablePtr b, - dRealMutablePtr lo, dRealMutablePtr hi, dRealPtr cfm, int *findex, - dxQuickStepParameters *qs) -{ - const int num_iterations = qs->num_iterations; - const dReal sor_w = qs->w; // SOR over-relaxation parameter - - int i,j; - -#ifdef WARM_STARTING - // for warm starting, this seems to be necessary to prevent - // jerkiness in motor-driven joints. i have no idea why this works. - for (i=0; i= 0) { - for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; - } - iMJ_ptr += 12; - J_ptr += 12; - Ad[i] = sor_w / (sum + cfm[i]); - } - - // scale J and b by Ad - J_ptr = J; - for (i=0; i= 0) order[j++].index = i; - dIASSERT (j==m); -#endif - - for (int iteration=0; iteration < num_iterations; iteration++) { - -#ifdef REORDER_CONSTRAINTS - // constraints with findex < 0 always come first. - if (iteration < 2) { - // for the first two iterations, solve the constraints in - // the given order - for (i=0; i v2) ? v1 : v2; - if (max > 0) { - //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max; - order[i].error = dFabs(lambda[i]-last_lambda[i]); - } - else { - order[i].error = dInfinity; - } - order[i].findex = findex[i]; - order[i].index = i; - } - } - qsort (order,m,sizeof(IndexError),&compare_index_error); - - //@@@ potential optimization: swap lambda and last_lambda pointers rather - // than copying the data. we must make sure lambda is properly - // returned to the caller - memcpy (last_lambda,lambda,m*sizeof(dReal)); -#endif -#ifdef RANDOMLY_REORDER_CONSTRAINTS - if ((iteration & 7) == 0) { - for (i=1; i= 0) { - hi[index] = dFabs (hicopy[index] * lambda[findex[index]]); - lo[index] = -hi[index]; - } - - int b1 = jb[index*2]; - int b2 = jb[index*2+1]; - dReal delta = b[index] - lambda[index]*Ad[index]; - dRealMutablePtr fc_ptr = fc + 6*b1; - - // @@@ potential optimization: SIMD-ize this and the b2 >= 0 case - delta -=fc_ptr[0] * J_ptr[0] + fc_ptr[1] * J_ptr[1] + - fc_ptr[2] * J_ptr[2] + fc_ptr[3] * J_ptr[3] + - fc_ptr[4] * J_ptr[4] + fc_ptr[5] * J_ptr[5]; - // @@@ potential optimization: handle 1-body constraints in a separate - // loop to avoid the cost of test & jump? - if (b2 >= 0) { - fc_ptr = fc + 6*b2; - delta -=fc_ptr[0] * J_ptr[6] + fc_ptr[1] * J_ptr[7] + - fc_ptr[2] * J_ptr[8] + fc_ptr[3] * J_ptr[9] + - fc_ptr[4] * J_ptr[10] + fc_ptr[5] * J_ptr[11]; - } - - // compute lambda and clamp it to [lo,hi]. - // @@@ potential optimization: does SSE have clamping instructions - // to save test+jump penalties here? - dReal new_lambda = lambda[index] + delta; - if (new_lambda < lo[index]) { - delta = lo[index]-lambda[index]; - lambda[index] = lo[index]; - } - else if (new_lambda > hi[index]) { - delta = hi[index]-lambda[index]; - lambda[index] = hi[index]; - } - else { - lambda[index] = new_lambda; - } - - //@@@ a trick that may or may not help - //dReal ramp = (1-((dReal)(iteration+1)/(dReal)num_iterations)); - //delta *= ramp; - - // update fc. - // @@@ potential optimization: SIMD for this and the b2 >= 0 case - fc_ptr = fc + 6*b1; - fc_ptr[0] += delta * iMJ_ptr[0]; - fc_ptr[1] += delta * iMJ_ptr[1]; - fc_ptr[2] += delta * iMJ_ptr[2]; - fc_ptr[3] += delta * iMJ_ptr[3]; - fc_ptr[4] += delta * iMJ_ptr[4]; - fc_ptr[5] += delta * iMJ_ptr[5]; - // @@@ potential optimization: handle 1-body constraints in a separate - // loop to avoid the cost of test & jump? - if (b2 >= 0) { - fc_ptr = fc + 6*b2; - fc_ptr[0] += delta * iMJ_ptr[6]; - fc_ptr[1] += delta * iMJ_ptr[7]; - fc_ptr[2] += delta * iMJ_ptr[8]; - fc_ptr[3] += delta * iMJ_ptr[9]; - fc_ptr[4] += delta * iMJ_ptr[10]; - fc_ptr[5] += delta * iMJ_ptr[11]; - } - } - } -} - - -void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, - dxJoint * const *_joint, int nj, dReal stepsize) -{ - int i,j; - IFTIMING(dTimerStart("preprocessing");) - - dReal stepsize1 = dRecip(stepsize); - - // number all bodies in the body list - set their tag values - for (i=0; itag = i; - - // make a local copy of the joint array, because we might want to modify it. - // (the "dxJoint *const*" declaration says we're allowed to modify the joints - // but not the joint array, because the caller might need it unchanged). - //@@@ do we really need to do this? we'll be sorting constraint rows individually, not joints - dxJoint **joint = (dxJoint**) alloca (nj * sizeof(dxJoint*)); - memcpy (joint,_joint,nj * sizeof(dxJoint*)); - - // for all bodies, compute the inertia tensor and its inverse in the global - // frame, and compute the rotational force and add it to the torque - // accumulator. I and invI are a vertical stack of 3x4 matrices, one per body. - dRealAllocaArray (I,3*4*nb); // need to remember all I's for feedback purposes only - dRealAllocaArray (invI,3*4*nb); - for (i=0; imass.I,body[i]->R); - dMULTIPLY0_333 (I+i*12,body[i]->R,tmp); - // compute inverse inertia tensor in global frame - dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R); - dMULTIPLY0_333 (invI+i*12,body[i]->R,tmp); - // compute rotational force - dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel); - dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); - } - - // add the gravity force to all bodies - for (i=0; iflags & dxBodyNoGravity)==0) { - body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; - body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; - body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; - } - } - - // get joint information (m = total constraint dimension, nub = number of unbounded variables). - // joints with m=0 are inactive and are removed from the joints array - // entirely, so that the code that follows does not consider them. - //@@@ do we really need to save all the info1's - dxJoint::Info1 *info = (dxJoint::Info1*) alloca (nj*sizeof(dxJoint::Info1)); - for (i=0, j=0; jvtable->getInfo1 (joint[j],info+i); - dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); - if (info[i].m > 0) { - joint[i] = joint[j]; - i++; - } - } - nj = i; - - // create the row offset array - int m = 0; - int *ofs = (int*) alloca (nj*sizeof(int)); - for (i=0; i 0) { - // create a constraint equation right hand side vector `c', a constraint - // force mixing vector `cfm', and LCP low and high bound vectors, and an - // 'findex' vector. - dRealAllocaArray (c,m); - dRealAllocaArray (cfm,m); - dRealAllocaArray (lo,m); - dRealAllocaArray (hi,m); - int *findex = (int*) alloca (m*sizeof(int)); - dSetZero (c,m); - dSetValue (cfm,m,world->global_cfm); - dSetValue (lo,m,-dInfinity); - dSetValue (hi,m, dInfinity); - for (i=0; iglobal_erp; - for (i=0; ivtable->getInfo2 (joint[i],&Jinfo); - // adjust returned findex values for global index numbering - for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; - } - } - - // create an array of body numbers for each joint row - int *jb_ptr = jb; - for (i=0; inode[0].body) ? (joint[i]->node[0].body->tag) : -1; - int b2 = (joint[i]->node[1].body) ? (joint[i]->node[1].body->tag) : -1; - for (j=0; jinvMass; - for (j=0; j<3; j++) tmp1[i*6+j] = body[i]->facc[j] * body_invMass + body[i]->lvel[j] * stepsize1; - dMULTIPLY0_331 (tmp1 + i*6 + 3,invI + i*12,body[i]->tacc); - for (j=0; j<3; j++) tmp1[i*6+3+j] += body[i]->avel[j] * stepsize1; - } - - // put J*tmp1 into rhs - dRealAllocaArray (rhs,m); - multiply_J (m,J,jb,tmp1,rhs); - - // complete rhs - for (i=0; ilambda,info[i].m * sizeof(dReal)); - } -#endif - - // solve the LCP problem and get lambda and invM*constraint_force - IFTIMING (dTimerNow ("solving LCP problem");) - dRealAllocaArray (cforce,nb*6); - SOR_LCP (m,nb,J,jb,body,invI,lambda,cforce,rhs,lo,hi,cfm,findex,&world->qs); - -#ifdef WARM_STARTING - // save lambda for the next iteration - //@@@ note that this doesn't work for contact joints yet, as they are - // recreated every iteration - for (i=0; ilambda,lambda+ofs[i],info[i].m * sizeof(dReal)); - } -#endif - - // note that the SOR method overwrites rhs and J at this point, so - // they should not be used again. - - // add stepsize * cforce to the body velocity - for (i=0; ilvel[j] += stepsize * cforce[i*6+j]; - for (j=0; j<3; j++) body[i]->avel[j] += stepsize * cforce[i*6+3+j]; - } - - // if joint feedback is requested, compute the constraint force. - // BUT: cforce is inv(M)*J'*lambda, whereas we want just J'*lambda, - // so we must compute M*cforce. - // @@@ if any joint has a feedback request we compute the entire - // adjusted cforce, which is not the most efficient way to do it. - for (j=0; jfeedback) { - // compute adjusted cforce - for (i=0; imass.mass; - cforce [i*6+0] *= k; - cforce [i*6+1] *= k; - cforce [i*6+2] *= k; - dVector3 tmp; - dMULTIPLY0_331 (tmp, I + 12*i, cforce + i*6 + 3); - cforce [i*6+3] = tmp[0]; - cforce [i*6+4] = tmp[1]; - cforce [i*6+5] = tmp[2]; - } - // compute feedback for this and all remaining joints - for (; jfeedback; - if (fb) { - int b1 = joint[j]->node[0].body->tag; - memcpy (fb->f1,cforce+b1*6,3*sizeof(dReal)); - memcpy (fb->t1,cforce+b1*6+3,3*sizeof(dReal)); - if (joint[j]->node[1].body) { - int b2 = joint[j]->node[1].body->tag; - memcpy (fb->f2,cforce+b2*6,3*sizeof(dReal)); - memcpy (fb->t2,cforce+b2*6+3,3*sizeof(dReal)); - } - } - } - } - } - } - - // compute the velocity update: - // add stepsize * invM * fe to the body velocity - - IFTIMING (dTimerNow ("compute velocity update");) - for (i=0; iinvMass; - for (j=0; j<3; j++) body[i]->lvel[j] += stepsize * body_invMass * body[i]->facc[j]; - for (j=0; j<3; j++) body[i]->tacc[j] *= stepsize; - dMULTIPLYADD0_331 (body[i]->avel,invI + i*12,body[i]->tacc); - } - -#if 0 - // check that the updated velocity obeys the constraint (this check needs unmodified J) - dRealAllocaArray (vel,nb*6); - for (i=0; ilvel[j]; - for (j=0; j<3; j++) vel[i*6+3+j] = body[i]->avel[j]; - } - dRealAllocaArray (tmp,m); - multiply_J (m,J,jb,vel,tmp); - dReal error = 0; - for (i=0; ifacc,3); - dSetZero (body[i]->tacc,3); - } - - IFTIMING (dTimerEnd();) - IFTIMING (if (m > 0) dTimerReport (stdout,1);) -} diff --git a/Extras/ode/ode/src/quickstep.h b/Extras/ode/ode/src/quickstep.h deleted file mode 100644 index 43863e775..000000000 --- a/Extras/ode/ode/src/quickstep.h +++ /dev/null @@ -1,33 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_QUICK_STEP_H_ -#define _ODE_QUICK_STEP_H_ - -#include - - -void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, - dxJoint * const *_joint, int nj, dReal stepsize); - - -#endif diff --git a/Extras/ode/ode/src/rotation.cpp b/Extras/ode/ode/src/rotation.cpp deleted file mode 100644 index 1180e6d99..000000000 --- a/Extras/ode/ode/src/rotation.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -quaternions have the format: (s,vx,vy,vz) where (vx,vy,vz) is the -"rotation axis" and s is the "rotation angle". - -*/ - -#include -#include - - -#define _R(i,j) R[(i)*4+(j)] - -#define SET_3x3_IDENTITY \ - _R(0,0) = REAL(1.0); \ - _R(0,1) = REAL(0.0); \ - _R(0,2) = REAL(0.0); \ - _R(0,3) = REAL(0.0); \ - _R(1,0) = REAL(0.0); \ - _R(1,1) = REAL(1.0); \ - _R(1,2) = REAL(0.0); \ - _R(1,3) = REAL(0.0); \ - _R(2,0) = REAL(0.0); \ - _R(2,1) = REAL(0.0); \ - _R(2,2) = REAL(1.0); \ - _R(2,3) = REAL(0.0); - - -void dRSetIdentity (dMatrix3 R) -{ - dAASSERT (R); - SET_3x3_IDENTITY; -} - - -void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, - dReal angle) -{ - dAASSERT (R); - dQuaternion q; - dQFromAxisAndAngle (q,ax,ay,az,angle); - dQtoR (q,R); -} - - -void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi) -{ - dReal sphi,cphi,stheta,ctheta,spsi,cpsi; - dAASSERT (R); - sphi = dSin(phi); - cphi = dCos(phi); - stheta = dSin(theta); - ctheta = dCos(theta); - spsi = dSin(psi); - cpsi = dCos(psi); - _R(0,0) = cpsi*ctheta; - _R(0,1) = spsi*ctheta; - _R(0,2) =-stheta; - _R(1,0) = cpsi*stheta*sphi - spsi*cphi; - _R(1,1) = spsi*stheta*sphi + cpsi*cphi; - _R(1,2) = ctheta*sphi; - _R(2,0) = cpsi*stheta*cphi + spsi*sphi; - _R(2,1) = spsi*stheta*cphi - cpsi*sphi; - _R(2,2) = ctheta*cphi; -} - - -void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, - dReal bx, dReal by, dReal bz) -{ - dReal l,k; - dAASSERT (R); - l = dSqrt (ax*ax + ay*ay + az*az); - if (l <= REAL(0.0)) { - dDEBUGMSG ("zero length vector"); - return; - } - l = dRecip(l); - ax *= l; - ay *= l; - az *= l; - k = ax*bx + ay*by + az*bz; - bx -= k*ax; - by -= k*ay; - bz -= k*az; - l = dSqrt (bx*bx + by*by + bz*bz); - if (l <= REAL(0.0)) { - dDEBUGMSG ("zero length vector"); - return; - } - l = dRecip(l); - bx *= l; - by *= l; - bz *= l; - _R(0,0) = ax; - _R(1,0) = ay; - _R(2,0) = az; - _R(0,1) = bx; - _R(1,1) = by; - _R(2,1) = bz; - _R(0,2) = - by*az + ay*bz; - _R(1,2) = - bz*ax + az*bx; - _R(2,2) = - bx*ay + ax*by; -} - - -void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az) -{ - dVector3 n,p,q; - n[0] = ax; - n[1] = ay; - n[2] = az; - dNormalize3 (n); - dPlaneSpace (n,p,q); - _R(0,0) = p[0]; - _R(1,0) = p[1]; - _R(2,0) = p[2]; - _R(0,1) = q[0]; - _R(1,1) = q[1]; - _R(2,1) = q[2]; - _R(0,2) = n[0]; - _R(1,2) = n[1]; - _R(2,2) = n[2]; -} - - -void dQSetIdentity (dQuaternion q) -{ - dAASSERT (q); - q[0] = 1; - q[1] = 0; - q[2] = 0; - q[3] = 0; -} - - -void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, - dReal angle) -{ - dAASSERT (q); - dReal l = ax*ax + ay*ay + az*az; - if (l > REAL(0.0)) { - angle *= REAL(0.5); - q[0] = dCos (angle); - l = dSin(angle) * dRecipSqrt(l); - q[1] = ax*l; - q[2] = ay*l; - q[3] = az*l; - } - else { - q[0] = 1; - q[1] = 0; - q[2] = 0; - q[3] = 0; - } -} - - -void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) -{ - dAASSERT (qa && qb && qc); - qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; - qa[1] = qb[0]*qc[1] + qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; - qa[2] = qb[0]*qc[2] + qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; - qa[3] = qb[0]*qc[3] + qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; -} - - -void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) -{ - dAASSERT (qa && qb && qc); - qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3]; - qa[1] = qb[0]*qc[1] - qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2]; - qa[2] = qb[0]*qc[2] - qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3]; - qa[3] = qb[0]*qc[3] - qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1]; -} - - -void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) -{ - dAASSERT (qa && qb && qc); - qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3]; - qa[1] = -qb[0]*qc[1] + qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2]; - qa[2] = -qb[0]*qc[2] + qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3]; - qa[3] = -qb[0]*qc[3] + qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1]; -} - - -void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc) -{ - dAASSERT (qa && qb && qc); - qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3]; - qa[1] = -qb[0]*qc[1] - qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2]; - qa[2] = -qb[0]*qc[2] - qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3]; - qa[3] = -qb[0]*qc[3] - qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1]; -} - - -// dRfromQ(), dQfromR() and dDQfromW() are derived from equations in "An Introduction -// to Physically Based Modeling: Rigid Body Simulation - 1: Unconstrained -// Rigid Body Dynamics" by David Baraff, Robotics Institute, Carnegie Mellon -// University, 1997. - -void dRfromQ (dMatrix3 R, const dQuaternion q) -{ - dAASSERT (q && R); - // q = (s,vx,vy,vz) - dReal qq1 = 2*q[1]*q[1]; - dReal qq2 = 2*q[2]*q[2]; - dReal qq3 = 2*q[3]*q[3]; - _R(0,0) = 1 - qq2 - qq3; - _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]); - _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]); - _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]); - _R(1,1) = 1 - qq1 - qq3; - _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]); - _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]); - _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]); - _R(2,2) = 1 - qq1 - qq2; -} - - -void dQfromR (dQuaternion q, const dMatrix3 R) -{ - dAASSERT (q && R); - dReal tr,s; - tr = _R(0,0) + _R(1,1) + _R(2,2); - if (tr >= 0) { - s = dSqrt (tr + 1); - q[0] = REAL(0.5) * s; - s = REAL(0.5) * dRecip(s); - q[1] = (_R(2,1) - _R(1,2)) * s; - q[2] = (_R(0,2) - _R(2,0)) * s; - q[3] = (_R(1,0) - _R(0,1)) * s; - } - else { - // find the largest diagonal element and jump to the appropriate case - if (_R(1,1) > _R(0,0)) { - if (_R(2,2) > _R(1,1)) goto case_2; - goto case_1; - } - if (_R(2,2) > _R(0,0)) goto case_2; - goto case_0; - - case_0: - s = dSqrt((_R(0,0) - (_R(1,1) + _R(2,2))) + 1); - q[1] = REAL(0.5) * s; - s = REAL(0.5) * dRecip(s); - q[2] = (_R(0,1) + _R(1,0)) * s; - q[3] = (_R(2,0) + _R(0,2)) * s; - q[0] = (_R(2,1) - _R(1,2)) * s; - return; - - case_1: - s = dSqrt((_R(1,1) - (_R(2,2) + _R(0,0))) + 1); - q[2] = REAL(0.5) * s; - s = REAL(0.5) * dRecip(s); - q[3] = (_R(1,2) + _R(2,1)) * s; - q[1] = (_R(0,1) + _R(1,0)) * s; - q[0] = (_R(0,2) - _R(2,0)) * s; - return; - - case_2: - s = dSqrt((_R(2,2) - (_R(0,0) + _R(1,1))) + 1); - q[3] = REAL(0.5) * s; - s = REAL(0.5) * dRecip(s); - q[1] = (_R(2,0) + _R(0,2)) * s; - q[2] = (_R(1,2) + _R(2,1)) * s; - q[0] = (_R(1,0) - _R(0,1)) * s; - return; - } -} - - -void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q) -{ - dAASSERT (w && q && dq); - dq[0] = REAL(0.5)*(- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]); - dq[1] = REAL(0.5)*( w[0]*q[0] + w[1]*q[3] - w[2]*q[2]); - dq[2] = REAL(0.5)*(- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]); - dq[3] = REAL(0.5)*( w[0]*q[2] - w[1]*q[1] + w[2]*q[0]); -} diff --git a/Extras/ode/ode/src/scrapbook.cpp b/Extras/ode/ode/src/scrapbook.cpp deleted file mode 100644 index 2621814c9..000000000 --- a/Extras/ode/ode/src/scrapbook.cpp +++ /dev/null @@ -1,485 +0,0 @@ - -/* - -this is code that was once useful but has now been obseleted. - -this file should not be compiled as part of ODE! - -*/ - -//*************************************************************************** -// intersect a line segment with a plane - -extern "C" int dClipLineToBox (const dVector3 p1, const dVector3 p2, - const dVector3 p, const dMatrix3 R, - const dVector3 side) -{ - // compute the start and end of the line (p1 and p2) relative to the box. - // we will do all subsequent computations in this box-relative coordinate - // system. we have to do a translation and rotation for each point. - dVector3 tmp,s,e; - tmp[0] = p1[0] - p[0]; - tmp[1] = p1[1] - p[1]; - tmp[2] = p1[2] - p[2]; - dMULTIPLY1_331 (s,R,tmp); - tmp[0] = p2[0] - p[0]; - tmp[1] = p2[1] - p[1]; - tmp[2] = p2[2] - p[2]; - dMULTIPLY1_331 (e,R,tmp); - - // compute the vector 'v' from the start point to the end point - dVector3 v; - v[0] = e[0] - s[0]; - v[1] = e[1] - s[1]; - v[2] = e[2] - s[2]; - - // a point on the line is defined by the parameter 't'. t=0 corresponds - // to the start of the line, t=1 corresponds to the end of the line. - // we will clip the line to the box by finding the range of t where a - // point on the line is inside the box. the currently known bounds for - // t and tlo..thi. - dReal tlo=0,thi=1; - - // clip in the X/Y/Z direction - for (int i=0; i<3; i++) { - // first adjust s,e for the current t range. this is redundant for the - // first iteration, but never mind. - e[i] = s[i] + thi*v[i]; - s[i] = s[i] + tlo*v[i]; - // compute where t intersects the positive and negative sides. - dReal tp = ( side[i] - s[i])/v[i]; // @@@ handle case where denom=0 - dReal tm = (-side[i] - s[i])/v[i]; - // handle 9 intersection cases - if (s[i] <= -side[i]) { - tlo = tm; - if (e[i] <= -side[i]) return 0; - else if (e[i] >= side[i]) thi = tp; - } - else if (s[i] <= side[i]) { - if (e[i] <= -side[i]) thi = tm; - else if (e[i] >= side[i]) thi = tp; - } - else { - tlo = tp; - if (e[i] <= -side[i]) thi = tm; - else if (e[i] >= side[i]) return 0; - } - } - - //... @@@ AT HERE @@@ - - return 1; -} - - -//*************************************************************************** -// a nice try at C-B collision. unfortunately it doesn't work. the logic -// for testing for line-box intersection is correct, but unfortunately the -// closest-point distance estimates are often too large. as a result contact -// points are placed incorrectly. - - -int dCollideCB (const dxGeom *o1, const dxGeom *o2, int flags, - dContactGeom *contact, int skip) -{ - int i; - - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->_class->num == dCCylinderClass); - dIASSERT (o2->_class->num == dBoxClass); - contact->g1 = const_cast (o1); - contact->g2 = const_cast (o2); - dxCCylinder *cyl = (dxCCylinder*) CLASSDATA(o1); - dxBox *box = (dxBox*) CLASSDATA(o2); - - // get p1,p2 = cylinder axis endpoints, get radius - dVector3 p1,p2; - dReal clen = cyl->lz * REAL(0.5); - p1[0] = o1->pos[0] + clen * o1->R[2]; - p1[1] = o1->pos[1] + clen * o1->R[6]; - p1[2] = o1->pos[2] + clen * o1->R[10]; - p2[0] = o1->pos[0] - clen * o1->R[2]; - p2[1] = o1->pos[1] - clen * o1->R[6]; - p2[2] = o1->pos[2] - clen * o1->R[10]; - dReal radius = cyl->radius; - - // copy out box center, rotation matrix, and side array - dReal *c = o2->pos; - dReal *R = o2->R; - dReal *side = box->side; - - // compute the start and end of the line (p1 and p2) relative to the box. - // we will do all subsequent computations in this box-relative coordinate - // system. we have to do a translation and rotation for each point. - dVector3 tmp3,s,e; - tmp3[0] = p1[0] - c[0]; - tmp3[1] = p1[1] - c[1]; - tmp3[2] = p1[2] - c[2]; - dMULTIPLY1_331 (s,R,tmp3); - tmp3[0] = p2[0] - c[0]; - tmp3[1] = p2[1] - c[1]; - tmp3[2] = p2[2] - c[2]; - dMULTIPLY1_331 (e,R,tmp3); - - // compute the vector 'v' from the start point to the end point - dVector3 v; - v[0] = e[0] - s[0]; - v[1] = e[1] - s[1]; - v[2] = e[2] - s[2]; - - // compute the half-sides of the box - dReal S0 = side[0] * REAL(0.5); - dReal S1 = side[1] * REAL(0.5); - dReal S2 = side[2] * REAL(0.5); - - // compute the size of the bounding box around the line segment - dReal B0 = dFabs (v[0]); - dReal B1 = dFabs (v[1]); - dReal B2 = dFabs (v[2]); - - // for all 6 separation axes, measure the penetration depth. if any depth is - // less than 0 then the objects don't penetrate at all so we can just - // return 0. find the axis with the smallest depth, and record its normal. - - // note: normalR is set to point to a column of R if that is the smallest - // depth normal so far. otherwise normalR is 0 and normalC is set to a - // vector relative to the box. invert_normal is 1 if the sign of the normal - // should be flipped. - - dReal depth,trial_depth,tmp,length; - const dReal *normalR=0; - dVector3 normalC; - int invert_normal = 0; - int code = 0; // 0=no contact, 1-3=face contact, 4-6=edge contact - - depth = dInfinity; - - // look at face-normal axes - -#undef TEST -#define TEST(center,depth_expr,norm,contact_code) \ - tmp = (center); \ - trial_depth = radius + REAL(0.5) * ((depth_expr) - dFabs(tmp)); \ - if (trial_depth < 0) return 0; \ - if (trial_depth < depth) { \ - depth = trial_depth; \ - normalR = (norm); \ - invert_normal = (tmp < 0); \ - code = contact_code; \ - } - - TEST (s[0]+e[0], side[0] + B0, R+0, 1); - TEST (s[1]+e[1], side[1] + B1, R+1, 2); - TEST (s[2]+e[2], side[2] + B2, R+2, 3); - - // look at v x box-edge axes - -#undef TEST -#define TEST(box_radius,line_offset,nx,ny,nz,contact_code) \ - tmp = (line_offset); \ - trial_depth = (box_radius) - dFabs(tmp); \ - length = dSqrt ((nx)*(nx) + (ny)*(ny) + (nz)*(nz)); \ - if (length > 0) { \ - length = dRecip(length); \ - trial_depth = trial_depth * length + radius; \ - if (trial_depth < 0) return 0; \ - if (trial_depth < depth) { \ - depth = trial_depth; \ - normalR = 0; \ - normalC[0] = (nx)*length; \ - normalC[1] = (ny)*length; \ - normalC[2] = (nz)*length; \ - invert_normal = (tmp < 0); \ - code = contact_code; \ - } \ - } - - TEST (B2*S1+B1*S2,v[1]*s[2]-v[2]*s[1], 0,-v[2],v[1], 4); - TEST (B2*S0+B0*S2,v[2]*s[0]-v[0]*s[2], v[2],0,-v[0], 5); - TEST (B1*S0+B0*S1,v[0]*s[1]-v[1]*s[0], -v[1],v[0],0, 6); - -#undef TEST - - // if we get to this point, the box and ccylinder interpenetrate. - // compute the normal in global coordinates. - dReal *normal = contact[0].normal; - if (normalR) { - normal[0] = normalR[0]; - normal[1] = normalR[4]; - normal[2] = normalR[8]; - } - else { - dMULTIPLY0_331 (normal,R,normalC); - } - if (invert_normal) { - normal[0] = -normal[0]; - normal[1] = -normal[1]; - normal[2] = -normal[2]; - } - - // set the depth - contact[0].depth = depth; - - if (code == 0) { - return 0; // should never get here - } - else if (code >= 4) { - // handle edge contacts - // find an endpoint q1 on the intersecting edge of the box - dVector3 q1; - dReal sign[3]; - for (i=0; i<3; i++) q1[i] = c[i]; - sign[0] = (dDOT14(normal,R+0) > 0) ? REAL(1.0) : REAL(-1.0); - for (i=0; i<3; i++) q1[i] += sign[0] * S0 * R[i*4]; - sign[1] = (dDOT14(normal,R+1) > 0) ? REAL(1.0) : REAL(-1.0); - for (i=0; i<3; i++) q1[i] += sign[1] * S1 * R[i*4+1]; - sign[2] = (dDOT14(normal,R+2) > 0) ? REAL(1.0) : REAL(-1.0); - for (i=0; i<3; i++) q1[i] += sign[2] * S2 * R[i*4+2]; - - // find the other endpoint q2 of the intersecting edge - dVector3 q2; - for (i=0; i<3; i++) - q2[i] = q1[i] - R[code-4 + i*4] * (sign[code-4] * side[code-4]); - - // determine the closest point between the box edge and the line segment - dVector3 cp1,cp2; - dClosestLineSegmentPoints (q1,q2, p1,p2, cp1,cp2); - for (i=0; i<3; i++) contact[0].pos[i] = cp1[i] - REAL(0.5)*normal[i]*depth; - return 1; - } - else { - // handle face contacts. - // @@@ temporary: make deepest vertex on the line the contact point. - // @@@ this kind of works, but we sometimes need two contact points for - // @@@ stability. - - // compute 'v' in global coordinates - dVector3 gv; - for (i=0; i<3; i++) gv[i] = p2[i] - p1[i]; - - if (dDOT (normal,gv) > 0) { - for (i=0; i<3; i++) - contact[0].pos[i] = p1[i] + (depth*REAL(0.5)-radius)*normal[i]; - } - else { - for (i=0; i<3; i++) - contact[0].pos[i] = p2[i] + (depth*REAL(0.5)-radius)*normal[i]; - } - return 1; - } -} - -//*************************************************************************** -// this function works, it's just not being used for anything at the moment: - -// given a box (R,side), `R' is the rotation matrix for the box, and `side' -// is a vector of x/y/z side lengths, return the size of the interval of the -// box projected along the given axis. if the axis has unit length then the -// return value will be the actual diameter, otherwise the result will be -// scaled by the axis length. - -static inline dReal boxDiameter (const dMatrix3 R, const dVector3 side, - const dVector3 axis) -{ - dVector3 q; - dMULTIPLY1_331 (q,R,axis); // transform axis to body-relative - return dFabs(q[0])*side[0] + dFabs(q[1])*side[1] + dFabs(q[2])*side[2]; -} - -//*************************************************************************** -// the old capped cylinder to capped cylinder collision code. this fails to -// detect cap-to-cap contact points when the cylinder axis are aligned, but -// other that that it is pretty robust. - -// this returns at most one contact point when the two cylinder's axes are not -// aligned, and at most two (for stability) when they are aligned. -// the algorithm minimizes the distance between two "sample spheres" that are -// positioned along the cylinder axes according to: -// sphere1 = pos1 + alpha1 * axis1 -// sphere2 = pos2 + alpha2 * axis2 -// alpha1 and alpha2 are limited to +/- half the length of the cylinders. -// the algorithm works by finding a solution that has both alphas free, or -// a solution that has one or both alphas fixed to the ends of the cylinder. - -int dCollideCCylinderCCylinder (dxGeom *o1, dxGeom *o2, - int flags, dContactGeom *contact, int skip) -{ - int i; - const dReal tolerance = REAL(1e-5); - - dIASSERT (skip >= (int)sizeof(dContactGeom)); - dIASSERT (o1->type == dCCylinderClass); - dIASSERT (o2->type == dCCylinderClass); - dxCCylinder *cyl1 = (dxCCylinder*) o1; - dxCCylinder *cyl2 = (dxCCylinder*) o2; - - contact->g1 = o1; - contact->g2 = o2; - - // copy out some variables, for convenience - dReal lz1 = cyl1->lz * REAL(0.5); - dReal lz2 = cyl2->lz * REAL(0.5); - dReal *pos1 = o1->pos; - dReal *pos2 = o2->pos; - dReal axis1[3],axis2[3]; - axis1[0] = o1->R[2]; - axis1[1] = o1->R[6]; - axis1[2] = o1->R[10]; - axis2[0] = o2->R[2]; - axis2[1] = o2->R[6]; - axis2[2] = o2->R[10]; - - dReal alpha1,alpha2,sphere1[3],sphere2[3]; - int fix1 = 0; // 0 if alpha1 is free, +/-1 to fix at +/- lz1 - int fix2 = 0; // 0 if alpha2 is free, +/-1 to fix at +/- lz2 - - for (int count=0; count<9; count++) { - // find a trial solution by fixing or not fixing the alphas - if (fix1) { - if (fix2) { - // alpha1 and alpha2 are fixed, so the solution is easy - if (fix1 > 0) alpha1 = lz1; else alpha1 = -lz1; - if (fix2 > 0) alpha2 = lz2; else alpha2 = -lz2; - for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; - } - else { - // fix alpha1 but let alpha2 be free - if (fix1 > 0) alpha1 = lz1; else alpha1 = -lz1; - for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; - alpha2 = (axis2[0]*(sphere1[0]-pos2[0]) + - axis2[1]*(sphere1[1]-pos2[1]) + - axis2[2]*(sphere1[2]-pos2[2])); - for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; - } - } - else { - if (fix2) { - // fix alpha2 but let alpha1 be free - if (fix2 > 0) alpha2 = lz2; else alpha2 = -lz2; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; - alpha1 = (axis1[0]*(sphere2[0]-pos1[0]) + - axis1[1]*(sphere2[1]-pos1[1]) + - axis1[2]*(sphere2[2]-pos1[2])); - for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; - } - else { - // let alpha1 and alpha2 be free - // compute determinant of d(d^2)\d(alpha) jacobian - dReal a1a2 = dDOT (axis1,axis2); - dReal det = REAL(1.0)-a1a2*a1a2; - if (det < tolerance) { - // the cylinder axes (almost) parallel, so we will generate up to two - // contacts. the solution matrix is rank deficient so alpha1 and - // alpha2 are related by: - // alpha2 = alpha1 + (pos1-pos2)'*axis1 (if axis1==axis2) - // or alpha2 = -(alpha1 + (pos1-pos2)'*axis1) (if axis1==-axis2) - // first compute where the two cylinders overlap in alpha1 space: - if (a1a2 < 0) { - axis2[0] = -axis2[0]; - axis2[1] = -axis2[1]; - axis2[2] = -axis2[2]; - } - dReal q[3]; - for (i=0; i<3; i++) q[i] = pos1[i]-pos2[i]; - dReal k = dDOT (axis1,q); - dReal a1lo = -lz1; - dReal a1hi = lz1; - dReal a2lo = -lz2 - k; - dReal a2hi = lz2 - k; - dReal lo = (a1lo > a2lo) ? a1lo : a2lo; - dReal hi = (a1hi < a2hi) ? a1hi : a2hi; - if (lo <= hi) { - int num_contacts = flags & NUMC_MASK; - if (num_contacts >= 2 && lo < hi) { - // generate up to two contacts. if one of those contacts is - // not made, fall back on the one-contact strategy. - for (i=0; i<3; i++) sphere1[i] = pos1[i] + lo*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + (lo+k)*axis2[i]; - int n1 = dCollideSpheres (sphere1,cyl1->radius, - sphere2,cyl2->radius,contact); - if (n1) { - for (i=0; i<3; i++) sphere1[i] = pos1[i] + hi*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + (hi+k)*axis2[i]; - dContactGeom *c2 = CONTACT(contact,skip); - int n2 = dCollideSpheres (sphere1,cyl1->radius, - sphere2,cyl2->radius, c2); - if (n2) { - c2->g1 = o1; - c2->g2 = o2; - return 2; - } - } - } - - // just one contact to generate, so put it in the middle of - // the range - alpha1 = (lo + hi) * REAL(0.5); - alpha2 = alpha1 + k; - for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; - return dCollideSpheres (sphere1,cyl1->radius, - sphere2,cyl2->radius,contact); - } - else return 0; - } - det = REAL(1.0)/det; - dReal delta[3]; - for (i=0; i<3; i++) delta[i] = pos1[i] - pos2[i]; - dReal q1 = dDOT (delta,axis1); - dReal q2 = dDOT (delta,axis2); - alpha1 = det*(a1a2*q2-q1); - alpha2 = det*(q2-a1a2*q1); - for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i]; - for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i]; - } - } - - // if the alphas are outside their allowed ranges then fix them and - // try again - if (fix1==0) { - if (alpha1 < -lz1) { - fix1 = -1; - continue; - } - if (alpha1 > lz1) { - fix1 = 1; - continue; - } - } - if (fix2==0) { - if (alpha2 < -lz2) { - fix2 = -1; - continue; - } - if (alpha2 > lz2) { - fix2 = 1; - continue; - } - } - - // unfix the alpha variables if the local distance gradient indicates - // that we are not yet at the minimum - dReal tmp[3]; - for (i=0; i<3; i++) tmp[i] = sphere1[i] - sphere2[i]; - if (fix1) { - dReal gradient = dDOT (tmp,axis1); - if ((fix1 > 0 && gradient > 0) || (fix1 < 0 && gradient < 0)) { - fix1 = 0; - continue; - } - } - if (fix2) { - dReal gradient = -dDOT (tmp,axis2); - if ((fix2 > 0 && gradient > 0) || (fix2 < 0 && gradient < 0)) { - fix2 = 0; - continue; - } - } - return dCollideSpheres (sphere1,cyl1->radius,sphere2,cyl2->radius,contact); - } - // if we go through the loop too much, then give up. we should NEVER get to - // this point (i hope). - dMessage (0,"dCollideCC(): too many iterations"); - return 0; -} diff --git a/Extras/ode/ode/src/stack.cpp b/Extras/ode/ode/src/stack.cpp deleted file mode 100644 index e062f92b5..000000000 --- a/Extras/ode/ode/src/stack.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -@@@ this file should not be compiled any more @@@ - -#include -#include -#include "stack.h" -#include "ode/error.h" -#include "ode/config.h" - -//**************************************************************************** -// unix version that uses mmap(). some systems have anonymous mmaps and some -// need to mmap /dev/zero. - -#ifndef WIN32 - -#include -#include -#include -#include -#include - - -void dStack::init (int max_size) -{ - if (sizeof(long int) != sizeof(char*)) dDebug (0,"internal"); - if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0"); - -#ifndef MMAP_ANONYMOUS - static int dev_zero_fd = -1; // cached file descriptor for /dev/zero - if (dev_zero_fd < 0) dev_zero_fd = open ("/dev/zero", O_RDWR); - if (dev_zero_fd < 0) dError (0,"can't open /dev/zero (%s)",strerror(errno)); - base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, - dev_zero_fd,0); -#else - base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON,0,0); -#endif - - if (int(base) == -1) dError (0,"Stack::init(), mmap() failed, " - "max_size=%d (%s)",max_size,strerror(errno)); - size = max_size; - pointer = base; - frame = 0; -} - - -void dStack::destroy() -{ - munmap (base,size); - base = 0; - size = 0; - pointer = 0; - frame = 0; -} - -#endif - -//**************************************************************************** - -#ifdef WIN32 - -#include "windows.h" - - -void dStack::init (int max_size) -{ - if (sizeof(LPVOID) != sizeof(char*)) dDebug (0,"internal"); - if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0"); - base = (char*) VirtualAlloc (NULL,max_size,MEM_RESERVE,PAGE_READWRITE); - if (base == 0) dError (0,"Stack::init(), VirtualAlloc() failed, " - "max_size=%d",max_size); - size = max_size; - pointer = base; - frame = 0; - committed = 0; - - // get page size - SYSTEM_INFO info; - GetSystemInfo (&info); - pagesize = info.dwPageSize; -} - - -void dStack::destroy() -{ - VirtualFree (base,0,MEM_RELEASE); - base = 0; - size = 0; - pointer = 0; - frame = 0; -} - -#endif diff --git a/Extras/ode/ode/src/stack.h b/Extras/ode/ode/src/stack.h deleted file mode 100644 index 5afff41a1..000000000 --- a/Extras/ode/ode/src/stack.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* this comes from the `reuse' library. copy any changes back to the source. - -these stack allocation functions are a replacement for alloca(), except that -they allocate memory from a separate pool. - -advantages over alloca(): - - consecutive allocations are guaranteed to be contiguous with increasing - address. - - functions can allocate stack memory that is returned to the caller, - in other words pushing and popping stack frames is optional. - -disadvantages compared to alloca(): - - less portable - - slightly slower, although still orders of magnitude faster than malloc(). - - longjmp() and exceptions do not deallocate stack memory (but who cares?). - -just like alloca(): - - using too much stack memory does not fail gracefully, it fails with a - segfault. - -*/ - - -#ifndef _ODE_STACK_H_ -#define _ODE_STACK_H_ - - -#ifdef WIN32 -#include "windows.h" -#endif - - -struct dStack { - char *base; // bottom of the stack - int size; // maximum size of the stack - char *pointer; // current top of the stack - char *frame; // linked list of stack frame ptrs -# ifdef WIN32 // stuff for windows: - int pagesize; // - page size - this is ASSUMED to be a power of 2 - int committed; // - bytes committed in allocated region -#endif - - // initialize the stack. `max_size' is the maximum size that the stack can - // reach. on unix and windows a `virtual' memory block of this size is - // mapped into the address space but does not actually consume physical - // memory until it is referenced - so it is safe to set this to a high value. - - void init (int max_size); - - - // destroy the stack. this unmaps any virtual memory that was allocated. - - void destroy(); - - - // allocate `size' bytes from the stack and return a pointer to the allocated - // memory. `size' must be >= 0. the returned pointer will be aligned to the - // size of a long int. - - char * alloc (int size) - { - char *ret = pointer; - pointer += ((size-1) | (sizeof(long int)-1) )+1; -# ifdef WIN32 - // for windows we need to commit pages as they are required - if ((pointer-base) > committed) { - committed = ((pointer-base-1) | (pagesize-1))+1; // round up to pgsize - VirtualAlloc (base,committed,MEM_COMMIT,PAGE_READWRITE); - } -# endif - return ret; - } - - - // return the address that will be returned by the next call to alloc() - - char *nextAlloc() - { - return pointer; - } - - - // push and pop the current size of the stack. pushFrame() saves the current - // frame pointer on the stack, and popFrame() retrieves it. a typical - // stack-using function will bracket alloc() calls with pushFrame() and - // popFrame(). both functions return the current stack pointer - this should - // be the same value for the two bracketing calls. calling popFrame() too - // many times will result in a segfault. - - char * pushFrame() - { - char *newframe = pointer; - char **addr = (char**) alloc (sizeof(char*)); - *addr = frame; - frame = newframe; - return newframe; - - /* OLD CODE - *((char**)pointer) = frame; - frame = pointer; - char *ret = pointer; - pointer += sizeof(char*); - return ret; - */ - } - - char * popFrame() - { - pointer = frame; - frame = *((char**)pointer); - return pointer; - } -}; - - -#endif diff --git a/Extras/ode/ode/src/step.cpp b/Extras/ode/ode/src/step.cpp deleted file mode 100644 index 247a755d3..000000000 --- a/Extras/ode/ode/src/step.cpp +++ /dev/null @@ -1,1786 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include "objects.h" -#include "joint.h" -#include -#include -#include -#include -#include -#include -#include "lcp.h" -#include "util.h" - -//**************************************************************************** -// misc defines - -#define FAST_FACTOR -//#define TIMING - -// memory allocation system -#ifdef dUSE_MALLOC_FOR_ALLOCA -unsigned int dMemoryFlag; -#define REPORT_OUT_OF_MEMORY fprintf(stderr, "Insufficient memory to complete rigid body simulation. Results will not be accurate.\n") - -#define ALLOCA(t,v,s) t* v=(t*)malloc(s) -#define UNALLOCA(t) free(t) - -#else -#define ALLOCA(t,v,s) t* v=(t*)dALLOCA16(s) -#define UNALLOCA(t) /* nothing */ -#endif - - -//**************************************************************************** -// debugging - comparison of various vectors and matrices produced by the -// slow and fast versions of the stepper. - -//#define COMPARE_METHODS - -#ifdef COMPARE_METHODS -#include "testing.h" -dMatrixComparison comparator; -#endif - -// undef to use the fast decomposition -#define DIRECT_CHOLESKY -#undef REPORT_ERROR - -//**************************************************************************** -// special matrix multipliers - -// this assumes the 4th and 8th rows of B and C are zero. - -static void Multiply2_p8r (dReal *A, dReal *B, dReal *C, - int p, int r, int Askip) -{ - int i,j; - dReal sum,*bb,*cc; - dIASSERT (p>0 && r>0 && A && B && C); - bb = B; - for (i=p; i; i--) { - cc = C; - for (j=r; j; j--) { - sum = bb[0]*cc[0]; - sum += bb[1]*cc[1]; - sum += bb[2]*cc[2]; - sum += bb[4]*cc[4]; - sum += bb[5]*cc[5]; - sum += bb[6]*cc[6]; - *(A++) = sum; - cc += 8; - } - A += Askip - r; - bb += 8; - } -} - - -// this assumes the 4th and 8th rows of B and C are zero. - -static void MultiplyAdd2_p8r (dReal *A, dReal *B, dReal *C, - int p, int r, int Askip) -{ - int i,j; - dReal sum,*bb,*cc; - dIASSERT (p>0 && r>0 && A && B && C); - bb = B; - for (i=p; i; i--) { - cc = C; - for (j=r; j; j--) { - sum = bb[0]*cc[0]; - sum += bb[1]*cc[1]; - sum += bb[2]*cc[2]; - sum += bb[4]*cc[4]; - sum += bb[5]*cc[5]; - sum += bb[6]*cc[6]; - *(A++) += sum; - cc += 8; - } - A += Askip - r; - bb += 8; - } -} - - -// this assumes the 4th and 8th rows of B are zero. - -static void Multiply0_p81 (dReal *A, dReal *B, dReal *C, int p) -{ - int i; - dIASSERT (p>0 && A && B && C); - dReal sum; - for (i=p; i; i--) { - sum = B[0]*C[0]; - sum += B[1]*C[1]; - sum += B[2]*C[2]; - sum += B[4]*C[4]; - sum += B[5]*C[5]; - sum += B[6]*C[6]; - *(A++) = sum; - B += 8; - } -} - - -// this assumes the 4th and 8th rows of B are zero. - -static void MultiplyAdd0_p81 (dReal *A, dReal *B, dReal *C, int p) -{ - int i; - dIASSERT (p>0 && A && B && C); - dReal sum; - for (i=p; i; i--) { - sum = B[0]*C[0]; - sum += B[1]*C[1]; - sum += B[2]*C[2]; - sum += B[4]*C[4]; - sum += B[5]*C[5]; - sum += B[6]*C[6]; - *(A++) += sum; - B += 8; - } -} - - -// this assumes the 4th and 8th rows of B are zero. - -static void MultiplyAdd1_8q1 (dReal *A, dReal *B, dReal *C, int q) -{ - int k; - dReal sum; - dIASSERT (q>0 && A && B && C); - sum = 0; - for (k=0; k0 && A && B && C); - sum = 0; - for (k=0; ktag = i; - - // make a local copy of the joint array, because we might want to modify it. - // (the "dxJoint *const*" declaration says we're allowed to modify the joints - // but not the joint array, because the caller might need it unchanged). - ALLOCA(dxJoint*,joint,nj*sizeof(dxJoint*)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (joint == NULL) { - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - memcpy (joint,_joint,nj * sizeof(dxJoint*)); - - // for all bodies, compute the inertia tensor and its inverse in the global - // frame, and compute the rotational force and add it to the torque - // accumulator. - // @@@ check computation of rotational force. - ALLOCA(dReal,I,3*nb*4*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (I == NULL) { - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,invI,3*nb*4*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (invI == NULL) { - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - //dSetZero (I,3*nb*4); - //dSetZero (invI,3*nb*4); - for (i=0; imass.I,body[i]->R); - dMULTIPLY0_333 (I+i*12,body[i]->R,tmp); - // compute inverse inertia tensor in global frame - dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R); - dMULTIPLY0_333 (invI+i*12,body[i]->R,tmp); - // compute rotational force - dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel); - dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); - } - - // add the gravity force to all bodies - for (i=0; iflags & dxBodyNoGravity)==0) { - body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; - body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; - body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; - } - } - - // get m = total constraint dimension, nub = number of unbounded variables. - // create constraint offset array and number-of-rows array for all joints. - // the constraints are re-ordered as follows: the purely unbounded - // constraints, the mixed unbounded + LCP constraints, and last the purely - // LCP constraints. - // - // joints with m=0 are inactive and are removed from the joints array - // entirely, so that the code that follows does not consider them. - int m = 0; - ALLOCA(dxJoint::Info1,info,nj*sizeof(dxJoint::Info1)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (info == NULL) { - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - ALLOCA(int,ofs,nj*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (ofs == NULL) { - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - for (i=0, j=0; jvtable->getInfo1 (joint[j],info+i); - dIASSERT (info[i].m >= 0 && info[i].m <= 6 && - info[i].nub >= 0 && info[i].nub <= info[i].m); - if (info[i].m > 0) { - joint[i] = joint[j]; - i++; - } - } - nj = i; - - // the purely unbounded constraints - for (i=0; i 0 && info[i].nub < info[i].m) { - ofs[i] = m; - m += info[i].m; - } - // the purely LCP constraints - for (i=0; iinvMass; - MM[nskip+1] = body[i]->invMass; - MM[2*nskip+2] = body[i]->invMass; - MM += 3*nskip+3; - for (j=0; j<3; j++) for (k=0; k<3; k++) { - MM[j*nskip+k] = invI[i*12+j*4+k]; - } - } - - // assemble some body vectors: fe = external forces, v = velocities - ALLOCA(dReal,fe,n6*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (fe == NULL) { - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - ALLOCA(dReal,v,n6*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (v == NULL) { - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - //dSetZero (fe,n6); - //dSetZero (v,n6); - for (i=0; ifacc[j]; - for (j=0; j<3; j++) fe[i*6+3+j] = body[i]->tacc[j]; - for (j=0; j<3; j++) v[i*6+j] = body[i]->lvel[j]; - for (j=0; j<3; j++) v[i*6+3+j] = body[i]->avel[j]; - } - - // this will be set to the velocity update - ALLOCA(dReal,vnew,n6*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (vnew == NULL) { - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - dSetZero (vnew,n6); - - // if there are constraints, compute cforce - if (m > 0) { - // create a constraint equation right hand side vector `c', a constraint - // force mixing vector `cfm', and LCP low and high bound vectors, and an - // 'findex' vector. - ALLOCA(dReal,c,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (c == NULL) { - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,cfm,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (cfm == NULL) { - UNALLOCA(c); - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,lo,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (lo == NULL) { - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,hi,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (hi == NULL) { - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(int,findex,m*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (findex == NULL) { - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - dSetZero (c,m); - dSetValue (cfm,m,world->global_cfm); - dSetValue (lo,m,-dInfinity); - dSetValue (hi,m, dInfinity); - for (i=0; iglobal_erp; - for (i=0; inode[0].body->tag; - Jinfo.J1a = Jinfo.J1l + 3; - if (joint[i]->node[1].body) { - Jinfo.J2l = J + nskip*ofs[i] + 6*joint[i]->node[1].body->tag; - Jinfo.J2a = Jinfo.J2l + 3; - } - else { - Jinfo.J2l = 0; - Jinfo.J2a = 0; - } - Jinfo.c = c + ofs[i]; - Jinfo.cfm = cfm + ofs[i]; - Jinfo.lo = lo + ofs[i]; - Jinfo.hi = hi + ofs[i]; - Jinfo.findex = findex + ofs[i]; - joint[i]->vtable->getInfo2 (joint[i],&Jinfo); - // adjust returned findex values for global index numbering - for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; - } - } - - // compute A = J*invM*J' -# ifdef TIMING - dTimerNow ("compute A"); -# endif - ALLOCA(dReal,JinvM,m*nskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (JinvM == NULL) { - UNALLOCA(J); - UNALLOCA(findex); - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - //dSetZero (JinvM,m*nskip); - dMultiply0 (JinvM,J,invM,m,n6,n6); - int mskip = dPAD(m); - ALLOCA(dReal,A,m*mskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (A == NULL) { - UNALLOCA(JinvM); - UNALLOCA(J); - UNALLOCA(findex); - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(vnew); - UNALLOCA(v); - UNALLOCA(fe); - UNALLOCA(invM); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - //dSetZero (A,m*mskip); - dMultiply2 (A,JinvM,J,m,n6,m); - - // add cfm to the diagonal of A - for (i=0; ilvel[j] = vnew[i*6+j]; - for (j=0; j<3; j++) body[i]->avel[j] = vnew[i*6+3+j]; - } - - // update the position and orientation from the new linear/angular velocity - // (over the given timestep) -#ifdef TIMING - dTimerNow ("update position"); -#endif - for (i=0; ifacc[0] = 0; - body[i]->facc[1] = 0; - body[i]->facc[2] = 0; - body[i]->facc[3] = 0; - body[i]->tacc[0] = 0; - body[i]->tacc[1] = 0; - body[i]->tacc[2] = 0; - body[i]->tacc[3] = 0; - } - -#ifdef TIMING - dTimerEnd(); - if (m > 0) dTimerReport (stdout,1); -#endif - - UNALLOCA(joint); - UNALLOCA(I); - UNALLOCA(invI); - UNALLOCA(info); - UNALLOCA(ofs); - UNALLOCA(invM); - UNALLOCA(fe); - UNALLOCA(v); - UNALLOCA(vnew); -} - -//**************************************************************************** -// an optimized version of dInternalStepIsland1() - -void dInternalStepIsland_x2 (dxWorld *world, dxBody * const *body, int nb, - dxJoint * const *_joint, int nj, dReal stepsize) -{ - int i,j,k; -#ifdef TIMING - dTimerStart("preprocessing"); -#endif - - dReal stepsize1 = dRecip(stepsize); - - // number all bodies in the body list - set their tag values - for (i=0; itag = i; - - // make a local copy of the joint array, because we might want to modify it. - // (the "dxJoint *const*" declaration says we're allowed to modify the joints - // but not the joint array, because the caller might need it unchanged). - ALLOCA(dxJoint*,joint,nj*sizeof(dxJoint*)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (joint == NULL) { - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - memcpy (joint,_joint,nj * sizeof(dxJoint*)); - - // for all bodies, compute the inertia tensor and its inverse in the global - // frame, and compute the rotational force and add it to the torque - // accumulator. I and invI are vertically stacked 3x4 matrices, one per body. - // @@@ check computation of rotational force. - ALLOCA(dReal,I,3*nb*4*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (I == NULL) { - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,invI,3*nb*4*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (invI == NULL) { - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - - //dSetZero (I,3*nb*4); - //dSetZero (invI,3*nb*4); - for (i=0; imass.I,body[i]->R); - dMULTIPLY0_333 (I+i*12,body[i]->R,tmp); - // compute inverse inertia tensor in global frame - dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R); - dMULTIPLY0_333 (invI+i*12,body[i]->R,tmp); - // compute rotational force - dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel); - dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); - } - - // add the gravity force to all bodies - for (i=0; iflags & dxBodyNoGravity)==0) { - body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; - body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; - body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; - } - } - - // get m = total constraint dimension, nub = number of unbounded variables. - // create constraint offset array and number-of-rows array for all joints. - // the constraints are re-ordered as follows: the purely unbounded - // constraints, the mixed unbounded + LCP constraints, and last the purely - // LCP constraints. this assists the LCP solver to put all unbounded - // variables at the start for a quick factorization. - // - // joints with m=0 are inactive and are removed from the joints array - // entirely, so that the code that follows does not consider them. - // also number all active joints in the joint list (set their tag values). - // inactive joints receive a tag value of -1. - - int m = 0; - ALLOCA(dxJoint::Info1,info,nj*sizeof(dxJoint::Info1)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (info == NULL) { - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(int,ofs,nj*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (ofs == NULL) { - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - for (i=0, j=0; jvtable->getInfo1 (joint[j],info+i); - dIASSERT (info[i].m >= 0 && info[i].m <= 6 && - info[i].nub >= 0 && info[i].nub <= info[i].m); - if (info[i].m > 0) { - joint[i] = joint[j]; - joint[i]->tag = i; - i++; - } - else { - joint[j]->tag = -1; - } - } - nj = i; - - // the purely unbounded constraints - for (i=0; i 0 && info[i].nub < info[i].m) { - ofs[i] = m; - m += info[i].m; - } - // the purely LCP constraints - for (i=0; i 0) { - // create a constraint equation right hand side vector `c', a constraint - // force mixing vector `cfm', and LCP low and high bound vectors, and an - // 'findex' vector. - ALLOCA(dReal,c,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (c == NULL) { - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,cfm,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (cfm == NULL) { - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,lo,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (lo == NULL) { - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(dReal,hi,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (hi == NULL) { - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - ALLOCA(int,findex,m*sizeof(int)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (findex == NULL) { - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - dSetZero (c,m); - dSetValue (cfm,m,world->global_cfm); - dSetValue (lo,m,-dInfinity); - dSetValue (hi,m, dInfinity); - for (i=0; iglobal_erp; - for (i=0; ivtable->getInfo2 (joint[i],&Jinfo); - // adjust returned findex values for global index numbering - for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; - } - } - - // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same - // format as J so we just go through the constraints in J multiplying by - // the appropriate scalars and matrices. -# ifdef TIMING - dTimerNow ("compute A"); -# endif - ALLOCA(dReal,JinvM,2*m*8*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (JinvM == NULL) { - UNALLOCA(J); - UNALLOCA(findex); - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - dSetZero (JinvM,2*m*8); - for (i=0; inode[0].body->tag; - dReal body_invMass = body[b]->invMass; - dReal *body_invI = invI + b*12; - dReal *Jsrc = J + 2*8*ofs[i]; - dReal *Jdst = JinvM + 2*8*ofs[i]; - for (j=info[i].m-1; j>=0; j--) { - for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass; - dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI); - Jsrc += 8; - Jdst += 8; - } - if (joint[i]->node[1].body) { - b = joint[i]->node[1].body->tag; - body_invMass = body[b]->invMass; - body_invI = invI + b*12; - for (j=info[i].m-1; j>=0; j--) { - for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass; - dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI); - Jsrc += 8; - Jdst += 8; - } - } - } - - // now compute A = JinvM * J'. A's rows and columns are grouped by joint, - // i.e. in the same way as the rows of J. block (i,j) of A is only nonzero - // if joints i and j have at least one body in common. this fact suggests - // the algorithm used to fill A: - // - // for b = all bodies - // n = number of joints attached to body b - // for i = 1..n - // for j = i+1..n - // ii = actual joint number for i - // jj = actual joint number for j - // // (ii,jj) will be set to all pairs of joints around body b - // compute blockwise: A(ii,jj) += JinvM(ii) * J(jj)' - // - // this algorithm catches all pairs of joints that have at least one body - // in common. it does not compute the diagonal blocks of A however - - // another similar algorithm does that. - - int mskip = dPAD(m); - ALLOCA(dReal,A,m*mskip*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (A == NULL) { - UNALLOCA(JinvM); - UNALLOCA(J); - UNALLOCA(findex); - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - dSetZero (A,m*mskip); - for (i=0; ifirstjoint; n1; n1=n1->next) { - for (dxJointNode *n2=n1->next; n2; n2=n2->next) { - // get joint numbers and ensure ofs[j1] >= ofs[j2] - int j1 = n1->joint->tag; - int j2 = n2->joint->tag; - if (ofs[j1] < ofs[j2]) { - int tmp = j1; - j1 = j2; - j2 = tmp; - } - - // if either joint was tagged as -1 then it is an inactive (m=0) - // joint that should not be considered - if (j1==-1 || j2==-1) continue; - - // determine if body i is the 1st or 2nd body of joints j1 and j2 - int jb1 = (joint[j1]->node[1].body == body[i]); - int jb2 = (joint[j2]->node[1].body == body[i]); - // jb1/jb2 must be 0 for joints with only one body - dIASSERT(joint[j1]->node[1].body || jb1==0); - dIASSERT(joint[j2]->node[1].body || jb2==0); - - // set block of A - MultiplyAdd2_p8r (A + ofs[j1]*mskip + ofs[j2], - JinvM + 2*8*ofs[j1] + jb1*8*info[j1].m, - J + 2*8*ofs[j2] + jb2*8*info[j2].m, - info[j1].m,info[j2].m, mskip); - } - } - } - // compute diagonal blocks of A - for (i=0; inode[1].body) { - MultiplyAdd2_p8r (A + ofs[i]*(mskip+1), - JinvM + 2*8*ofs[i] + 8*info[i].m, - J + 2*8*ofs[i] + 8*info[i].m, - info[i].m,info[i].m, mskip); - } - } - - // add cfm to the diagonal of A - for (i=0; iinvMass; - dReal *body_invI = invI + i*12; - for (j=0; j<3; j++) tmp1[i*8+j] = body[i]->facc[j] * body_invMass + - body[i]->lvel[j] * stepsize1; - dMULTIPLY0_331 (tmp1 + i*8 + 4,body_invI,body[i]->tacc); - for (j=0; j<3; j++) tmp1[i*8+4+j] += body[i]->avel[j] * stepsize1; - } - // put J*tmp1 into rhs - ALLOCA(dReal,rhs,m*sizeof(dReal)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (rhs == NULL) { - UNALLOCA(tmp1); - UNALLOCA(A); - UNALLOCA(JinvM); - UNALLOCA(J); - UNALLOCA(findex); - UNALLOCA(hi); - UNALLOCA(lo); - UNALLOCA(cfm); - UNALLOCA(c); - UNALLOCA(cforce); - UNALLOCA(ofs); - UNALLOCA(info); - UNALLOCA(invI); - UNALLOCA(I); - UNALLOCA(joint); - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - return; - } -#endif - //dSetZero (rhs,m); - for (i=0; inode[0].body->tag, info[i].m); - if (joint[i]->node[1].body) { - MultiplyAdd0_p81 (rhs+ofs[i],JJ + 8*info[i].m, - tmp1 + 8*joint[i]->node[1].body->tag, info[i].m); - } - } - // complete rhs - for (i=0; inode[0].body; - dxBody* b2 = joint[i]->node[1].body; - dJointFeedback *fb = joint[i]->feedback; - - if (fb) { - // the user has requested feedback on the amount of force that this - // joint is applying to the bodies. we use a slightly slower - // computation that splits out the force components and puts them - // in the feedback structure. - dReal data1[8],data2[8]; - Multiply1_8q1 (data1, JJ, lambda+ofs[i], info[i].m); - dReal *cf1 = cforce + 8*b1->tag; - cf1[0] += (fb->f1[0] = data1[0]); - cf1[1] += (fb->f1[1] = data1[1]); - cf1[2] += (fb->f1[2] = data1[2]); - cf1[4] += (fb->t1[0] = data1[4]); - cf1[5] += (fb->t1[1] = data1[5]); - cf1[6] += (fb->t1[2] = data1[6]); - if (b2){ - Multiply1_8q1 (data2, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); - dReal *cf2 = cforce + 8*b2->tag; - cf2[0] += (fb->f2[0] = data2[0]); - cf2[1] += (fb->f2[1] = data2[1]); - cf2[2] += (fb->f2[2] = data2[2]); - cf2[4] += (fb->t2[0] = data2[4]); - cf2[5] += (fb->t2[1] = data2[5]); - cf2[6] += (fb->t2[2] = data2[6]); - } - } - else { - // no feedback is required, let's compute cforce the faster way - MultiplyAdd1_8q1 (cforce + 8*b1->tag,JJ, lambda+ofs[i], info[i].m); - if (b2) { - MultiplyAdd1_8q1 (cforce + 8*b2->tag, - JJ + 8*info[i].m, lambda+ofs[i], info[i].m); - } - } - } - UNALLOCA(c); - UNALLOCA(cfm); - UNALLOCA(lo); - UNALLOCA(hi); - UNALLOCA(findex); - UNALLOCA(J); - UNALLOCA(JinvM); - UNALLOCA(A); - UNALLOCA(tmp1); - UNALLOCA(rhs); - UNALLOCA(lambda); - UNALLOCA(residual); - } - - // compute the velocity update -#ifdef TIMING - dTimerNow ("compute velocity update"); -#endif - - // add fe to cforce - for (i=0; ifacc[j]; - for (j=0; j<3; j++) cforce[i*8+4+j] += body[i]->tacc[j]; - } - // multiply cforce by stepsize - for (i=0; i < nb*8; i++) cforce[i] *= stepsize; - // add invM * cforce to the body velocity - for (i=0; iinvMass; - dReal *body_invI = invI + i*12; - for (j=0; j<3; j++) body[i]->lvel[j] += body_invMass * cforce[i*8+j]; - dMULTIPLYADD0_331 (body[i]->avel,body_invI,cforce+i*8+4); - } - - // update the position and orientation from the new linear/angular velocity - // (over the given timestep) -# ifdef TIMING - dTimerNow ("update position"); -# endif - for (i=0; ilvel[j]; - for (j=0; j<3; j++) tmp_vnew[i*6+3+j] = body[i]->avel[j]; - } - comparator.nextMatrix (tmp_vnew,nb*6,1,0,"vnew"); - UNALLOCA(tmp); -#endif - -#ifdef TIMING - dTimerNow ("tidy up"); -#endif - - // zero all force accumulators - for (i=0; ifacc[0] = 0; - body[i]->facc[1] = 0; - body[i]->facc[2] = 0; - body[i]->facc[3] = 0; - body[i]->tacc[0] = 0; - body[i]->tacc[1] = 0; - body[i]->tacc[2] = 0; - body[i]->tacc[3] = 0; - } - -#ifdef TIMING - dTimerEnd(); - if (m > 0) dTimerReport (stdout,1); -#endif - - UNALLOCA(joint); - UNALLOCA(I); - UNALLOCA(invI); - UNALLOCA(info); - UNALLOCA(ofs); - UNALLOCA(cforce); -} - -//**************************************************************************** - -void dInternalStepIsland (dxWorld *world, dxBody * const *body, int nb, - dxJoint * const *joint, int nj, dReal stepsize) -{ - -#ifdef dUSE_MALLOC_FOR_ALLOCA - dMemoryFlag = d_MEMORY_OK; -#endif - -#ifndef COMPARE_METHODS - dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize); - -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { - REPORT_OUT_OF_MEMORY; - return; - } -#endif - -#endif - -#ifdef COMPARE_METHODS - int i; - - // save body state - ALLOCA(dxBody,state,nb*sizeof(dxBody)); -#ifdef dUSE_MALLOC_FOR_ALLOCA - if (state == NULL) { - dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; - REPORT_OUT_OF_MEMORY; - return; - } -#endif - for (i=0; i - - -void dInternalStepIsland (dxWorld *world, - dxBody * const *body, int nb, - dxJoint * const *joint, int nj, - dReal stepsize); - - - -#endif diff --git a/Extras/ode/ode/src/stepfast.cpp b/Extras/ode/ode/src/stepfast.cpp deleted file mode 100644 index 806943676..000000000 --- a/Extras/ode/ode/src/stepfast.cpp +++ /dev/null @@ -1,1137 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * Fast iterative solver, David Whittaker. Email: david@csworkbench.com * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// This is the StepFast code by David Whittaker. This code is faster, but -// sometimes less stable than, the original "big matrix" code. -// Refer to the user's manual for more information. -// Note that this source file duplicates a lot of stuff from step.cpp, -// eventually we should move the common code to a third file. - -#include "objects.h" -#include "joint.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "lcp.h" -#include "step.h" -#include "util.h" - - -// misc defines - -#define ALLOCA dALLOCA16 - -#define RANDOM_JOINT_ORDER -//#define FAST_FACTOR //use a factorization approximation to the LCP solver (fast, theoretically less accurate) -#define SLOW_LCP //use the old LCP solver -//#define NO_ISLANDS //does not perform island creation code (3~4% of simulation time), body disabling doesn't work -//#define TIMING - - -static int autoEnableDepth = 2; - -void dWorldSetAutoEnableDepthSF1 (dxWorld *world, int autodepth) -{ - if (autodepth > 0) - autoEnableDepth = autodepth; - else - autoEnableDepth = 0; -} - -int dWorldGetAutoEnableDepthSF1 (dxWorld *world) -{ - return autoEnableDepth; -} - -//little bit of math.... the _sym_ functions assume the return matrix will be symmetric -static void -Multiply2_sym_p8p (dReal * A, dReal * B, dReal * C, int p, int Askip) -{ - int i, j; - dReal sum, *aa, *ad, *bb, *cc; - dIASSERT (p > 0 && A && B && C); - bb = B; - for (i = 0; i < p; i++) - { - //aa is going accross the matrix, ad down - aa = ad = A; - cc = C; - for (j = i; j < p; j++) - { - sum = bb[0] * cc[0]; - sum += bb[1] * cc[1]; - sum += bb[2] * cc[2]; - sum += bb[4] * cc[4]; - sum += bb[5] * cc[5]; - sum += bb[6] * cc[6]; - *(aa++) = *ad = sum; - ad += Askip; - cc += 8; - } - bb += 8; - A += Askip + 1; - C += 8; - } -} - -static void -MultiplyAdd2_sym_p8p (dReal * A, dReal * B, dReal * C, int p, int Askip) -{ - int i, j; - dReal sum, *aa, *ad, *bb, *cc; - dIASSERT (p > 0 && A && B && C); - bb = B; - for (i = 0; i < p; i++) - { - //aa is going accross the matrix, ad down - aa = ad = A; - cc = C; - for (j = i; j < p; j++) - { - sum = bb[0] * cc[0]; - sum += bb[1] * cc[1]; - sum += bb[2] * cc[2]; - sum += bb[4] * cc[4]; - sum += bb[5] * cc[5]; - sum += bb[6] * cc[6]; - *(aa++) += sum; - *ad += sum; - ad += Askip; - cc += 8; - } - bb += 8; - A += Askip + 1; - C += 8; - } -} - - -// this assumes the 4th and 8th rows of B are zero. - -static void -Multiply0_p81 (dReal * A, dReal * B, dReal * C, int p) -{ - int i; - dIASSERT (p > 0 && A && B && C); - dReal sum; - for (i = p; i; i--) - { - sum = B[0] * C[0]; - sum += B[1] * C[1]; - sum += B[2] * C[2]; - sum += B[4] * C[4]; - sum += B[5] * C[5]; - sum += B[6] * C[6]; - *(A++) = sum; - B += 8; - } -} - - -// this assumes the 4th and 8th rows of B are zero. - -static void -MultiplyAdd0_p81 (dReal * A, dReal * B, dReal * C, int p) -{ - int i; - dIASSERT (p > 0 && A && B && C); - dReal sum; - for (i = p; i; i--) - { - sum = B[0] * C[0]; - sum += B[1] * C[1]; - sum += B[2] * C[2]; - sum += B[4] * C[4]; - sum += B[5] * C[5]; - sum += B[6] * C[6]; - *(A++) += sum; - B += 8; - } -} - - -// this assumes the 4th and 8th rows of B are zero. - -static void -Multiply1_8q1 (dReal * A, dReal * B, dReal * C, int q) -{ - int k; - dReal sum; - dIASSERT (q > 0 && A && B && C); - sum = 0; - for (k = 0; k < q; k++) - sum += B[k * 8] * C[k]; - A[0] = sum; - sum = 0; - for (k = 0; k < q; k++) - sum += B[1 + k * 8] * C[k]; - A[1] = sum; - sum = 0; - for (k = 0; k < q; k++) - sum += B[2 + k * 8] * C[k]; - A[2] = sum; - sum = 0; - for (k = 0; k < q; k++) - sum += B[4 + k * 8] * C[k]; - A[4] = sum; - sum = 0; - for (k = 0; k < q; k++) - sum += B[5 + k * 8] * C[k]; - A[5] = sum; - sum = 0; - for (k = 0; k < q; k++) - sum += B[6 + k * 8] * C[k]; - A[6] = sum; -} - -//**************************************************************************** -// body rotation - -// return sin(x)/x. this has a singularity at 0 so special handling is needed -// for small arguments. - -static inline dReal -sinc (dReal x) -{ - // if |x| < 1e-4 then use a taylor series expansion. this two term expansion - // is actually accurate to one LS bit within this range if double precision - // is being used - so don't worry! - if (dFabs (x) < 1.0e-4) - return REAL (1.0) - x * x * REAL (0.166666666666666666667); - else - return dSin (x) / x; -} - - -// given a body b, apply its linear and angular rotation over the time -// interval h, thereby adjusting its position and orientation. - -static inline void -moveAndRotateBody (dxBody * b, dReal h) -{ - int j; - - // handle linear velocity - for (j = 0; j < 3; j++) - b->pos[j] += h * b->lvel[j]; - - if (b->flags & dxBodyFlagFiniteRotation) - { - dVector3 irv; // infitesimal rotation vector - dQuaternion q; // quaternion for finite rotation - - if (b->flags & dxBodyFlagFiniteRotationAxis) - { - // split the angular velocity vector into a component along the finite - // rotation axis, and a component orthogonal to it. - dVector3 frv, irv; // finite rotation vector - dReal k = dDOT (b->finite_rot_axis, b->avel); - frv[0] = b->finite_rot_axis[0] * k; - frv[1] = b->finite_rot_axis[1] * k; - frv[2] = b->finite_rot_axis[2] * k; - irv[0] = b->avel[0] - frv[0]; - irv[1] = b->avel[1] - frv[1]; - irv[2] = b->avel[2] - frv[2]; - - // make a rotation quaternion q that corresponds to frv * h. - // compare this with the full-finite-rotation case below. - h *= REAL (0.5); - dReal theta = k * h; - q[0] = dCos (theta); - dReal s = sinc (theta) * h; - q[1] = frv[0] * s; - q[2] = frv[1] * s; - q[3] = frv[2] * s; - } - else - { - // make a rotation quaternion q that corresponds to w * h - dReal wlen = dSqrt (b->avel[0] * b->avel[0] + b->avel[1] * b->avel[1] + b->avel[2] * b->avel[2]); - h *= REAL (0.5); - dReal theta = wlen * h; - q[0] = dCos (theta); - dReal s = sinc (theta) * h; - q[1] = b->avel[0] * s; - q[2] = b->avel[1] * s; - q[3] = b->avel[2] * s; - } - - // do the finite rotation - dQuaternion q2; - dQMultiply0 (q2, q, b->q); - for (j = 0; j < 4; j++) - b->q[j] = q2[j]; - - // do the infitesimal rotation if required - if (b->flags & dxBodyFlagFiniteRotationAxis) - { - dReal dq[4]; - dWtoDQ (irv, b->q, dq); - for (j = 0; j < 4; j++) - b->q[j] += h * dq[j]; - } - } - else - { - // the normal way - do an infitesimal rotation - dReal dq[4]; - dWtoDQ (b->avel, b->q, dq); - for (j = 0; j < 4; j++) - b->q[j] += h * dq[j]; - } - - // normalize the quaternion and convert it to a rotation matrix - dNormalize4 (b->q); - dQtoR (b->q, b->R); - - // notify all attached geoms that this body has moved - for (dxGeom * geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) - dGeomMoved (geom); -} - -//**************************************************************************** -//This is an implementation of the iterated/relaxation algorithm. -//Here is a quick overview of the algorithm per Sergi Valverde's posts to the -//mailing list: -// -// for i=0..N-1 do -// for c = 0..C-1 do -// Solve constraint c-th -// Apply forces to constraint bodies -// next -// next -// Integrate bodies - -void -dInternalStepFast (dxWorld * world, dxBody * body[2], dReal * GI[2], dReal * GinvI[2], dxJoint * joint, dxJoint::Info1 info, dxJoint::Info2 Jinfo, dReal stepsize) -{ - int i, j, k; -# ifdef TIMING - dTimerNow ("constraint preprocessing"); -# endif - - dReal stepsize1 = dRecip (stepsize); - - int m = info.m; - // nothing to do if no constraints. - if (m <= 0) - return; - - int nub = 0; - if (info.nub == info.m) - nub = m; - - // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same - // format as J so we just go through the constraints in J multiplying by - // the appropriate scalars and matrices. -# ifdef TIMING - dTimerNow ("compute A"); -# endif - dReal JinvM[2 * 6 * 8]; - //dSetZero (JinvM, 2 * m * 8); - - dReal *Jsrc = Jinfo.J1l; - dReal *Jdst = JinvM; - if (body[0]) - { - for (j = m - 1; j >= 0; j--) - { - for (k = 0; k < 3; k++) - Jdst[k] = Jsrc[k] * body[0]->invMass; - dMULTIPLY0_133 (Jdst + 4, Jsrc + 4, GinvI[0]); - Jsrc += 8; - Jdst += 8; - } - } - if (body[1]) - { - Jsrc = Jinfo.J2l; - Jdst = JinvM + 8 * m; - for (j = m - 1; j >= 0; j--) - { - for (k = 0; k < 3; k++) - Jdst[k] = Jsrc[k] * body[1]->invMass; - dMULTIPLY0_133 (Jdst + 4, Jsrc + 4, GinvI[1]); - Jsrc += 8; - Jdst += 8; - } - } - - - // now compute A = JinvM * J'. - int mskip = dPAD (m); - dReal A[6 * 8]; - //dSetZero (A, 6 * 8); - - if (body[0]) { - Multiply2_sym_p8p (A, JinvM, Jinfo.J1l, m, mskip); - if (body[1]) - MultiplyAdd2_sym_p8p (A, JinvM + 8 * m, Jinfo.J2l, - m, mskip); - } else { - if (body[1]) - Multiply2_sym_p8p (A, JinvM + 8 * m, Jinfo.J2l, - m, mskip); - } - - // add cfm to the diagonal of A - for (i = 0; i < m; i++) - A[i * mskip + i] += Jinfo.cfm[i] * stepsize1; - - // compute the right hand side `rhs' -# ifdef TIMING - dTimerNow ("compute rhs"); -# endif - dReal tmp1[16]; - //dSetZero (tmp1, 16); - // put v/h + invM*fe into tmp1 - for (i = 0; i < 2; i++) - { - if (!body[i]) - continue; - for (j = 0; j < 3; j++) - tmp1[i * 8 + j] = body[i]->facc[j] * body[i]->invMass + body[i]->lvel[j] * stepsize1; - dMULTIPLY0_331 (tmp1 + i * 8 + 4, GinvI[i], body[i]->tacc); - for (j = 0; j < 3; j++) - tmp1[i * 8 + 4 + j] += body[i]->avel[j] * stepsize1; - } - // put J*tmp1 into rhs - dReal rhs[6]; - //dSetZero (rhs, 6); - - if (body[0]) { - Multiply0_p81 (rhs, Jinfo.J1l, tmp1, m); - if (body[1]) - MultiplyAdd0_p81 (rhs, Jinfo.J2l, tmp1 + 8, m); - } else { - if (body[1]) - Multiply0_p81 (rhs, Jinfo.J2l, tmp1 + 8, m); - } - - // complete rhs - for (i = 0; i < m; i++) - rhs[i] = Jinfo.c[i] * stepsize1 - rhs[i]; - -#ifdef SLOW_LCP - // solve the LCP problem and get lambda. - // this will destroy A but that's okay -# ifdef TIMING - dTimerNow ("solving LCP problem"); -# endif - dReal *lambda = (dReal *) ALLOCA (m * sizeof (dReal)); - dReal *residual = (dReal *) ALLOCA (m * sizeof (dReal)); - dReal lo[6], hi[6]; - memcpy (lo, Jinfo.lo, m * sizeof (dReal)); - memcpy (hi, Jinfo.hi, m * sizeof (dReal)); - dSolveLCP (m, A, lambda, rhs, residual, nub, lo, hi, Jinfo.findex); -#endif - - // LCP Solver replacement: - // This algorithm goes like this: - // Do a straightforward LDLT factorization of the matrix A, solving for - // A*x = rhs - // For each x[i] that is outside of the bounds of lo[i] and hi[i], - // clamp x[i] into that range. - // Substitute into A the now known x's - // subtract the residual away from the rhs. - // Remove row and column i from L, updating the factorization - // place the known x's at the end of the array, keeping up with location in p - // Repeat until all constraints have been clamped or all are within bounds - // - // This is probably only faster in the single joint case where only one repeat is - // the norm. - -#ifdef FAST_FACTOR - // factorize A (L*D*L'=A) -# ifdef TIMING - dTimerNow ("factorize A"); -# endif - dReal d[6]; - dReal L[6 * 8]; - memcpy (L, A, m * mskip * sizeof (dReal)); - dFactorLDLT (L, d, m, mskip); - - // compute lambda -# ifdef TIMING - dTimerNow ("compute lambda"); -# endif - - int left = m; //constraints left to solve. - int remove[6]; - dReal lambda[6]; - dReal x[6]; - int p[6]; - for (i = 0; i < 6; i++) - p[i] = i; - while (true) - { - memcpy (x, rhs, left * sizeof (dReal)); - dSolveLDLT (L, d, x, left, mskip); - - int fixed = 0; - for (i = 0; i < left; i++) - { - j = p[i]; - remove[i] = false; - // This isn't the exact same use of findex as dSolveLCP.... since x[findex] - // may change after I've already clamped x[i], but it should be close - if (Jinfo.findex[j] > -1) - { - dReal f = fabs (Jinfo.hi[j] * x[p[Jinfo.findex[j]]]); - if (x[i] > f) - x[i] = f; - else if (x[i] < -f) - x[i] = -f; - else - continue; - } - else - { - if (x[i] > Jinfo.hi[j]) - x[i] = Jinfo.hi[j]; - else if (x[i] < Jinfo.lo[j]) - x[i] = Jinfo.lo[j]; - else - continue; - } - remove[i] = true; - fixed++; - } - if (fixed == 0 || fixed == left) //no change or all constraints solved - break; - - for (i = 0; i < left; i++) //sub in to right hand side. - if (remove[i]) - for (j = 0; j < left; j++) - if (!remove[j]) - rhs[j] -= A[j * mskip + i] * x[i]; - - for (int r = left - 1; r >= 0; r--) //eliminate row/col for fixed variables - { - if (remove[r]) - { - //dRemoveLDLT adapted for use without row pointers. - if (r == left - 1) - { - left--; - continue; // deleting last row/col is easy - } - else if (r == 0) - { - dReal a[6]; - for (i = 0; i < left; i++) - a[i] = -A[i * mskip]; - a[0] += REAL (1.0); - dLDLTAddTL (L, d, a, left, mskip); - } - else - { - dReal t[6]; - dReal a[6]; - for (i = 0; i < r; i++) - t[i] = L[r * mskip + i] / d[i]; - for (i = 0; i < left - r; i++) - a[i] = dDot (L + (r + i) * mskip, t, r) - A[(r + i) * mskip + r]; - a[0] += REAL (1.0); - dLDLTAddTL (L + r * mskip + r, d + r, a, left - r, mskip); - } - - dRemoveRowCol (L, left, mskip, r); - //end dRemoveLDLT - - left--; - if (r < (left - 1)) - { - dReal tx = x[r]; - memmove (d + r, d + r + 1, (left - r) * sizeof (dReal)); - memmove (rhs + r, rhs + r + 1, (left - r) * sizeof (dReal)); - //x will get written over by rhs anyway, no need to move it around - //just store the fixed value we just discovered in it. - x[left] = tx; - for (i = 0; i < m; i++) - if (p[i] > r && p[i] <= left) - p[i]--; - p[r] = left; - } - } - } - } - - for (i = 0; i < m; i++) - lambda[i] = x[p[i]]; -# endif - // compute the constraint force `cforce' -# ifdef TIMING - dTimerNow ("compute constraint force"); -#endif - - // compute cforce = J'*lambda - dJointFeedback *fb = joint->feedback; - dReal cforce[16]; - //dSetZero (cforce, 16); - - if (fb) - { - // the user has requested feedback on the amount of force that this - // joint is applying to the bodies. we use a slightly slower - // computation that splits out the force components and puts them - // in the feedback structure. - dReal data1[8], data2[8]; - if (body[0]) - { - Multiply1_8q1 (data1, Jinfo.J1l, lambda, m); - dReal *cf1 = cforce; - cf1[0] = (fb->f1[0] = data1[0]); - cf1[1] = (fb->f1[1] = data1[1]); - cf1[2] = (fb->f1[2] = data1[2]); - cf1[4] = (fb->t1[0] = data1[4]); - cf1[5] = (fb->t1[1] = data1[5]); - cf1[6] = (fb->t1[2] = data1[6]); - } - if (body[1]) - { - Multiply1_8q1 (data2, Jinfo.J2l, lambda, m); - dReal *cf2 = cforce + 8; - cf2[0] = (fb->f2[0] = data2[0]); - cf2[1] = (fb->f2[1] = data2[1]); - cf2[2] = (fb->f2[2] = data2[2]); - cf2[4] = (fb->t2[0] = data2[4]); - cf2[5] = (fb->t2[1] = data2[5]); - cf2[6] = (fb->t2[2] = data2[6]); - } - } - else - { - // no feedback is required, let's compute cforce the faster way - if (body[0]) - Multiply1_8q1 (cforce, Jinfo.J1l, lambda, m); - if (body[1]) - Multiply1_8q1 (cforce + 8, Jinfo.J2l, lambda, m); - } - - for (i = 0; i < 2; i++) - { - if (!body[i]) - continue; - for (j = 0; j < 3; j++) - { - body[i]->facc[j] += cforce[i * 8 + j]; - body[i]->tacc[j] += cforce[i * 8 + 4 + j]; - } - } -} - -void -dInternalStepIslandFast (dxWorld * world, dxBody * const *bodies, int nb, dxJoint * const *_joints, int nj, dReal stepsize, int maxiterations) -{ -# ifdef TIMING - dTimerNow ("preprocessing"); -# endif - dxBody *bodyPair[2], *body; - dReal *GIPair[2], *GinvIPair[2]; - dxJoint *joint; - int iter, b, j, i; - dReal ministep = stepsize / maxiterations; - - // make a local copy of the joint array, because we might want to modify it. - // (the "dxJoint *const*" declaration says we're allowed to modify the joints - // but not the joint array, because the caller might need it unchanged). - dxJoint **joints = (dxJoint **) ALLOCA (nj * sizeof (dxJoint *)); - memcpy (joints, _joints, nj * sizeof (dxJoint *)); - - // get m = total constraint dimension, nub = number of unbounded variables. - // create constraint offset array and number-of-rows array for all joints. - // the constraints are re-ordered as follows: the purely unbounded - // constraints, the mixed unbounded + LCP constraints, and last the purely - // LCP constraints. this assists the LCP solver to put all unbounded - // variables at the start for a quick factorization. - // - // joints with m=0 are inactive and are removed from the joints array - // entirely, so that the code that follows does not consider them. - // also number all active joints in the joint list (set their tag values). - // inactive joints receive a tag value of -1. - - int m = 0; - dxJoint::Info1 * info = (dxJoint::Info1 *) ALLOCA (nj * sizeof (dxJoint::Info1)); - int *ofs = (int *) ALLOCA (nj * sizeof (int)); - for (i = 0, j = 0; j < nj; j++) - { // i=dest, j=src - joints[j]->vtable->getInfo1 (joints[j], info + i); - dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); - if (info[i].m > 0) - { - joints[i] = joints[j]; - joints[i]->tag = i; - i++; - } - else - { - joints[j]->tag = -1; - } - } - nj = i; - - // the purely unbounded constraints - for (i = 0; i < nj; i++) - { - ofs[i] = m; - m += info[i].m; - } - dReal *c = NULL; - dReal *cfm = NULL; - dReal *lo = NULL; - dReal *hi = NULL; - int *findex = NULL; - - dReal *J = NULL; - dxJoint::Info2 * Jinfo = NULL; - - if (m) - { - // create a constraint equation right hand side vector `c', a constraint - // force mixing vector `cfm', and LCP low and high bound vectors, and an - // 'findex' vector. - c = (dReal *) ALLOCA (m * sizeof (dReal)); - cfm = (dReal *) ALLOCA (m * sizeof (dReal)); - lo = (dReal *) ALLOCA (m * sizeof (dReal)); - hi = (dReal *) ALLOCA (m * sizeof (dReal)); - findex = (int *) ALLOCA (m * sizeof (int)); - dSetZero (c, m); - dSetValue (cfm, m, world->global_cfm); - dSetValue (lo, m, -dInfinity); - dSetValue (hi, m, dInfinity); - for (i = 0; i < m; i++) - findex[i] = -1; - - // get jacobian data from constraints. a (2*m)x8 matrix will be created - // to store the two jacobian blocks from each constraint. it has this - // format: - // - // l l l 0 a a a 0 \ . - // l l l 0 a a a 0 }-- jacobian body 1 block for joint 0 (3 rows) - // l l l 0 a a a 0 / - // l l l 0 a a a 0 \ . - // l l l 0 a a a 0 }-- jacobian body 2 block for joint 0 (3 rows) - // l l l 0 a a a 0 / - // l l l 0 a a a 0 }--- jacobian body 1 block for joint 1 (1 row) - // l l l 0 a a a 0 }--- jacobian body 2 block for joint 1 (1 row) - // etc... - // - // (lll) = linear jacobian data - // (aaa) = angular jacobian data - // -# ifdef TIMING - dTimerNow ("create J"); -# endif - J = (dReal *) ALLOCA (2 * m * 8 * sizeof (dReal)); - dSetZero (J, 2 * m * 8); - Jinfo = (dxJoint::Info2 *) ALLOCA (nj * sizeof (dxJoint::Info2)); - for (i = 0; i < nj; i++) - { - Jinfo[i].rowskip = 8; - Jinfo[i].fps = dRecip (stepsize); - Jinfo[i].erp = world->global_erp; - Jinfo[i].J1l = J + 2 * 8 * ofs[i]; - Jinfo[i].J1a = Jinfo[i].J1l + 4; - Jinfo[i].J2l = Jinfo[i].J1l + 8 * info[i].m; - Jinfo[i].J2a = Jinfo[i].J2l + 4; - Jinfo[i].c = c + ofs[i]; - Jinfo[i].cfm = cfm + ofs[i]; - Jinfo[i].lo = lo + ofs[i]; - Jinfo[i].hi = hi + ofs[i]; - Jinfo[i].findex = findex + ofs[i]; - //joints[i]->vtable->getInfo2 (joints[i], Jinfo+i); - } - - } - - dReal *saveFacc = (dReal *) ALLOCA (nb * 4 * sizeof (dReal)); - dReal *saveTacc = (dReal *) ALLOCA (nb * 4 * sizeof (dReal)); - dReal *globalI = (dReal *) ALLOCA (nb * 12 * sizeof (dReal)); - dReal *globalInvI = (dReal *) ALLOCA (nb * 12 * sizeof (dReal)); - for (b = 0; b < nb; b++) - { - for (i = 0; i < 4; i++) - { - saveFacc[b * 4 + i] = bodies[b]->facc[i]; - saveTacc[b * 4 + i] = bodies[b]->tacc[i]; - } - bodies[b]->tag = b; - } - - for (iter = 0; iter < maxiterations; iter++) - { -# ifdef TIMING - dTimerNow ("applying inertia and gravity"); -# endif - dReal tmp[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - for (b = 0; b < nb; b++) - { - body = bodies[b]; - - // for all bodies, compute the inertia tensor and its inverse in the global - // frame, and compute the rotational force and add it to the torque - // accumulator. I and invI are vertically stacked 3x4 matrices, one per body. - // @@@ check computation of rotational force. - - // compute inertia tensor in global frame - dMULTIPLY2_333 (tmp, body->mass.I, body->R); - dMULTIPLY0_333 (globalI + b * 12, body->R, tmp); - // compute inverse inertia tensor in global frame - dMULTIPLY2_333 (tmp, body->invI, body->R); - dMULTIPLY0_333 (globalInvI + b * 12, body->R, tmp); - - for (i = 0; i < 4; i++) - body->tacc[i] = saveTacc[b * 4 + i]; - // compute rotational force - dMULTIPLY0_331 (tmp, globalI + b * 12, body->avel); - dCROSS (body->tacc, -=, body->avel, tmp); - - // add the gravity force to all bodies - if ((body->flags & dxBodyNoGravity) == 0) - { - body->facc[0] = saveFacc[b * 4 + 0] + body->mass.mass * world->gravity[0]; - body->facc[1] = saveFacc[b * 4 + 1] + body->mass.mass * world->gravity[1]; - body->facc[2] = saveFacc[b * 4 + 2] + body->mass.mass * world->gravity[2]; - body->facc[3] = 0; - } else { - body->facc[0] = saveFacc[b * 4 + 0]; - body->facc[1] = saveFacc[b * 4 + 1]; - body->facc[2] = saveFacc[b * 4 + 2]; - body->facc[3] = 0; - } - - } - -#ifdef RANDOM_JOINT_ORDER -#ifdef TIMING - dTimerNow ("randomizing joint order"); -#endif - //randomize the order of the joints by looping through the array - //and swapping the current joint pointer with a random one before it. - for (j = 0; j < nj; j++) - { - joint = joints[j]; - dxJoint::Info1 i1 = info[j]; - dxJoint::Info2 i2 = Jinfo[j]; - const int r = dRandInt(j+1); - joints[j] = joints[r]; - info[j] = info[r]; - Jinfo[j] = Jinfo[r]; - joints[r] = joint; - info[r] = i1; - Jinfo[r] = i2; - } -#endif - - //now iterate through the random ordered joint array we created. - for (j = 0; j < nj; j++) - { -#ifdef TIMING - dTimerNow ("setting up joint"); -#endif - joint = joints[j]; - bodyPair[0] = joint->node[0].body; - bodyPair[1] = joint->node[1].body; - - if (bodyPair[0] && (bodyPair[0]->flags & dxBodyDisabled)) - bodyPair[0] = 0; - if (bodyPair[1] && (bodyPair[1]->flags & dxBodyDisabled)) - bodyPair[1] = 0; - - //if this joint is not connected to any enabled bodies, skip it. - if (!bodyPair[0] && !bodyPair[1]) - continue; - - if (bodyPair[0]) - { - GIPair[0] = globalI + bodyPair[0]->tag * 12; - GinvIPair[0] = globalInvI + bodyPair[0]->tag * 12; - } - if (bodyPair[1]) - { - GIPair[1] = globalI + bodyPair[1]->tag * 12; - GinvIPair[1] = globalInvI + bodyPair[1]->tag * 12; - } - - joints[j]->vtable->getInfo2 (joints[j], Jinfo + j); - - //dInternalStepIslandFast is an exact copy of the old routine with one - //modification: the calculated forces are added back to the facc and tacc - //vectors instead of applying them to the bodies and moving them. - if (info[j].m > 0) - { - dInternalStepFast (world, bodyPair, GIPair, GinvIPair, joint, info[j], Jinfo[j], ministep); - } - } - // } -# ifdef TIMING - dTimerNow ("moving bodies"); -# endif - //Now we can simulate all the free floating bodies, and move them. - for (b = 0; b < nb; b++) - { - body = bodies[b]; - - for (i = 0; i < 4; i++) - { - body->facc[i] *= ministep; - body->tacc[i] *= ministep; - } - - //apply torque - dMULTIPLYADD0_331 (body->avel, globalInvI + b * 12, body->tacc); - - //apply force - for (i = 0; i < 3; i++) - body->lvel[i] += body->invMass * body->facc[i]; - - //move It! - moveAndRotateBody (body, ministep); - } - } - for (b = 0; b < nb; b++) - for (j = 0; j < 4; j++) - bodies[b]->facc[j] = bodies[b]->tacc[j] = 0; -} - - -#ifdef NO_ISLANDS - -// Since the iterative algorithm doesn't care about islands of bodies, this is a -// faster algorithm that just sends it all the joints and bodies in one array. -// It's downfall is it's inability to handle disabled bodies as well as the old one. -static void -processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations) -{ - // nothing to do if no bodies - if (world->nb <= 0) - return; - - dInternalHandleAutoDisabling (world,stepsize); - -# ifdef TIMING - dTimerStart ("creating joint and body arrays"); -# endif - dxBody **bodies, *body; - dxJoint **joints, *joint; - joints = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *)); - bodies = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *)); - - int nj = 0; - for (joint = world->firstjoint; joint; joint = (dxJoint *) joint->next) - joints[nj++] = joint; - - int nb = 0; - for (body = world->firstbody; body; body = (dxBody *) body->next) - bodies[nb++] = body; - - dInternalStepIslandFast (world, bodies, nb, joints, nj, stepsize, maxiterations); -# ifdef TIMING - dTimerEnd (); - dTimerReport (stdout, 1); -# endif -} - -#else - -//**************************************************************************** -// island processing - -// this groups all joints and bodies in a world into islands. all objects -// in an island are reachable by going through connected bodies and joints. -// each island can be simulated separately. -// note that joints that are not attached to anything will not be included -// in any island, an so they do not affect the simulation. -// -// this function starts new island from unvisited bodies. however, it will -// never start a new islands from a disabled body. thus islands of disabled -// bodies will not be included in the simulation. disabled bodies are -// re-enabled if they are found to be part of an active island. - -static void -processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations) -{ -#ifdef TIMING - dTimerStart ("Island Setup"); -#endif - dxBody *b, *bb, **body; - dxJoint *j, **joint; - - // nothing to do if no bodies - if (world->nb <= 0) - return; - - - dInternalHandleAutoDisabling (world,stepsize); - - // make arrays for body and joint lists (for a single island) to go into - body = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *)); - joint = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *)); - int bcount = 0; // number of bodies in `body' - int jcount = 0; // number of joints in `joint' - int tbcount = 0; - int tjcount = 0; - - // set all body/joint tags to 0 - for (b = world->firstbody; b; b = (dxBody *) b->next) - b->tag = 0; - for (j = world->firstjoint; j; j = (dxJoint *) j->next) - j->tag = 0; - - // allocate a stack of unvisited bodies in the island. the maximum size of - // the stack can be the lesser of the number of bodies or joints, because - // new bodies are only ever added to the stack by going through untagged - // joints. all the bodies in the stack must be tagged! - int stackalloc = (world->nj < world->nb) ? world->nj : world->nb; - dxBody **stack = (dxBody **) ALLOCA (stackalloc * sizeof (dxBody *)); - int *autostack = (int *) ALLOCA (stackalloc * sizeof (int)); - - for (bb = world->firstbody; bb; bb = (dxBody *) bb->next) - { -#ifdef TIMING - dTimerNow ("Island Processing"); -#endif - // get bb = the next enabled, untagged body, and tag it - if (bb->tag || (bb->flags & dxBodyDisabled)) - continue; - bb->tag = 1; - - // tag all bodies and joints starting from bb. - int stacksize = 0; - int autoDepth = autoEnableDepth; - b = bb; - body[0] = bb; - bcount = 1; - jcount = 0; - goto quickstart; - while (stacksize > 0) - { - b = stack[--stacksize]; // pop body off stack - autoDepth = autostack[stacksize]; - body[bcount++] = b; // put body on body list - quickstart: - - // traverse and tag all body's joints, add untagged connected bodies - // to stack - for (dxJointNode * n = b->firstjoint; n; n = n->next) - { - if (!n->joint->tag) - { - int thisDepth = autoEnableDepth; - n->joint->tag = 1; - joint[jcount++] = n->joint; - if (n->body && !n->body->tag) - { - if (n->body->flags & dxBodyDisabled) - thisDepth = autoDepth - 1; - if (thisDepth < 0) - continue; - n->body->flags &= ~dxBodyDisabled; - n->body->tag = 1; - autostack[stacksize] = thisDepth; - stack[stacksize++] = n->body; - } - } - } - dIASSERT (stacksize <= world->nb); - dIASSERT (stacksize <= world->nj); - } - - // now do something with body and joint lists - dInternalStepIslandFast (world, body, bcount, joint, jcount, stepsize, maxiterations); - - // what we've just done may have altered the body/joint tag values. - // we must make sure that these tags are nonzero. - // also make sure all bodies are in the enabled state. - int i; - for (i = 0; i < bcount; i++) - { - body[i]->tag = 1; - body[i]->flags &= ~dxBodyDisabled; - } - for (i = 0; i < jcount; i++) - joint[i]->tag = 1; - - tbcount += bcount; - tjcount += jcount; - } - -#ifdef TIMING - dMessage(0, "Total joints processed: %i, bodies: %i", tjcount, tbcount); -#endif - - // if debugging, check that all objects (except for disabled bodies, - // unconnected joints, and joints that are connected to disabled bodies) - // were tagged. -# ifndef dNODEBUG - for (b = world->firstbody; b; b = (dxBody *) b->next) - { - if (b->flags & dxBodyDisabled) - { - if (b->tag) - dDebug (0, "disabled body tagged"); - } - else - { - if (!b->tag) - dDebug (0, "enabled body not tagged"); - } - } - for (j = world->firstjoint; j; j = (dxJoint *) j->next) - { - if ((j->node[0].body && (j->node[0].body->flags & dxBodyDisabled) == 0) || (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled) == 0)) - { - if (!j->tag) - dDebug (0, "attached enabled joint not tagged"); - } - else - { - if (j->tag) - dDebug (0, "unattached or disabled joint tagged"); - } - } -# endif - -# ifdef TIMING - dTimerEnd (); - dTimerReport (stdout, 1); -# endif -} - -#endif - - -void dWorldStepFast1 (dWorldID w, dReal stepsize, int maxiterations) -{ - dUASSERT (w, "bad world argument"); - dUASSERT (stepsize > 0, "stepsize must be > 0"); - processIslandsFast (w, stepsize, maxiterations); -} diff --git a/Extras/ode/ode/src/testing.cpp b/Extras/ode/ode/src/testing.cpp deleted file mode 100644 index d55afc252..000000000 --- a/Extras/ode/ode/src/testing.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include -#include "testing.h" - -#ifdef dDOUBLE -static const dReal tol = 1.0e-9; -#else -static const dReal tol = 1.0e-5f; -#endif - - -// matrix header on the stack - -struct dMatrixComparison::dMatInfo { - int n,m; // size of matrix - char name[128]; // name of the matrix - dReal *data; // matrix data - int size; // size of `data' -}; - - - -dMatrixComparison::dMatrixComparison() -{ - afterfirst = 0; - index = 0; -} - - -dMatrixComparison::~dMatrixComparison() -{ - reset(); -} - - -dReal dMatrixComparison::nextMatrix (dReal *A, int n, int m, int lower_tri, - char *name, ...) -{ - if (A==0 || n < 1 || m < 1 || name==0) dDebug (0,"bad args to nextMatrix"); - int num = n*dPAD(m); - - if (afterfirst==0) { - dMatInfo *mi = (dMatInfo*) dAlloc (sizeof(dMatInfo)); - mi->n = n; - mi->m = m; - mi->size = num * sizeof(dReal); - mi->data = (dReal*) dAlloc (mi->size); - memcpy (mi->data,A,mi->size); - - va_list ap; - va_start (ap,name); - vsprintf (mi->name,name,ap); - if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long"); - - mat.push (mi); - return 0; - } - else { - if (lower_tri && n != m) - dDebug (0,"dMatrixComparison, lower triangular matrix must be square"); - if (index >= mat.size()) dDebug (0,"dMatrixComparison, too many matrices"); - dMatInfo *mp = mat[index]; - index++; - - dMatInfo mi; - va_list ap; - va_start (ap,name); - vsprintf (mi.name,name,ap); - if (strlen(mi.name) >= sizeof (mi.name)) dDebug (0,"name too long"); - - if (strcmp(mp->name,mi.name) != 0) - dDebug (0,"dMatrixComparison, name mismatch (\"%s\" and \"%s\")", - mp->name,mi.name); - if (mp->n != n || mp->m != m) - dDebug (0,"dMatrixComparison, size mismatch (%dx%d and %dx%d)", - mp->n,mp->m,n,m); - - dReal maxdiff; - if (lower_tri) { - maxdiff = dMaxDifferenceLowerTriangle (A,mp->data,n); - } - else { - maxdiff = dMaxDifference (A,mp->data,n,m); - } - if (maxdiff > tol) - dDebug (0,"dMatrixComparison, matrix error (size=%dx%d, name=\"%s\", " - "error=%.4e)",n,m,mi.name,maxdiff); - return maxdiff; - } -} - - -void dMatrixComparison::end() -{ - if (mat.size() <= 0) dDebug (0,"no matrices in sequence"); - afterfirst = 1; - index = 0; -} - - -void dMatrixComparison::reset() -{ - for (int i=0; idata,mat[i]->size); - dFree (mat[i],sizeof(dMatInfo)); - } - mat.setSize (0); - afterfirst = 0; - index = 0; -} - - -void dMatrixComparison::dump() -{ - for (int i=0; iname,mat[i]->n,mat[i]->m); -} - -//**************************************************************************** -// unit test - -#include - -static jmp_buf jump_buffer; - -static void myDebug (int num, const char *msg, va_list ap) -{ - // printf ("(Error %d: ",num); - // vprintf (msg,ap); - // printf (")\n"); - longjmp (jump_buffer,1); -} - - -extern "C" void dTestMatrixComparison() -{ - volatile int i; - printf ("dTestMatrixComparison()\n"); - dMessageFunction *orig_debug = dGetDebugHandler(); - - dMatrixComparison mc; - dReal A[50*50]; - - // make first sequence - unsigned long seed = dRandGetSeed(); - for (i=1; i<49; i++) { - dMakeRandomMatrix (A,i,i+1,1.0); - mc.nextMatrix (A,i,i+1,0,"A%d",i); - } - mc.end(); - - //mc.dump(); - - // test identical sequence - dSetDebugHandler (&myDebug); - dRandSetSeed (seed); - if (setjmp (jump_buffer)) { - printf ("\tFAILED (1)\n"); - } - else { - for (i=1; i<49; i++) { - dMakeRandomMatrix (A,i,i+1,1.0); - mc.nextMatrix (A,i,i+1,0,"A%d",i); - } - mc.end(); - printf ("\tpassed (1)\n"); - } - dSetDebugHandler (orig_debug); - - // test broken sequences (with matrix error) - dRandSetSeed (seed); - volatile int passcount = 0; - for (i=1; i<49; i++) { - if (setjmp (jump_buffer)) { - passcount++; - } - else { - dSetDebugHandler (&myDebug); - dMakeRandomMatrix (A,i,i+1,1.0); - A[(i-1)*dPAD(i+1)+i] += REAL(0.01); - mc.nextMatrix (A,i,i+1,0,"A%d",i); - dSetDebugHandler (orig_debug); - } - } - mc.end(); - printf ("\t%s (2)\n",(passcount == 48) ? "passed" : "FAILED"); - - // test broken sequences (with name error) - dRandSetSeed (seed); - passcount = 0; - for (i=1; i<49; i++) { - if (setjmp (jump_buffer)) { - passcount++; - } - else { - dSetDebugHandler (&myDebug); - dMakeRandomMatrix (A,i,i+1,1.0); - mc.nextMatrix (A,i,i+1,0,"B%d",i); - dSetDebugHandler (orig_debug); - } - } - mc.end(); - printf ("\t%s (3)\n",(passcount == 48) ? "passed" : "FAILED"); - - // test identical sequence again - dSetDebugHandler (&myDebug); - dRandSetSeed (seed); - if (setjmp (jump_buffer)) { - printf ("\tFAILED (4)\n"); - } - else { - for (i=1; i<49; i++) { - dMakeRandomMatrix (A,i,i+1,1.0); - mc.nextMatrix (A,i,i+1,0,"A%d",i); - } - mc.end(); - printf ("\tpassed (4)\n"); - } - dSetDebugHandler (orig_debug); -} diff --git a/Extras/ode/ode/src/testing.h b/Extras/ode/ode/src/testing.h deleted file mode 100644 index 4d19ff329..000000000 --- a/Extras/ode/ode/src/testing.h +++ /dev/null @@ -1,65 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* stuff used for testing */ - -#ifndef _ODE_TESTING_H_ -#define _ODE_TESTING_H_ - -#include -#include "array.h" - - -// compare a sequence of named matrices/vectors, i.e. to make sure that two -// different pieces of code are giving the same results. - -class dMatrixComparison { - struct dMatInfo; - dArray mat; - int afterfirst,index; - -public: - dMatrixComparison(); - ~dMatrixComparison(); - - dReal nextMatrix (dReal *A, int n, int m, int lower_tri, char *name, ...); - // add a new n*m matrix A to the sequence. the name of the matrix is given - // by the printf-style arguments (name,...). if this is the first sequence - // then this object will simply record the matrices and return 0. - // if this the second or subsequent sequence then this object will compare - // the matrices with the first sequence, and report any differences. - // the matrix error will be returned. if `lower_tri' is 1 then only the - // lower triangle of the matrix (including the diagonal) will be compared - // (the matrix must be square). - - void end(); - // end a sequence. - - void reset(); - // restarts the object, so the next sequence will be the first sequence. - - void dump(); - // print out info about all the matrices in the sequence -}; - - -#endif diff --git a/Extras/ode/ode/src/timer.cpp b/Extras/ode/ode/src/timer.cpp deleted file mode 100644 index 81df2595e..000000000 --- a/Extras/ode/ode/src/timer.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -/* - -TODO ----- - -* gettimeofday() and the pentium time stamp counter return the real time, - not the process time. fix this somehow! - -*/ - -#include -#include - -// misc defines -#define ALLOCA dALLOCA16 - -//**************************************************************************** -// implementation for windows based on the multimedia performance counter. - -#ifdef WIN32 - -#include "windows.h" - -static inline void getClockCount (unsigned long cc[2]) -{ - LARGE_INTEGER a; - QueryPerformanceCounter (&a); - cc[0] = a.LowPart; - cc[1] = a.HighPart; -} - - -static inline void serialize() -{ -} - - -static inline double loadClockCount (unsigned long cc[2]) -{ - LARGE_INTEGER a; - a.LowPart = cc[0]; - a.HighPart = cc[1]; - return double(a.QuadPart); -} - - -double dTimerResolution() -{ - return 1.0/dTimerTicksPerSecond(); -} - - -double dTimerTicksPerSecond() -{ - static int query=0; - static double hz=0.0; - if (!query) { - LARGE_INTEGER a; - QueryPerformanceFrequency (&a); - hz = double(a.QuadPart); - query = 1; - } - return hz; -} - -#endif - -//**************************************************************************** -// implementation based on the pentium time stamp counter. the timer functions -// can be serializing or non-serializing. serializing will ensure that all -// instructions have executed and data has been written back before the cpu -// time stamp counter is read. the CPUID instruction is used to serialize. - -#if defined(PENTIUM) && !defined(WIN32) - -// we need to know the clock rate so that the timing function can report -// accurate times. this number only needs to be set accurately if we're -// doing performance tests and care about real-world time numbers - otherwise, -// just ignore this. i have not worked out how to determine this number -// automatically yet. - -#define PENTIUM_HZ (500e6) - - -static inline void getClockCount (unsigned long cc[2]) -{ - asm volatile ( - "rdtsc\n" - "movl %%eax,(%%esi)\n" - "movl %%edx,4(%%esi)\n" - : : "S" (cc) : "%eax","%edx","cc","memory"); -} - - -static inline void serialize() -{ - asm volatile ( - "mov $0,%%eax\n" - "cpuid\n" - : : : "%eax","%ebx","%ecx","%edx","cc","memory"); -} - - -static inline double loadClockCount (unsigned long a[2]) -{ - double ret; - asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) : - "cc","memory"); - return ret; -} - - -double dTimerResolution() -{ - return 1.0/PENTIUM_HZ; -} - - -double dTimerTicksPerSecond() -{ - return PENTIUM_HZ; -} - -#endif - -//**************************************************************************** -// otherwise, do the implementation based on gettimeofday(). - -#if !defined(PENTIUM) && !defined(WIN32) - -#ifndef macintosh - -#include -#include - - -static inline void getClockCount (unsigned long cc[2]) -{ - struct timeval tv; - gettimeofday (&tv,0); - cc[0] = tv.tv_usec; - cc[1] = tv.tv_sec; -} - -#else // macintosh - -#include -#include - -static inline void getClockCount (unsigned long cc[2]) -{ - UnsignedWide ms; - Microseconds (&ms); - cc[1] = ms.lo / 1000000; - cc[0] = ms.lo - ( cc[1] * 1000000 ); -} - -#endif - - -static inline void serialize() -{ -} - - -static inline double loadClockCount (unsigned long a[2]) -{ - return a[1]*1.0e6 + a[0]; -} - - -double dTimerResolution() -{ - unsigned long cc1[2],cc2[2]; - getClockCount (cc1); - do { - getClockCount (cc2); - } - while (cc1[0]==cc2[0] && cc1[1]==cc2[1]); - do { - getClockCount (cc1); - } - while (cc1[0]==cc2[0] && cc1[1]==cc2[1]); - double t1 = loadClockCount (cc1); - double t2 = loadClockCount (cc2); - return (t1-t2) / dTimerTicksPerSecond(); -} - - -double dTimerTicksPerSecond() -{ - return 1000000; -} - -#endif - -//**************************************************************************** -// stop watches - -void dStopwatchReset (dStopwatch *s) -{ - s->time = 0; - s->cc[0] = 0; - s->cc[1] = 0; -} - - -void dStopwatchStart (dStopwatch *s) -{ - serialize(); - getClockCount (s->cc); -} - - -void dStopwatchStop (dStopwatch *s) -{ - unsigned long cc[2]; - serialize(); - getClockCount (cc); - double t1 = loadClockCount (s->cc); - double t2 = loadClockCount (cc); - s->time += t2-t1; -} - - -double dStopwatchTime (dStopwatch *s) -{ - return s->time / dTimerTicksPerSecond(); -} - -//**************************************************************************** -// code timers - -// maximum number of events to record -#define MAXNUM 100 - -static int num = 0; // number of entries used in event array -static struct { - unsigned long cc[2]; // clock counts - double total_t; // total clocks used in this slot. - double total_p; // total percentage points used in this slot. - int count; // number of times this slot has been updated. - char *description; // pointer to static string -} event[MAXNUM]; - - -// make sure all slot totals and counts reset to 0 at start - -static void initSlots() -{ - static int initialized=0; - if (!initialized) { - for (int i=0; i (description); - num = 1; - serialize(); - getClockCount (event[0].cc); -} - - -void dTimerNow (const char *description) -{ - if (num < MAXNUM) { - // do not serialize - getClockCount (event[num].cc); - event[num].description = const_cast (description); - num++; - } -} - - -void dTimerEnd() -{ - if (num < MAXNUM) { - serialize(); - getClockCount (event[num].cc); - event[num].description = "TOTAL"; - num++; - } -} - -//**************************************************************************** -// print report - -static void fprintDoubleWithPrefix (FILE *f, double a, char *fmt) -{ - if (a >= 0.999999) { - fprintf (f,fmt,a); - return; - } - a *= 1000.0; - if (a >= 0.999999) { - fprintf (f,fmt,a); - fprintf (f,"m"); - return; - } - a *= 1000.0; - if (a >= 0.999999) { - fprintf (f,fmt,a); - fprintf (f,"u"); - return; - } - a *= 1000.0; - fprintf (f,fmt,a); - fprintf (f,"n"); -} - - -void dTimerReport (FILE *fout, int average) -{ - int i; - size_t maxl; - double ccunit = 1.0/dTimerTicksPerSecond(); - fprintf (fout,"\nTimer Report ("); - fprintDoubleWithPrefix (fout,ccunit,"%.2f "); - fprintf (fout,"s resolution)\n------------\n"); - if (num < 1) return; - - // get maximum description length - maxl = 0; - for (i=0; i maxl) maxl = l; - } - - // calculate total time - double t1 = loadClockCount (event[0].cc); - double t2 = loadClockCount (event[num-1].cc); - double total = t2 - t1; - if (total <= 0) total = 1; - - // compute time difference for all slots except the last one. update totals - double *times = (double*) ALLOCA (num * sizeof(double)); - for (i=0; i < (num-1); i++) { - double t1 = loadClockCount (event[i].cc); - double t2 = loadClockCount (event[i+1].cc); - times[i] = t2 - t1; - event[i].count++; - event[i].total_t += times[i]; - event[i].total_p += times[i]/total * 100.0; - } - - // print report (with optional averages) - for (i=0; ifirstbody; bb; bb=(dxBody*)bb->next) { - // nothing to do unless this body is currently enabled and has - // the auto-disable flag set - if ((bb->flags & (dxBodyAutoDisable|dxBodyDisabled)) != dxBodyAutoDisable) continue; - - // see if the body is idle - int idle = 1; // initial assumption - dReal lspeed2 = dDOT(bb->lvel,bb->lvel); - if (lspeed2 > bb->adis.linear_threshold) { - idle = 0; // moving fast - not idle - } - else { - dReal aspeed = dDOT(bb->avel,bb->avel); - if (aspeed > bb->adis.angular_threshold) { - idle = 0; // turning fast - not idle - } - } - - // if it's idle, accumulate steps and time. - // these counters won't overflow because this code doesn't run for disabled bodies. - if (idle) { - bb->adis_stepsleft--; - bb->adis_timeleft -= stepsize; - } - else { - bb->adis_stepsleft = bb->adis.idle_steps; - bb->adis_timeleft = bb->adis.idle_time; - } - - // disable the body if it's idle for a long enough time - if (bb->adis_stepsleft < 0 && bb->adis_timeleft < 0) { - bb->flags |= dxBodyDisabled; - } - } -} - - -//**************************************************************************** -// body rotation - -// return sin(x)/x. this has a singularity at 0 so special handling is needed -// for small arguments. - -static inline dReal sinc (dReal x) -{ - // if |x| < 1e-4 then use a taylor series expansion. this two term expansion - // is actually accurate to one LS bit within this range if double precision - // is being used - so don't worry! - if (dFabs(x) < 1.0e-4) return REAL(1.0) - x*x*REAL(0.166666666666666666667); - else return dSin(x)/x; -} - - -// given a body b, apply its linear and angular rotation over the time -// interval h, thereby adjusting its position and orientation. - -void dxStepBody (dxBody *b, dReal h) -{ - int j; - - // handle linear velocity - for (j=0; j<3; j++) b->pos[j] += h * b->lvel[j]; - - if (b->flags & dxBodyFlagFiniteRotation) { - dVector3 irv; // infitesimal rotation vector - dQuaternion q; // quaternion for finite rotation - - if (b->flags & dxBodyFlagFiniteRotationAxis) { - // split the angular velocity vector into a component along the finite - // rotation axis, and a component orthogonal to it. - dVector3 frv; // finite rotation vector - dReal k = dDOT (b->finite_rot_axis,b->avel); - frv[0] = b->finite_rot_axis[0] * k; - frv[1] = b->finite_rot_axis[1] * k; - frv[2] = b->finite_rot_axis[2] * k; - irv[0] = b->avel[0] - frv[0]; - irv[1] = b->avel[1] - frv[1]; - irv[2] = b->avel[2] - frv[2]; - - // make a rotation quaternion q that corresponds to frv * h. - // compare this with the full-finite-rotation case below. - h *= REAL(0.5); - dReal theta = k * h; - q[0] = dCos(theta); - dReal s = sinc(theta) * h; - q[1] = frv[0] * s; - q[2] = frv[1] * s; - q[3] = frv[2] * s; - } - else { - // make a rotation quaternion q that corresponds to w * h - dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] + - b->avel[2]*b->avel[2]); - h *= REAL(0.5); - dReal theta = wlen * h; - q[0] = dCos(theta); - dReal s = sinc(theta) * h; - q[1] = b->avel[0] * s; - q[2] = b->avel[1] * s; - q[3] = b->avel[2] * s; - } - - // do the finite rotation - dQuaternion q2; - dQMultiply0 (q2,q,b->q); - for (j=0; j<4; j++) b->q[j] = q2[j]; - - // do the infitesimal rotation if required - if (b->flags & dxBodyFlagFiniteRotationAxis) { - dReal dq[4]; - dWtoDQ (irv,b->q,dq); - for (j=0; j<4; j++) b->q[j] += h * dq[j]; - } - } - else { - // the normal way - do an infitesimal rotation - dReal dq[4]; - dWtoDQ (b->avel,b->q,dq); - for (j=0; j<4; j++) b->q[j] += h * dq[j]; - } - - // normalize the quaternion and convert it to a rotation matrix - dNormalize4 (b->q); - dQtoR (b->q,b->R); - - // notify all attached geoms that this body has moved - for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) - dGeomMoved (geom); -} - -//**************************************************************************** -// island processing - -// this groups all joints and bodies in a world into islands. all objects -// in an island are reachable by going through connected bodies and joints. -// each island can be simulated separately. -// note that joints that are not attached to anything will not be included -// in any island, an so they do not affect the simulation. -// -// this function starts new island from unvisited bodies. however, it will -// never start a new islands from a disabled body. thus islands of disabled -// bodies will not be included in the simulation. disabled bodies are -// re-enabled if they are found to be part of an active island. - -void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper) -{ - dxBody *b,*bb,**body; - dxJoint *j,**joint; - - // nothing to do if no bodies - if (world->nb <= 0) return; - - // handle auto-disabling of bodies - dInternalHandleAutoDisabling (world,stepsize); - - // make arrays for body and joint lists (for a single island) to go into - body = (dxBody**) ALLOCA (world->nb * sizeof(dxBody*)); - joint = (dxJoint**) ALLOCA (world->nj * sizeof(dxJoint*)); - int bcount = 0; // number of bodies in `body' - int jcount = 0; // number of joints in `joint' - - // set all body/joint tags to 0 - for (b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0; - for (j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0; - - // allocate a stack of unvisited bodies in the island. the maximum size of - // the stack can be the lesser of the number of bodies or joints, because - // new bodies are only ever added to the stack by going through untagged - // joints. all the bodies in the stack must be tagged! - int stackalloc = (world->nj < world->nb) ? world->nj : world->nb; - dxBody **stack = (dxBody**) ALLOCA (stackalloc * sizeof(dxBody*)); - - for (bb=world->firstbody; bb; bb=(dxBody*)bb->next) { - // get bb = the next enabled, untagged body, and tag it - if (bb->tag || (bb->flags & dxBodyDisabled)) continue; - bb->tag = 1; - - // tag all bodies and joints starting from bb. - int stacksize = 0; - b = bb; - body[0] = bb; - bcount = 1; - jcount = 0; - goto quickstart; - while (stacksize > 0) { - b = stack[--stacksize]; // pop body off stack - body[bcount++] = b; // put body on body list - quickstart: - - // traverse and tag all body's joints, add untagged connected bodies - // to stack - for (dxJointNode *n=b->firstjoint; n; n=n->next) { - if (!n->joint->tag) { - n->joint->tag = 1; - joint[jcount++] = n->joint; - if (n->body && !n->body->tag) { - n->body->tag = 1; - stack[stacksize++] = n->body; - } - } - } - dIASSERT(stacksize <= world->nb); - dIASSERT(stacksize <= world->nj); - } - - // now do something with body and joint lists - stepper (world,body,bcount,joint,jcount,stepsize); - - // what we've just done may have altered the body/joint tag values. - // we must make sure that these tags are nonzero. - // also make sure all bodies are in the enabled state. - int i; - for (i=0; itag = 1; - body[i]->flags &= ~dxBodyDisabled; - } - for (i=0; itag = 1; - } - - // if debugging, check that all objects (except for disabled bodies, - // unconnected joints, and joints that are connected to disabled bodies) - // were tagged. -# ifndef dNODEBUG - for (b=world->firstbody; b; b=(dxBody*)b->next) { - if (b->flags & dxBodyDisabled) { - if (b->tag) dDebug (0,"disabled body tagged"); - } - else { - if (!b->tag) dDebug (0,"enabled body not tagged"); - } - } - for (j=world->firstjoint; j; j=(dxJoint*)j->next) { - if ((j->node[0].body && (j->node[0].body->flags & dxBodyDisabled)==0) || - (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled)==0)) { - if (!j->tag) dDebug (0,"attached enabled joint not tagged"); - } - else { - if (j->tag) dDebug (0,"unattached or disabled joint tagged"); - } - } -# endif -} diff --git a/Extras/ode/ode/src/util.h b/Extras/ode/ode/src/util.h deleted file mode 100644 index a8e639020..000000000 --- a/Extras/ode/ode/src/util.h +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#ifndef _ODE_UTIL_H_ -#define _ODE_UTIL_H_ - -#include "objects.h" - - -void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize); -void dxStepBody (dxBody *b, dReal h); - -typedef void (*dstepper_fn_t) (dxWorld *world, dxBody * const *body, int nb, - dxJoint * const *_joint, int nj, dReal stepsize); - -void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper); - - -#endif diff --git a/Extras/ode/ode/test/test_BulletGjk.cpp b/Extras/ode/ode/test/test_BulletGjk.cpp deleted file mode 100644 index 79b08e6e1..000000000 --- a/Extras/ode/ode/test/test_BulletGjk.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -///Bullet Continuous Collision Detection and Physics Engine: - - - - - -#include -#include -//#include -#include "CollisionDispatch/CollisionObject.h" -#include "CollisionDispatch/CollisionWorld.h" -#include "BroadphaseCollision/SimpleBroadphase.h" -#include "BroadphaseCollision/AxisSweep3.h" - - -#include "CollisionDispatch/CollisionDispatcher.h" - -#include "CollisionShapes/BoxShape.h" -#include "CollisionShapes/SphereShape.h" -#include "CollisionShapes/CylinderShape.h" - - - -#ifdef _MSC_VER -#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints -#endif - -// select correct drawing functions - -#ifdef dDOUBLE -#define dsDrawBox dsDrawBoxD -#define dsDrawSphere dsDrawSphereD -#define dsDrawCylinder dsDrawCylinderD -#define dsDrawCappedCylinder dsDrawCappedCylinderD -#endif - - -// some constants - -#define NUM 100 // max number of objects -#define DENSITY (5.0) // density of all objects -#define GPB 3 // maximum number of geometries per body -#define MAX_CONTACTS 4 // maximum number of contact points per body - - -// dynamics and collision objects - -struct MyObject { - dBodyID body; // the body - CollisionObject collider; //the collisionShape -}; - -static int num=0; // number of objects in simulation -static int nextobj=0; // next object to recycle if num==NUM -static dWorldID world; - -CollisionWorld* collisionWorld = 0; - -static MyObject obj[NUM]; -static dJointGroupID contactgroup; -static int selected = -1; // selected object -static int show_aabb = 0; // show geom AABBs? -static int show_contacts = 0; // show contact points? -static int random_pos = 1; // drop objects from random position? -static int write_world = 0; - - - -SimdTransform GetTransformFromOde(const dReal* pos,const dReal* rot) -{ - SimdTransform trans; - trans.setIdentity(); - -// rot is pointer to object's rotation matrix, 4*3 format! - - SimdMatrix3x3 orn(rot[0],rot[1],rot[2], - rot[4],rot[5],rot[6], - rot[8],rot[9],rot[10]); - - trans.setOrigin(SimdVector3(pos[0],pos[1],pos[2])); - trans.setBasis(orn); - - return trans; -} - -void GetOdeFromTransform(const SimdTransform& trans,dReal* pos,dReal* rot) -{ - pos[0] = trans.getOrigin().x(); - pos[1] = trans.getOrigin().y(); - pos[2] = trans.getOrigin().z(); - - rot[0] = trans.getBasis()[0][0]; - rot[1] = trans.getBasis()[0][1]; - rot[2] = trans.getBasis()[0][2]; - - rot[4] = trans.getBasis()[1][0]; - rot[5] = trans.getBasis()[1][1]; - rot[6] = trans.getBasis()[1][2]; - - rot[8] = trans.getBasis()[2][0]; - rot[9] = trans.getBasis()[2][1]; - rot[10] = trans.getBasis()[2][2]; - -} - - - -// start simulation - set viewpoint - -static void start() -{ - static float xyz[3] = {2.1640f,-1.3079f,1.7600f}; - static float hpr[3] = {125.5000f,-17.0000f,0.0000f}; - dsSetViewpoint (xyz,hpr); - printf ("To drop another object, press:\n"); - printf (" b for box.\n"); - printf (" s for sphere.\n"); - printf (" c for cylinder.\n"); - printf (" x for a composite object.\n"); - printf ("To select an object, press space.\n"); - printf ("To disable the selected object, press d.\n"); - printf ("To enable the selected object, press e.\n"); - printf ("To toggle showing the geom AABBs, press a.\n"); - printf ("To toggle showing the contact points, press t.\n"); - printf ("To toggle dropping from random position/orientation, press r.\n"); - printf ("To save the current state to 'state.dif', press 1.\n"); -} - - -char locase (char c) -{ - if (c >= 'A' && c <= 'Z') return c - ('a'-'A'); - else return c; -} - - -// called when a key pressed - -static void command (int cmd) -{ - size_t i; - int j,k; - dReal sides[3]; - dMass m; - - cmd = locase (cmd); - if (cmd == 'b' || cmd == 's' || cmd == 'c' - /* || cmd == 'l' */) { - if (num < NUM) { - i = num; - num++; - } - else { - i = nextobj; - nextobj++; - if (nextobj >= num) nextobj = 0; - - // destroy the body and geoms for slot i - dBodyDestroy (obj[i].body); - collisionWorld->RemoveCollisionObject(&obj[i].collider); - obj[i].collider.m_broadphaseHandle = (BroadphaseProxy*)(-1); - - - //todo: destroy collider - } - - obj[i].body = dBodyCreate (world); - for (k=0; k<3; k++) sides[k] = dRandReal()*0.2+0.1; - - dMatrix3 R; - if (random_pos) { - dBodySetPosition (obj[i].body, - dRandReal()*2-1,dRandReal()*2-1,dRandReal()+2); - dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, - dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); - } - else { - dReal maxheight = 0; - for (k=0; k maxheight) maxheight = pos[2]; - } - dBodySetPosition (obj[i].body, 0,0,maxheight+0.3); - dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); - } - dBodySetRotation (obj[i].body,R); - dBodySetData (obj[i].body,(void*) i); - - if (cmd == 'b') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - obj[i].collider.m_collisionShape = new BoxShape(SimdVector3(0.5*sides[0],0.5*sides[1],0.5*sides[2])); - obj[i].collider.m_worldTransform = GetTransformFromOde(dBodyGetPosition(obj[i].body),dBodyGetRotation(obj[i].body)); - collisionWorld->AddCollisionObject(&obj[i].collider); - obj[i].collider.m_userPointer = obj[i].body; - - } - else if (cmd == 'c') { - sides[0] *= 0.2; - sides[1] *= 0.2; - sides[2] *= 0.2; - dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); - obj[i].collider.m_collisionShape = new CylinderShapeZ(SimdVector3(sides[0],sides[1],sides[1])); - obj[i].collider.m_worldTransform = GetTransformFromOde(dBodyGetPosition(obj[i].body),dBodyGetRotation(obj[i].body)); - collisionWorld->AddCollisionObject(&obj[i].collider); - obj[i].collider.m_userPointer = obj[i].body; - //obj[i].geom[0] = dCreateCCylinder (space,sides[0],sides[1]); - } -/* - // cylinder option not yet implemented - else if (cmd == 'l') { - sides[1] *= 0.5; - dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); - obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); - } -*/ - else if (cmd == 's') { - sides[0] *= 0.5; - dMassSetSphere (&m,DENSITY,sides[0]); - obj[i].collider.m_collisionShape = new SphereShape(sides[0]); - - - obj[i].collider.m_worldTransform = GetTransformFromOde(dBodyGetPosition(obj[i].body),dBodyGetRotation(obj[i].body)); - collisionWorld->AddCollisionObject(&obj[i].collider); - obj[i].collider.m_userPointer = obj[i].body; - - //obj[i].geom[0] = dCreateSphere (space,sides[0]); - } - else if (cmd == 'x') { - - - - } - - for (k=0; k < GPB; k++) { - //if (obj[i].geom[k]) - // dGeomSetBody (obj[i].geom[k],obj[i].body); - } - - dBodySetMass (obj[i].body,&m); - } - - if (cmd == ' ') { - selected++; - if (selected >= num) selected = 0; - if (selected < 0) selected = 0; - } - else if (cmd == 'd' && selected >= 0 && selected < num) { - dBodyDisable (obj[selected].body); - } - else if (cmd == 'e' && selected >= 0 && selected < num) { - dBodyEnable (obj[selected].body); - } - else if (cmd == 'a') { - show_aabb ^= 1; - } - else if (cmd == 't') { - show_contacts ^= 1; - } - else if (cmd == 'r') { - random_pos ^= 1; - } - else if (cmd == '1') { - write_world = 1; - } -} - - -// draw a geom - -void drawGeom (CollisionObject& collider)//, const dReal *pos, const dReal *R, int show_aabb) -{ - dReal pos[4]; - dReal R[16]; - - GetOdeFromTransform(collider.m_worldTransform,&pos[0],&R[0]); - - int i; - - if (!collider.m_collisionShape) return; - - int type = collider.m_collisionShape->GetShapeType(); - - if (type == BOX_SHAPE_PROXYTYPE) { - dVector3 sides; - BoxShape* boxShape = static_cast(collider.m_collisionShape); - sides[0] = 2.f*boxShape->GetHalfExtents().x(); - sides[1] = 2.f*boxShape->GetHalfExtents().y(); - sides[2] = 2.f*boxShape->GetHalfExtents().z(); - ///boxshape already has margins 'inside' - dsDrawBox (pos,R,sides); - - } - else if (type == SPHERE_SHAPE_PROXYTYPE) { - SphereShape* sphereShape = static_cast(collider.m_collisionShape); - dReal radius = sphereShape->GetMargin(); - - dsDrawSphere (pos,R,radius); - - } - - else if (type == CYLINDER_SHAPE_PROXYTYPE) { - - CylinderShapeZ* cylinder = static_cast(collider.m_collisionShape); - dReal radius = cylinder->GetHalfExtents()[0]; - dReal length = 2.f*cylinder->GetHalfExtents()[1]; - radius += cylinder->GetMargin(); - length += 2.f*cylinder->GetMargin(); - - //dGeomCCylinderGetParams (g,&radius,&length); - dsDrawCylinder (pos,R,length,radius); - } -/* - // cylinder option not yet implemented - else if (type == dCylinderClass) { - dReal radius,length; - dGeomCylinderGetParams (g,&radius,&length); - dsDrawCylinder (pos,R,length,radius); - } - - else if (type == dGeomTransformClass) { - dGeomID g2 = dGeomTransformGetGeom (g); - const dReal *pos2 = dGeomGetPosition (g2); - const dReal *R2 = dGeomGetRotation (g2); - dVector3 actual_pos; - dMatrix3 actual_R; - dMULTIPLY0_331 (actual_pos,R,pos2); - actual_pos[0] += pos[0]; - actual_pos[1] += pos[1]; - actual_pos[2] += pos[2]; - dMULTIPLY0_333 (actual_R,R,R2); - drawGeom (g2,actual_pos,actual_R,0); - } - - if (show_aabb) { - // draw the bounding box for this geom - dReal aabb[6]; - dGeomGetAABB (g,aabb); - dVector3 bbpos; - for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); - dVector3 bbsides; - for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2]; - dMatrix3 RI; - dRSetIdentity (RI); - dsSetColorAlpha (1,0,0,0.5); - dsDrawBox (bbpos,RI,bbsides); - } -*/ -} - - -// simulation loop - -static void simLoop (int pause) -{ - dsSetColor (0,0,2); - //dSpaceCollide (space,0,&nearCallback); - collisionWorld->PerformDiscreteCollisionDetection(); - //now the collisionWorld contains all contact points... just copy them over to ODE and that's it - - for (int i=0;iGetDispatcher()->GetNumManifolds();i++) - { - PersistentManifold* manifold = collisionWorld->GetDispatcher()->GetManifoldByIndexInternal(i); - CollisionObject* obj0 = static_cast(manifold->GetBody0()); - CollisionObject* obj1 = static_cast(manifold->GetBody1()); - - //RefreshContactPoints will update and/or remove existing contactpoints from previous frames - manifold->RefreshContactPoints(obj0->m_worldTransform,obj1->m_worldTransform); - for (int j=0;jGetNumContacts();j++) - { - ManifoldPoint& pt = manifold->GetContactPoint(j); - if (pt.GetDistance()<0.f) - { - //report point to ODE - - dContact contact; - contact.surface.mode = dContactBounce | dContactSoftCFM; - contact.surface.mu = 10.f;//dInfinity; - contact.surface.mu2 = 0; - contact.surface.bounce = 0.1; - contact.surface.bounce_vel = 0.1; - contact.surface.soft_cfm = 0.01; - contact.geom.depth = -pt.GetDistance(); - - - contact.geom.normal[0] = pt.m_normalWorldOnB.x(); - contact.geom.normal[1] = pt.m_normalWorldOnB.y(); - contact.geom.normal[2] = pt.m_normalWorldOnB.z(); - //contact.geom.g1 does it really need this? - contact.geom.g1 = 0; - contact.geom.g2 = 0; - contact.geom.pos[0] = pt.GetPositionWorldOnB().x(); - contact.geom.pos[1] = pt.GetPositionWorldOnB().y(); - contact.geom.pos[2] = pt.GetPositionWorldOnB().z(); - - contact.fdir1[0] = 0.f; - contact.fdir1[1] = 0.f; - contact.fdir1[2] = 0.f; - - - dJointID c = dJointCreateContact (world,contactgroup,&contact); - dBodyID b1 = (dBodyID)obj0->m_userPointer; - dBodyID b2 = (dBodyID)obj1->m_userPointer; - dJointAttach (c,b1,b2); - if (show_contacts) - { - dMatrix3 RI; - dRSetIdentity (RI); - const dReal ss[3] = {0.02,0.02,0.02}; - dsDrawBox (contact.geom.pos,RI,ss); - } - - } - - - - - - } - } - - - - if (!pause) dWorldQuickStep (world,0.05); - - if (write_world) { - FILE *f = fopen ("state.dif","wt"); - if (f) { - dWorldExportDIF (world,f,"X"); - fclose (f); - } - write_world = 0; - } - - // remove all contact joints - dJointGroupEmpty (contactgroup); - - dsSetColor (1,1,0); - dsSetTexture (DS_WOOD); - for (int i=0; iSetMargin(0.005f); - collisionWorld->AddCollisionObject(&groundPlane); - groundPlane.m_userPointer = 0; - - memset (obj,0,sizeof(obj)); - - // run simulation - dsSimulationLoop (argc,argv,352,288,&fn); - - dJointGroupDestroy (contactgroup); - - delete collisionWorld; - dWorldDestroy (world); - - return 0; -} diff --git a/Extras/ode/ode/test/test_convex_stack.cpp b/Extras/ode/ode/test/test_convex_stack.cpp deleted file mode 100644 index e2b20369a..000000000 --- a/Extras/ode/ode/test/test_convex_stack.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "../../ode/ode/src/objects.h" //for iterating objects in the world -#include "BulletOdeCollide.h" -#include -#include - -#include -#include -#include "GeomToShape.h" -#include "BulletOdeTransformConvert.h" - -#ifdef _MSC_VER -#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints -#endif - -// select correct drawing functions - -#ifdef dDOUBLE -#define dsDrawBox dsDrawBoxD -#define dsDrawSphere dsDrawSphereD -#define dsDrawCylinder dsDrawCylinderD -#define dsDrawCappedCylinder dsDrawCappedCylinderD -#define dsDrawTriangle dsDrawTriangleD -#endif - - -// some constants - -#define NUM 100 //100 // max number of objects -#define DENSITY (5.0) // density of all objects -#define GPB 3 // maximum number of geometries per body -#define MAX_CONTACTS 4 // maximum number of contact points per body - - -// dynamics and collision objects - -struct MyObject { - dBodyID body; // the body - dGeomID geom[GPB]; // geometries representing this body -}; - -static int num=0; // number of objects in simulation -static int nextobj=0; // next object to recycle if num==NUM -static dWorldID world; -static dSpaceID space; -static MyObject obj[NUM]; - -CollisionObject* bulletObjects[NUM]; - - -static dJointGroupID contactgroup; -static int selected = -1; // selected object -static int show_aabb = 0; // show geom AABBs? -static int show_contacts = 0; // show contact points? -static int random_pos = 1; // drop objects from random position? -static int write_world = 0; - -//sample convex hull vertices + graphics indices (tetrahedron) -//the distance from each of these four points to the origin is 3sqrt(2/3)/4. -const int VertexCount = 4; -const int IndexCount = 4 * 3; - -typedef dReal dVector3R[3]; - -CollisionWorld* colWorld = 0; - - -dGeomID TriMesh1; -dGeomID TriMesh2; -static dTriMeshDataID TriData1, TriData2; // reusable static trimesh data - -float ConvexVertices[VertexCount*3] = { - REAL(-1./2.),REAL(-sqrt(3.)/6.), REAL(-sqrt(2./3.)/4.), - REAL(1./2.),REAL(-sqrt(3.)/6.),REAL(-sqrt(2./3.)/4.), - REAL(0.),REAL(2.*sqrt(3.)/6.),REAL(-sqrt(2./3.)/4.), - REAL(0.),REAL(0.),REAL(3.*sqrt(2./3.)/4.) - }; - -int ConvexIndices[IndexCount / 3][3] = { - {2,1,0}, - {1,3,0}, - {2,3,1}, - {0,3,2} -}; - - - -// this is called by dSpaceCollide when two objects in space are -// potentially colliding. - -static void nearCallback (void *data, dGeomID o1, dGeomID o2) -{ - int i; - // if (o1->body && o2->body) return; - - // exit without doing anything if the two bodies are connected by a joint - dBodyID b1 = dGeomGetBody(o1); - dBodyID b2 = dGeomGetBody(o2); - if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; - - dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box - for (i=0; i= 'A' && c <= 'Z') return c - ('a'-'A'); - else return c; -} - - -// called when a key pressed - -static void command (int cmd) -{ - size_t i; - int j,k; - dReal sides[3]; - dMass m; - - cmd = locase (cmd); - if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == '1' || cmd == '2' ||cmd == '3' || cmd == '4' - ) { - if (num < NUM) { - i = num; - num++; - } - else { - i = nextobj; - nextobj++; - if (nextobj >= num) nextobj = 0; - - // destroy the body and geoms for slot i - dBodyDestroy (obj[i].body); - - for (k=0; k < GPB; k++) { - if (obj[i].geom[k]) - { - dGeomDestroy (obj[i].geom[k]); - RemoveOdeGeomFromCollisionCache(obj[i].geom[k]); - - } else - { - if (bulletObjects[i]) - { - colWorld->RemoveCollisionObject(bulletObjects[i]); - delete bulletObjects[i]; - bulletObjects[i] = 0; - } - } - } - memset (&obj[i],0,sizeof(obj[i])); - } - - obj[i].body = dBodyCreate (world); - for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; - - dMatrix3 R; - if (random_pos) { - dBodySetPosition (obj[i].body, - dRandReal()*2-1,dRandReal()*2-1,dRandReal()+2); - dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, - dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); - } - else { - dReal maxheight = 0; - for (k=0; k maxheight) maxheight = pos[2]; - } - dBodySetPosition (obj[i].body, 0,0,maxheight+1); - dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); - } - dBodySetRotation (obj[i].body,R); - dBodySetData (obj[i].body,(void*) i); - - if (cmd == 'b') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); - - dGeomID boxId = obj[i].geom[0]; - - /* - CollisionShape* boxShape = CreateShapeFromGeom(boxId); - bulletObjects[i] = new CollisionObject; - //from BulletOdeTransformConvert.h - bulletObjects[i]->m_worldTransform = GetTransformFromGeom(boxId); - bulletObjects[i]->SetCollisionShape(boxShape); - colWorld->AddCollisionObject(bulletObjects[i]); - */ - - - } - else if (cmd == 'c') { - sides[0] *= 0.5; - dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); - obj[i].geom[0] = dCreateCCylinder (space,sides[0],sides[1]); - - } - - // cylinder option not yet implemented - else if (cmd == '1') { - sides[1] *= 0.5; - dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); - // obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); - SimdVector3 boxHalfExtents(0.5*sides[0],0.5*sides[0],0.5*sides[1]); - CollisionShape* boxShape = new CylinderShapeZ(boxHalfExtents); - boxShape->SetMargin(0.004f); - - obj[i].geom[0] = dCreateConvex(space,boxShape); - - } - else if (cmd == '2') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - - SimdVector3 boxHalfExtents(0.5f*sides[0],0.5f*sides[1],0.5f*sides[2]); - CollisionShape* boxShape = new BoxShape(boxHalfExtents); - boxShape->SetMargin(0.004f); - - //obj[i].geom[0] = dCreateConvex(space,boxShape); - - CollisionObject* colObj = new CollisionObject; - //from BulletOdeTransformConvert.h - colObj ->m_worldTransform = GetTransformFromBody(obj[i].body); - colObj ->SetCollisionShape(boxShape); - colWorld->AddCollisionObject(colObj ); - bulletObjects[i] = colObj; - - - } - - else if (cmd == '3') { - sides[1] *= 0.5; - dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); - // obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); - CollisionShape* boxShape = new ConeShape(0.5*sides[0],0.5*sides[2]); - boxShape->SetMargin(0.004f); - obj[i].geom[0] = dCreateConvex(space,boxShape); - - } - // cylinder option not yet implemented - else if (cmd == '4') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - ConvexHullShape* hullShape = new ConvexHullShape(0,0); - for (int k=0;kAddPoint(SimdPoint3(ConvexVertices[k*3],ConvexVertices[k*3+1],ConvexVertices[k*3+2])); - } - - hullShape->SetMargin(0.01f); - hullShape->setLocalScaling(SimdVector3(2.*sides[0],2.*sides[1],2.*sides[2])); - - - obj[i].geom[0] = dCreateConvex(space,hullShape); - - } - - else if (cmd == 's') { - sides[0] *= 0.5; - dMassSetSphere (&m,DENSITY,sides[0]); - obj[i].geom[0] = dCreateSphere (space,sides[0]); - } - else if (cmd == 'x') { - dGeomID g2[GPB]; // encapsulated geometries - dReal dpos[GPB][3]; // delta-positions for encapsulated geometries - - // start accumulating masses for the encapsulated geometries - dMass m2; - dMassSetZero (&m); - - // set random delta positions - for (j=0; j= num) selected = 0; - if (selected < 0) selected = 0; - } - else if (cmd == 'd' && selected >= 0 && selected < num) { - dBodyDisable (obj[selected].body); - } - else if (cmd == 'e' && selected >= 0 && selected < num) { - dBodyEnable (obj[selected].body); - } - else if (cmd == 'a') { - show_aabb ^= 1; - } - else if (cmd == 't') { - show_contacts ^= 1; - } - else if (cmd == 'r') { - random_pos ^= 1; - } - else if (cmd == '1') { - write_world = 1; - } -} - - - -// draw a geom - -void drawShape(CollisionShape* convexShape, const dReal *pos, const dReal *R, int show_aabb) -{ - - - switch (convexShape->GetShapeType()) - { - case BOX_SHAPE_PROXYTYPE: - { - BoxShape* boxShape = static_cast(convexShape); - SimdVector3 halfExtents = boxShape->GetHalfExtents(); - dVector3 sides; - sides[0] = halfExtents.getX(); - sides[1] = halfExtents.getY(); - sides[2] = halfExtents.getZ(); - dsDrawBox (pos,R,sides); - break; - } - /* - case CYLINDER_SHAPE_PROXYTYPE: - { - dsDrawCylinder (pos,R,sides[2],0.5*sides[0]);//length,radius); - break; - } - case CONE_SHAPE_PROXYTYPE: - { - dsDrawCone(pos,R,sides[2],0.5f*sides[0]); - break; - } - - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - // dsDrawCylinder2(pos,R,0.5*sides[2],0.5*sides[0],0.5*sides[1]); - - - { - int* Indices = (int*)::ConvexIndices; - - SimdVector3 scaling = convexShape->getLocalScaling(); - - - for (int ii = 0; ii < IndexCount / 3; ii++) { - const dReal v[9] = { // explicit conversion from float to dReal - ConvexVertices[Indices[ii * 3 + 0] * 3 + 0]*scaling[0], - ConvexVertices[Indices[ii * 3 + 0] * 3 + 1]*scaling[1], - ConvexVertices[Indices[ii * 3 + 0] * 3 + 2]*scaling[2], - ConvexVertices[Indices[ii * 3 + 1] * 3 + 0]*scaling[0], - ConvexVertices[Indices[ii * 3 + 1] * 3 + 1]*scaling[1], - ConvexVertices[Indices[ii * 3 + 1] * 3 + 2]*scaling[2], - ConvexVertices[Indices[ii * 3 + 2] * 3 + 0]*scaling[0], - ConvexVertices[Indices[ii * 3 + 2] * 3 + 1]*scaling[1], - ConvexVertices[Indices[ii * 3 + 2] * 3 + 2]*scaling[2] - }; - dsDrawTriangle(pos, R, &v[0], &v[3], &v[6], 1); - } - }; - - }; - */ - - default: - { - } - - }; -} - -void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) -{ - int i; - - if (!g) return; - if (!pos) pos = dGeomGetPosition (g); - if (!R) R = dGeomGetRotation (g); - - int type = dGeomGetClass (g); - if (type == dBoxClass) { - dVector3 sides; - dGeomBoxGetLengths (g,sides); - dsDrawBox (pos,R,sides); - } - else if (type == dConvexClass) { - dVector3 sides; - dGeomConvexGetLengths(g,sides); - - CollisionShape* convexShape = GetCollisionShapeFromConvex(g); - - - - } - - else if (type == dSphereClass) { - dsDrawSphere (pos,R,dGeomSphereGetRadius (g)); - } - else if (type == dCCylinderClass) { - dReal radius,length; - dGeomCCylinderGetParams (g,&radius,&length); - dsDrawCappedCylinder (pos,R,length,radius); - } - - // cylinder option not yet implemented - else if (type == dCylinderClass) { - dReal radius,length; - //dGeomCCylinderGetParams (g,&radius,&length); - dVector3 sides; - dGeomConvexGetLengths(g,sides); - - dsDrawCylinder (pos,R,sides[0],sides[1]);//length,radius); - } - else if (type == dGeomTransformClass) { - dGeomID g2 = dGeomTransformGetGeom (g); - const dReal *pos2 = dGeomGetPosition (g2); - const dReal *R2 = dGeomGetRotation (g2); - dVector3 actual_pos; - dMatrix3 actual_R; - dMULTIPLY0_331 (actual_pos,R,pos2); - actual_pos[0] += pos[0]; - actual_pos[1] += pos[1]; - actual_pos[2] += pos[2]; - dMULTIPLY0_333 (actual_R,R,R2); - drawGeom (g2,actual_pos,actual_R,0); - } - - if (show_aabb) { - // draw the bounding box for this geom - dReal aabb[6]; - dGeomGetAABB (g,aabb); - dVector3 bbpos; - for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); - dVector3 bbsides; - for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2]; - dMatrix3 RI; - dRSetIdentity (RI); - dsSetColorAlpha (1,0,0,0.5); - dsDrawBox (bbpos,RI,bbsides); - } -} - - -// simulation loop - -static void simLoop (int pause) -{ - dsSetColor (0,0,2); - dSpaceCollide (space,0,&nearCallback); - - { - //sync positions from geom to CollisionObject - for (int i=0;im_worldTransform = GetTransformFromBody( obj[i].body ); - } - } - colWorld->PerformDiscreteCollisionDetection(); - - - //add a bit of damping, had to dive into ode internal src, is there a way of doing this using public api ? - float ANGULAR_DRAG_CONSTANT = -0.01f; - float LINEAR_DRAG_CONSTANT = -0.01f; - float ANGULAR_VELOCITY_DAMPING = 0.99f; - float LINEAR_VELOCITY_DAMPING = 0.99f; - - dxWorld* w = (dxWorld*)world; - dxBody *nextb, *b = w->firstbody; - while (b) { - - b->avel[0]*=ANGULAR_VELOCITY_DAMPING; - b->avel[1]*=ANGULAR_VELOCITY_DAMPING; - b->avel[2]*=ANGULAR_VELOCITY_DAMPING; - b->lvel[0]*=LINEAR_VELOCITY_DAMPING; - b->lvel[1]*=LINEAR_VELOCITY_DAMPING; - b->lvel[2]*=LINEAR_VELOCITY_DAMPING; - - //next lines explodes the simulation, hence directly modifying the angular velocity above -// dBodyAddTorque(b,ANGULAR_DRAG_CONSTANT*b->avel[0],ANGULAR_DRAG_CONSTANT*b->avel[1],ANGULAR_DRAG_CONSTANT*b->avel[2]); -// dBodyAddForce(b,LINEAR_DRAG_CONSTANT*b->lvel[0],LINEAR_DRAG_CONSTANT*b->lvel[1],LINEAR_DRAG_CONSTANT*b->lvel[2]); - nextb = (dxBody*) b->next; - b = nextb; - } - - - - if (!pause) dWorldQuickStep (world,0.05); - - if (write_world) { - FILE *f = fopen ("state.dif","wt"); - if (f) { - dWorldExportDIF (world,f,"X"); - fclose (f); - } - write_world = 0; - } - - // remove all contact joints - dJointGroupEmpty (contactgroup); - - dsSetColor (1,1,0); - dsSetTexture (DS_WOOD); - for (int i=0; im_collisionShape, obj[i].body->pos, obj[i].body->R, show_aabb); - } - } - } -} -#include <..\ode\src\collision_kernel.h> - -int dCollideConvexConvex(dxGeom *o1, dxGeom *o2, int flags, - dContactGeom *contact, int skip); - -int main (int argc, char **argv) -{ - // setup pointers to drawstuff callback functions - dsFunctions fn; - fn.version = DS_VERSION; - fn.start = &start; - fn.step = &simLoop; - fn.command = &command; - fn.stop = 0; - fn.path_to_textures = "../../drawstuff/textures"; - - // create world - - world = dWorldCreate(); - space = dHashSpaceCreate (0); - contactgroup = dJointGroupCreate (0); - dWorldSetGravity (world,0,0,-0.5); - dWorldSetCFM (world,1e-5); - dWorldSetAutoDisableFlag (world,1); - dWorldSetContactMaxCorrectingVel (world,0.1); - dWorldSetContactSurfaceLayer (world,0.001); -// dCreatePlane (space,0,0,1,0); - - dGeomID groundGeom = dCreateBox(space,100.f,100.f,0.01f); - - - - CollisionDispatcher dispatcher; - SimdVector3 aabbMin(-1000,-1000,-1000); - SimdVector3 aabbMax(1000,1000,1000); - - AxisSweep3 broadphase(aabbMin,aabbMax); - - colWorld = new CollisionWorld(&dispatcher,&broadphase); - colWorld->PerformDiscreteCollisionDetection(); - - CollisionShape* boxShape = CreateShapeFromGeom(groundGeom); - CollisionObject* colObject = new CollisionObject; - colObject->m_worldTransform.setIdentity(); - colObject->SetCollisionShape(boxShape); - colWorld->AddCollisionObject(colObject); - - - ///see collision_convex.cpp - //setCollider (dConvexClass,dConvexClass,&dCollideConvexConvex); - //setCollider (dConvexClass,dPlaneClass,&dCollideConvexConvex); - //setCollider (dConvexClass,dBoxClass,&dCollideConvexConvex); - //setCollider (dConvexClass,dSphereClass,&dCollideConvexConvex); - //setCollider (dConvexClass,dCCylinderClass,&dCollideConvexConvex); - //setCollider( dTriMeshClass,dConvexClass, dCollideConvexConvex); - - memset (obj,0,sizeof(obj)); - - // run simulation - dsSimulationLoop (argc,argv,352,288,&fn); - - dJointGroupDestroy (contactgroup); - dSpaceDestroy (space); - dWorldDestroy (world); - - return 0; -} diff --git a/Extras/ode/ode/test/test_convex_trimesh.cpp b/Extras/ode/ode/test/test_convex_trimesh.cpp deleted file mode 100644 index ad2081851..000000000 --- a/Extras/ode/ode/test/test_convex_trimesh.cpp +++ /dev/null @@ -1,666 +0,0 @@ -/************************************************************************* - * * - * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * - * All rights reserved. Email: russ@q12.org Web: www.q12.org * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of EITHER: * - * (1) The GNU Lesser General Public License as published by the Free * - * Software Foundation; either version 2.1 of the License, or (at * - * your option) any later version. The text of the GNU Lesser * - * General Public License is included with this library in the * - * file LICENSE.TXT. * - * (2) The BSD-style license that is included with this library in * - * the file LICENSE-BSD.TXT. * - * * - * This library 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 files * - * LICENSE.TXT and LICENSE-BSD.TXT for more details. * - * * - *************************************************************************/ - -// TriMesh test by Erwin de Vries - -#include -#include -#include -#include -#include -#include -#include "BulletOdeCollide.h" - - -#ifdef _MSC_VER -#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints -#endif - -// select correct drawing functions - -#ifdef dDOUBLE -#define dsDrawBox dsDrawBoxD -#define dsDrawSphere dsDrawSphereD -#define dsDrawCylinder dsDrawCylinderD -#define dsDrawCappedCylinder dsDrawCappedCylinderD -#define dsDrawLine dsDrawLineD -#define dsDrawTriangle dsDrawTriangleD -#endif - - -// some constants - -#define NUM 200 // max number of objects -#define DENSITY (5.0) // density of all objects -#define GPB 3 // maximum number of geometries per body -#define MAX_CONTACTS 40 // maximum number of contact points per body - - -// dynamics and collision objects - -struct MyObject { - dBodyID body; // the body - dGeomID geom[GPB]; // geometries representing this body -}; - -static int num=0; // number of objects in simulation -static int nextobj=0; // next object to recycle if num==NUM -static dWorldID world; -static dSpaceID space; -static MyObject obj[NUM]; -static dJointGroupID contactgroup; -static int selected = -1; // selected object -static int show_aabb = 0; // show geom AABBs? -static int show_contacts = 0; // show contact points? -static int random_pos = 1; // drop objects from random position? - -#define VertexCount 5 -#define IndexCount 12 - -static dVector3 Size; -static dVector3 Vertices[VertexCount]; -static int Indices[IndexCount]; - -static dGeomID TriMesh=0; -static dGeomID Ray; - -const int ConvexVertexCount = 4; -const int ConvexIndexCount = 4 * 3; - - -float ConvexVertices[ConvexVertexCount*3] = { - REAL(-1./2.),REAL(-sqrt(3.)/6.), REAL(-sqrt(2./3.)/4.), - REAL(1./2.),REAL(-sqrt(3.)/6.),REAL(-sqrt(2./3.)/4.), - REAL(0.),REAL(2.*sqrt(3.)/6.),REAL(-sqrt(2./3.)/4.), - REAL(0.),REAL(0.),REAL(3.*sqrt(2./3.)/4.) - }; - -int ConvexIndices[ConvexIndexCount / 3][3] = { - {2,1,0}, - {1,3,0}, - {2,3,1}, - {0,3,2} -}; - - -// this is called by dSpaceCollide when two objects in space are -// potentially colliding. - -static void nearCallback (void *data, dGeomID o1, dGeomID o2) -{ - int i; - // if (o1->body && o2->body) return; - - // exit without doing anything if the two bodies are connected by a joint - dBodyID b1 = dGeomGetBody(o1); - dBodyID b2 = dGeomGetBody(o2); - if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return; - - dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box - for (i=0; i= 'A' && c <= 'Z') return c - ('a'-'A'); - else return c; -} - - -// called when a key pressed - -static void command (int cmd) -{ - int i,j,k; - dReal sides[3]; - dMass m; - - cmd = locase (cmd); - if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' - || cmd == '1' || cmd == '2' || cmd == '3' || cmd == '4' ) { - -// /* || cmd == 'l' */) { - if (num < NUM) { - i = num; - num++; - } - else { - i = nextobj; - nextobj++; - if (nextobj >= num) nextobj = 0; - - // destroy the body and geoms for slot i - dBodyDestroy (obj[i].body); - for (k=0; k < GPB; k++) { - if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]); - } - memset (&obj[i],0,sizeof(obj[i])); - } - - obj[i].body = dBodyCreate (world); - for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; - - dMatrix3 R; - if (random_pos) { - dBodySetPosition (obj[i].body, - dRandReal()*2-1,dRandReal()*2-1,dRandReal()+1); - dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, - dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); - } - else { - dReal maxheight = 0; - for (k=0; k maxheight) maxheight = pos[2]; - } - dBodySetPosition (obj[i].body, 0,0,maxheight+1); - dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0); - } - dBodySetRotation (obj[i].body,R); - dBodySetData (obj[i].body,(void*) i); - - if (cmd == 'b') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]); - } - else if (cmd == 'c') { - sides[0] *= 0.5; - dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); - obj[i].geom[0] = dCreateCCylinder (space,sides[0],sides[1]); - } - else if (cmd == '1') { - sides[1] *= 0.5; - dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); -// obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); - SimdVector3 boxHalfExtents(0.5*sides[0],0.5*sides[0],0.5*sides[1]); - CollisionShape* boxShape = new CylinderShapeZ(boxHalfExtents); - boxShape->SetMargin(0.004f); - - obj[i].geom[0] = dCreateConvex(space,boxShape); - - } - else if (cmd == '2') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - - SimdVector3 boxHalfExtents(0.5f*sides[0],0.5f*sides[1],0.5f*sides[2]); - CollisionShape* boxShape = new BoxShape(boxHalfExtents); - boxShape->SetMargin(0.004f); - - obj[i].geom[0] = dCreateConvex(space,boxShape); - } - - else if (cmd == '3') { - sides[1] *= 0.5; - dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]); -// obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]); - CollisionShape* boxShape = new ConeShape(0.5*sides[0],0.5*sides[2]); - boxShape->SetMargin(0.004f); - obj[i].geom[0] = dCreateConvex(space,boxShape); - - } - // cylinder option not yet implemented - else if (cmd == '4') { - dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); - ConvexHullShape* hullShape = new ConvexHullShape(0,0); - for (int k=0;kAddPoint(SimdPoint3(ConvexVertices[k*3],ConvexVertices[k*3+1],ConvexVertices[k*3+2])); - } - - hullShape->SetMargin(0.01f); - hullShape->setLocalScaling(SimdVector3(sides[0],sides[1],sides[2])); - - - obj[i].geom[0] = dCreateConvex(space,hullShape); - - } - - - else if (cmd == 's') { - sides[0] *= 0.5; - dMassSetSphere (&m,DENSITY,sides[0]); - obj[i].geom[0] = dCreateSphere (space,sides[0]); - } - else if (cmd == 'x') { - dGeomID g2[GPB]; // encapsulated geometries - dReal dpos[GPB][3]; // delta-positions for encapsulated geometries - - // start accumulating masses for the encapsulated geometries - dMass m2; - dMassSetZero (&m); - - // set random delta positions - for (j=0; j= num) selected = 0; - if (selected < 0) selected = 0; - } - else if (cmd == 'd' && selected >= 0 && selected < num) { - dBodyDisable (obj[selected].body); - } - else if (cmd == 'e' && selected >= 0 && selected < num) { - dBodyEnable (obj[selected].body); - } - else if (cmd == 'a') { - show_aabb ^= 1; - } - else if (cmd == 't') { - show_contacts ^= 1; - } - else if (cmd == 'r') { - random_pos ^= 1; - } -} - - -// draw a geom - -void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb) -{ - if (!g) return; - if (!pos) pos = dGeomGetPosition (g); - if (!R) R = dGeomGetRotation (g); - - int type = dGeomGetClass (g); - if (type == dBoxClass) { - dVector3 sides; - dGeomBoxGetLengths (g,sides); - dsDrawBox (pos,R,sides); - } - else if (type == dConvexClass) { - dVector3 sides; - dGeomConvexGetLengths(g,sides); - - CollisionShape* convexShape = GetCollisionShapeFromConvex(g); - switch (convexShape->GetShapeType()) - { - case BOX_SHAPE_PROXYTYPE: - { - dsDrawBox (pos,R,sides); - break; - } - case CYLINDER_SHAPE_PROXYTYPE: - { - dsDrawCylinder (pos,R,sides[2],0.5*sides[0]);//length,radius); - break; - } - case CONE_SHAPE_PROXYTYPE: - { - dsDrawCone(pos,R,sides[2],0.5f*sides[0]); - break; - } - - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - // dsDrawCylinder2(pos,R,0.5*sides[2],0.5*sides[0],0.5*sides[1]); - - - { - int* Indices = (int*)::ConvexIndices; - - SimdVector3 scaling = convexShape->getLocalScaling(); - - - for (int ii = 0; ii < IndexCount / 3; ii++) { - const dReal v[9] = { // explicit conversion from float to dReal - ConvexVertices[Indices[ii * 3 + 0] * 3 + 0]*scaling[0], - ConvexVertices[Indices[ii * 3 + 0] * 3 + 1]*scaling[1], - ConvexVertices[Indices[ii * 3 + 0] * 3 + 2]*scaling[2], - ConvexVertices[Indices[ii * 3 + 1] * 3 + 0]*scaling[0], - ConvexVertices[Indices[ii * 3 + 1] * 3 + 1]*scaling[1], - ConvexVertices[Indices[ii * 3 + 1] * 3 + 2]*scaling[2], - ConvexVertices[Indices[ii * 3 + 2] * 3 + 0]*scaling[0], - ConvexVertices[Indices[ii * 3 + 2] * 3 + 1]*scaling[1], - ConvexVertices[Indices[ii * 3 + 2] * 3 + 2]*scaling[2] - }; - dsDrawTriangle(pos, R, &v[0], &v[3], &v[6], 1); - } - }; - - }; - default: - { - } - - } - } - - - else if (type == dSphereClass) { - dsDrawSphere (pos,R,dGeomSphereGetRadius (g)); - } - else if (type == dCCylinderClass) { - dReal radius,length; - dGeomCCylinderGetParams (g,&radius,&length); - dsDrawCappedCylinder (pos,R,length,radius); - } -/* - // cylinder option not yet implemented - else if (type == dCylinderClass) { - dReal radius,length; - dGeomCylinderGetParams (g,&radius,&length); - dsDrawCylinder (pos,R,length,radius); - } -*/ - else if (type == dGeomTransformClass) { - dGeomID g2 = dGeomTransformGetGeom (g); - const dReal *pos2 = dGeomGetPosition (g2); - const dReal *R2 = dGeomGetRotation (g2); - dVector3 actual_pos; - dMatrix3 actual_R; - dMULTIPLY0_331 (actual_pos,R,pos2); - actual_pos[0] += pos[0]; - actual_pos[1] += pos[1]; - actual_pos[2] += pos[2]; - dMULTIPLY0_333 (actual_R,R,R2); - drawGeom (g2,actual_pos,actual_R,0); - } - - if (show_aabb) { - // draw the bounding box for this geom - dReal aabb[6]; - dGeomGetAABB (g,aabb); - dVector3 bbpos; - for (int i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); - dVector3 bbsides; - for (int j=0; j<3; j++) bbsides[j] = aabb[j*2+1] - aabb[j*2]; - dMatrix3 RI; - dRSetIdentity (RI); - dsSetColorAlpha (1,0,0,0.5); - dsDrawBox (bbpos,RI,bbsides); - } -} - - -// simulation loop - -static void simLoop (int pause) -{ - dsSetColor (0,0,2); - dSpaceCollide (space,0,&nearCallback); - if (!pause) dWorldStep (world,0.05); - //if (!pause) dWorldStepFast (world,0.05, 1); - - // remove all contact joints - dJointGroupEmpty (contactgroup); - - dsSetColor (1,1,0); - dsSetTexture (DS_WOOD); - for (int i=0; i> BUILD_LOG -cat < $SETTINGS -PLATFORM=$PLATFORM -PRECISION=$PRECISION -BUILD=$MODE -END -make clean -make >> BUILD_LOG 2>&1 -echo -e "\n\n---------------------------------------------\n\n" >> BUILD_LOG -} - -echo > BUILD_LOG - -PRECISION=SINGLE -MODE=debug -build -PRECISION=SINGLE -MODE=release -build -PRECISION=DOUBLE -MODE=debug -build -PRECISION=DOUBLE -MODE=release -build - -make clean -rm -f $SETTINGS diff --git a/Extras/ode/tools/build4.bat b/Extras/ode/tools/build4.bat deleted file mode 100644 index c044fde60..000000000 --- a/Extras/ode/tools/build4.bat +++ /dev/null @@ -1,86 +0,0 @@ -@echo off - -rem build all four precision/release configurations and log the build messages - -rem (used for debugging). - - - -setlocal - - - -set PLATFORM=cygwin - -set SETTINGS=config\user-settings - - - -echo SINGLE debug > BUILD_LOG - -echo PLATFORM=%PLATFORM%> %SETTINGS% - -echo PRECISION=SINGLE>> %SETTINGS% - -echo BUILD=debug>> %SETTINGS% - -make clean - -make >> BUILD_LOG - -echo --------------------------------------------- >> BUILD_LOG - - - -echo DOUBLE debug >> BUILD_LOG - -echo PLATFORM=%PLATFORM%> %SETTINGS% - -echo PRECISION=DOUBLE>> %SETTINGS% - -echo BUILD=debug>> %SETTINGS% - -make clean - -make >> BUILD_LOG - -echo --------------------------------------------- >> BUILD_LOG - - - -echo SINGLE release >> BUILD_LOG - -echo PLATFORM=%PLATFORM%> %SETTINGS% - -echo PRECISION=SINGLE>> %SETTINGS% - -echo BUILD=release>> %SETTINGS% - -make clean - -make >> BUILD_LOG - -echo --------------------------------------------- >> BUILD_LOG - - - -echo DOUBLE release >> BUILD_LOG - -echo PLATFORM=%PLATFORM%> %SETTINGS% - -echo PRECISION=DOUBLE>> %SETTINGS% - -echo BUILD=release>> %SETTINGS% - -make clean - -make >> BUILD_LOG - -echo --------------------------------------------- >> BUILD_LOG - - - -make clean - -del %SETTINGS% - diff --git a/Extras/ode/tools/make_distribution b/Extras/ode/tools/make_distribution deleted file mode 100644 index ed6d52bcb..000000000 --- a/Extras/ode/tools/make_distribution +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh - -VER=0.03 -# VER=`date +%y%m%d` - -if [ ! -f ode/src/ode.cpp ]; then - echo "run this from the ODE root directory" - exit 1 -fi - -ODE_DIR=`pwd` - -cd /tmp -if [ -d /tmp/ode-$VER ]; then - echo "remove /tmp/ode-$VER first" - exit 1 -fi - -mkdir /tmp/ode-$VER -cp -av $ODE_DIR/* /tmp/ode-$VER -find /tmp/ode-$VER -type d -name CVS -exec rm -rf {} \; -print -find /tmp/ode-$VER -type f -name *~ -exec rm -f {} \; -print -rmdir /tmp/ode-$VER/build - -cd /tmp/ode-$VER -make clean -cp config/user-settings.example config/user-settings - -cd ode/doc -./doccer ode.doc > ode.html - -cd /tmp/ode-$VER -echo -e "\n\nMake any modifications you want, then exit the shell:" -bash - -cd /tmp -tar cfvz ode-$VER.tgz ode-$VER -rm -rf /tmp/ode-$VER - -echo -e "\ntype to exit or 'c' to copy to q12" -read Q -if [ $Q ]; then - echo copying... - scp1 ode-$VER.tgz q12.org:~/q12/ode/release/ -fi diff --git a/Extras/ode/tools/process_deps b/Extras/ode/tools/process_deps deleted file mode 100644 index 9b95ddac3..000000000 --- a/Extras/ode/tools/process_deps +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl - -$a = join ('',); -$a =~ s/\\\n/ /g; # join continued lines -$a =~ s/(^\S+:)/$ARGV[0]$1/gm; # put prefix in front of rules -$a =~ s/\s+\/\S+/ /g; # remove absolute path dependencies -$a =~ s/\s+\n/\n/g; # remove whitespace at end of lines -$a =~ s/[ \t]+/ /g; # clean up interior whitespace -$a =~ s/ / \\\n /g; # put back line continuations - -print $a; diff --git a/Extras/ode/tools/rm.c b/Extras/ode/tools/rm.c deleted file mode 100644 index 75e55a8c3..000000000 --- a/Extras/ode/tools/rm.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - - - -this is a simple replacement for the windows command line 'del' command. - -this is more convenient to use in the ODE makefile because of the following - -differences from 'del' : - - * filenames may contain forward slashes. - - * wildcard expansion is not performed. - - * it is called 'rm', just like in unix. - - - -*/ - - - -#include - -#include - - - -int main (int argc, char **argv) - -{ - - int i; - - for (i=1; i